diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87bae98b..20485478 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 - run: cargo fmt --all -- --check - run: cargo clippy --all-targets --all-features -- -D warnings - - run: cargo test --all-features + - run: cargo test --features odbc-static - name: Upload Linux binary uses: actions/upload-artifact@v4 with: @@ -70,10 +70,12 @@ jobs: run: docker compose logs ${{ matrix.container }} - name: Run tests against ${{ matrix.database }} timeout-minutes: 5 - run: cargo test --all-features + run: cargo test --features odbc-static env: DATABASE_URL: ${{ matrix.db_url }} RUST_BACKTRACE: 1 + MALLOC_CHECK_: 3 + MALLOC_PERTURB_: 10 windows_test: runs-on: windows-latest diff --git a/.github/workflows/official-site.yml b/.github/workflows/official-site.yml index 0ec66068..3ad48ef3 100644 --- a/.github/workflows/official-site.yml +++ b/.github/workflows/official-site.yml @@ -8,7 +8,7 @@ on: concurrency: site-deploy jobs: - deploy: + deploy_official_site: runs-on: ubuntu-latest steps: - name: Cloning repo diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e67936fd..e32cf37e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -150,5 +150,6 @@ jobs: - uses: actions/checkout@v4 - name: Set up cargo cache uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 + - run: sudo apt-get update && sudo apt-get install -y unixodbc-dev - name: Publish to crates.io run: cargo publish --token ${{ secrets.CRATES_IO_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a204c38..ccf8bc1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # CHANGELOG.md +## v0.39.0 + - Ability to execute sql for URL paths with another extension. If you create sitemap.xml.sql, it will be executed for example.com/sitemap.xml + - Display source line info in errors even when the database does not return a precise error position. In this case, the entire problematic SQL statement is referenced. + - The shell with a vertical sidebar can now have "active" elements, just like the horizontal header bar. + - New `edit_url`, `delete_url`, and `custom_actions` properties in the [table](https://sql-page.com/component.sql?component=table) component to easily add nice icon buttons to a table. + - SQLPage now sets the [`Server-Timing` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Server-Timing) in development. So when you have a page that loads slowly, you can open your browser's network inspector, click on the slow request, then open the timing tab to understand where it's spending its time. + - image + - Fixed a memory corruption issue in the builtin odbc driver manager + + ## v0.38.0 - Added support for the Open Database Connectivity (ODBC) standard. - This makes SQLPage compatible with many new databases, including: @@ -18,6 +28,9 @@ - Supports SHA-256 (default) and SHA-512 algorithms - Output formats: hexadecimal (default) or base64 (e.g., `sha256-base64`) - See the [function documentation](https://sql-page.com/functions.sql?function=hmac) for detailed examples + - Fixed a slight spacing issue in the list components empty value display. + - Improved performance of setting a variable to a literal value. `SET x = 'hello'` is now executed locally by SQLPage and does not send anything to the database. This completely removes the cost of extracting static values into variables for cleaner SQL files. + - Enable arbitrary precision in the internal representation of numbers. This guarantees zero precision loss when the database returns very large or very small DECIMAL or NUMERIC values. ## v0.37.1 - fixed decoding of UUID values diff --git a/Cargo.lock b/Cargo.lock index 224be5f1..654b0598 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "bytes", "futures-core", "futures-sink", @@ -21,9 +21,9 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.11.1" +version = "3.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cceded2fb55f3c4b67068fa64962e2ca59614edc5b03167de9ff82ae803da0" +checksum = "7926860314cbe2fb5d1f13731e387ab43bd32bca224e82e6e2db85de0a3dba49" dependencies = [ "actix-codec", "actix-rt", @@ -31,14 +31,14 @@ dependencies = [ "actix-tls", "actix-utils", "base64 0.22.1", - "bitflags 2.9.4", + "bitflags 2.10.0", "brotli 8.0.2", "bytes", "bytestring", "derive_more 2.0.1", "encoding_rs", "flate2", - "foldhash", + "foldhash 0.1.5", "futures-core", "h2", "http 0.2.12", @@ -214,7 +214,7 @@ dependencies = [ "cookie", "derive_more 2.0.1", "encoding_rs", - "foldhash", + "foldhash 0.1.5", "futures-core", "futures-util", "impl-more", @@ -263,15 +263,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.1" @@ -291,7 +282,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -334,7 +325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.9.4", + "bitflags 2.10.0", "cc", "cesu8", "jni", @@ -516,7 +507,7 @@ dependencies = [ "polling", "rustix 1.1.2", "slab", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -621,9 +612,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "awc" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117ec0a30fe956b77d69efff54bce923854df0437874fe4bfa701dfdddca8d5d" +checksum = "3c170039c11c7f6c0a28f7b3bd4fb0c674cbfa317fabc1560022ad3ec2d69e7c" dependencies = [ "actix-codec", "actix-http", @@ -665,31 +656,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.32.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b715a6010afb9e457ca2b7c9d2b9c344baa8baed7b38dc476034c171b32575" +checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c" dependencies = [ "bindgen", "cc", "cmake", "dunce", "fs_extra", - "libloading", -] - -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link", ] [[package]] @@ -724,15 +699,17 @@ checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bigdecimal" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a22f228ab7a1b23027ccc6c350b72868017af7ea8356fbdf19f8d991c690013" +checksum = "560f42649de9fa436b73517378a147ec21f6c997a546581df4b4b31677828934" dependencies = [ "autocfg", "libm", "num-bigint", "num-integer", "num-traits", + "serde", + "serde_json", ] [[package]] @@ -741,7 +718,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -763,11 +740,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -885,7 +862,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "log", "polling", "rustix 0.38.44", @@ -895,9 +872,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.40" +version = "1.2.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" +checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" dependencies = [ "find-msvc-tools", "jobserver", @@ -922,9 +899,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -959,9 +936,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.48" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" dependencies = [ "clap_builder", "clap_derive", @@ -969,9 +946,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.48" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" dependencies = [ "anstream", "anstyle", @@ -981,9 +958,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.47" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -993,9 +970,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmake" @@ -1256,9 +1233,9 @@ dependencies = [ [[package]] name = "csv-core" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" dependencies = [ "memchr", ] @@ -1508,7 +1485,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -1646,9 +1623,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", "regex", @@ -1691,7 +1668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -1739,15 +1716,15 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "find-msvc-tools" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -1776,6 +1753,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.5.0" @@ -1944,9 +1927,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -1962,28 +1945,22 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "wasip2", ] -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - [[package]] name = "glob" version = "0.3.3" @@ -2013,7 +1990,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.11.4", + "indexmap 2.12.0", "slab", "tokio", "tokio-util", @@ -2047,10 +2024,6 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] [[package]] name = "hashbrown" @@ -2058,7 +2031,7 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash", + "foldhash 0.1.5", ] [[package]] @@ -2066,6 +2039,11 @@ name = "hashbrown" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "hashlink" @@ -2355,9 +2333,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown 0.16.0", @@ -2365,22 +2343,11 @@ dependencies = [ "serde_core", ] -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", -] - [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -2458,7 +2425,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] @@ -2549,15 +2516,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.176" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libflate" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d9dfdc14ea4ef0900c1cddbc8dcd553fbaacd8a4a282cf4018ae9dd04fb21e" +checksum = "249fa21ba2b59e8cbd69e722f5b31e1b466db96c937ae3de23e8b99ead0d1383" dependencies = [ "adler32", "core2", @@ -2568,23 +2535,23 @@ dependencies = [ [[package]] name = "libflate_lz77" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" +checksum = "a599cb10a9cd92b1300debcef28da8f70b935ec937f44fcd1b70a7c986a11c5c" dependencies = [ "core2", - "hashbrown 0.14.5", + "hashbrown 0.16.0", "rle-decode-fast", ] [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.4", + "windows-link", ] [[package]] @@ -2599,7 +2566,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", "redox_syscall 0.5.18", ] @@ -2720,18 +2687,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", "log", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -2740,7 +2708,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "jni-sys", "log", "ndk-sys", @@ -2854,9 +2822,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", "rustversion", @@ -2864,9 +2832,9 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2915,7 +2883,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "libc", "objc2", @@ -2931,7 +2899,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-core-location", @@ -2955,7 +2923,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-foundation", @@ -2997,7 +2965,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "dispatch", "libc", @@ -3022,7 +2990,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-foundation", @@ -3034,7 +3002,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-foundation", @@ -3057,7 +3025,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-cloud-kit", @@ -3089,27 +3057,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-core-location", "objc2-foundation", ] -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - [[package]] name = "odbc-api" -version = "19.0.2" +version = "19.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "564dc5b7c737a3821f60e3b9608320098a02203ab4a38be09bcd759225329554" +checksum = "f017d3949731e436bc1bb9a1fbc34197c2f39c588cdcb60d21adb1f8dd3b8514" dependencies = [ "atoi", "log", @@ -3121,10 +3080,10 @@ dependencies = [ [[package]] name = "odbc-sys" -version = "0.27.0" -source = "git+https://github.com/sqlpage/odbc-sys?branch=main#0b5489e7b07d45e6b126f5a57ed6c301f022d2da" +version = "0.27.3" +source = "git+https://github.com/sqlpage/odbc-sys?branch=no-autotools#b9617a5164eeda7b1ffaecc9afadbc0d3134633e" dependencies = [ - "cc", + "unix-odbc", ] [[package]] @@ -3144,9 +3103,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openidconnect" @@ -3303,12 +3262,12 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pem" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ "base64 0.22.1", - "serde", + "serde_core", ] [[package]] @@ -3450,7 +3409,7 @@ dependencies = [ "hermit-abi", "pin-project-lite", "rustix 1.1.2", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -3522,9 +3481,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -3600,7 +3559,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -3637,7 +3596,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -3673,9 +3632,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -3685,9 +3644,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -3696,15 +3655,15 @@ dependencies = [ [[package]] name = "regex-lite" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30" +checksum = "8d942b98df5e658f56f20d592c7f868833fe38115e65c33003d8cd224b0155da" [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "rfc6979" @@ -3743,7 +3702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.9.4", + "bitflags 2.10.0", "serde", "serde_derive", ] @@ -3778,12 +3737,6 @@ dependencies = [ "ordered-multimap", ] -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -3814,7 +3767,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3827,18 +3780,18 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.32" +version = "0.23.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" dependencies = [ "aws-lc-rs", "log", @@ -3871,15 +3824,15 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.17", - "webpki-roots 1.0.2", + "webpki-roots 1.0.3", "x509-parser", ] [[package]] name = "rustls-native-certs" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -3944,7 +3897,7 @@ version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -3997,7 +3950,7 @@ version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -4078,7 +4031,7 @@ version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.12.0", "itoa", "memchr", "ryu", @@ -4108,9 +4061,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee" +checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" dependencies = [ "serde_core", ] @@ -4129,15 +4082,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.15.0" +version = "3.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" +checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.11.4", + "indexmap 2.12.0", "schemars 0.9.0", "schemars 1.0.4", "serde_core", @@ -4148,9 +4101,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.15.0" +version = "3.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" +checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955" dependencies = [ "darling 0.21.3", "proc-macro2", @@ -4205,6 +4158,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "slab" version = "0.4.11" @@ -4238,12 +4197,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -4267,7 +4226,7 @@ dependencies = [ [[package]] name = "sqlpage" -version = "0.38.0-beta.1" +version = "0.39.0" dependencies = [ "actix-multipart", "actix-rt", @@ -4346,7 +4305,7 @@ dependencies = [ "atoi", "base64 0.22.1", "bigdecimal", - "bitflags 2.9.4", + "bitflags 2.10.0", "byteorder", "bytes", "chrono", @@ -4368,7 +4327,7 @@ dependencies = [ "hex", "hkdf", "hmac", - "indexmap 2.11.4", + "indexmap 2.12.0", "itoa", "libc", "libsqlite3-sys", @@ -4397,7 +4356,7 @@ dependencies = [ "tokio-util", "url", "uuid", - "webpki-roots 1.0.2", + "webpki-roots 1.0.3", "whoami", ] @@ -4444,9 +4403,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stringprep" @@ -4473,9 +4432,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" dependencies = [ "proc-macro2", "quote", @@ -4500,10 +4459,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix 1.1.2", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -4613,29 +4572,26 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.47.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2 0.6.0", + "socket2 0.6.1", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -4679,9 +4635,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0" +checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ "serde_core", "serde_spanned", @@ -4692,20 +4648,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.6" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.12.0", "toml_datetime", "toml_parser", "winnow", @@ -4713,9 +4669,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ "winnow", ] @@ -4823,9 +4779,9 @@ checksum = "70ba288e709927c043cbe476718d37be306be53fb1fafecd0dbe36d072be2580" [[package]] name = "unicode-ident" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" [[package]] name = "unicode-normalization" @@ -4854,6 +4810,14 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unix-odbc" +version = "0.1.2" +source = "git+https://github.com/sqlpage/odbc-sys?branch=no-autotools#b9617a5164eeda7b1ffaecc9afadbc0d3134633e" +dependencies = [ + "cc", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -4931,15 +4895,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" @@ -5053,14 +5008,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.2", + "webpki-roots 1.0.3", ] [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" dependencies = [ "rustls-pki-types", ] @@ -5078,9 +5033,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi-util" @@ -5088,14 +5043,14 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] name = "windows-core" -version = "0.62.1" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", @@ -5106,9 +5061,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.1" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -5117,9 +5072,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.2" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -5128,24 +5083,24 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] @@ -5183,14 +5138,14 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.4", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.61.1" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] @@ -5228,19 +5183,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.4" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -5257,9 +5212,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -5275,9 +5230,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -5293,9 +5248,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -5305,9 +5260,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -5323,9 +5278,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -5341,9 +5296,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -5359,9 +5314,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -5377,9 +5332,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" @@ -5389,7 +5344,7 @@ checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" dependencies = [ "android-activity", "atomic-waker", - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "calloop", "cfg_aliases", @@ -5465,7 +5420,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "dlib", "log", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 62f86d3c..f4a84374 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlpage" -version = "0.38.0-beta.1" +version = "0.39.0" edition = "2021" description = "Build data user interfaces entirely in SQL. A web server that takes .sql files and formats the query result using pre-made configurable professional-looking components." keywords = ["web", "sql", "framework"] @@ -44,7 +44,11 @@ tokio = { version = "1.24.1", features = ["macros", "rt", "process", "sync"] } tokio-stream = "0.1.9" anyhow = "1" serde = "1" -serde_json = { version = "1.0.82", features = ["preserve_order", "raw_value"] } +serde_json = { version = "1.0.82", features = [ + "preserve_order", + "raw_value", + "arbitrary_precision", +] } lambda-web = { version = "0.2.1", features = ["actix4"], optional = true } sqlparser = { version = "0.59.0", default-features = false, features = [ "std", @@ -53,7 +57,7 @@ sqlparser = { version = "0.59.0", default-features = false, features = [ async-stream = "0.3" async-trait = "0.1.61" async-recursion = "1.0.0" -bigdecimal = "0.4.8" +bigdecimal = { version = "0.4.8", features = ["serde-json"] } include_dir = "0.7.2" config = { version = "0.15.4", features = ["json"] } markdown = { version = "1.0.0-alpha.23", features = ["log"] } @@ -75,16 +79,17 @@ clap = { version = "4.5.17", features = ["derive"] } tokio-util = "0.7.12" openidconnect = { version = "4.0.0", default-features = false } encoding_rs = "0.8.35" -odbc-sys = { version = "0.27", features = [], optional = false } +odbc-sys = { version = "0.27.1", optional = true } [features] default = [] -odbc-static = ["odbc-sys/static"] +odbc-static = ["odbc-sys", "odbc-sys/vendored-unix-odbc"] +lambda-web = ["dep:lambda-web", "odbc-static"] [patch.crates-io] -odbc-sys = { git = "https://github.com/sqlpage/odbc-sys", branch = "main" } # see https://github.com/pacman82/odbc-sys/pull/60 +odbc-sys = { git = "https://github.com/sqlpage/odbc-sys", branch = "no-autotools" } [build-dependencies] awc = { version = "3", features = ["rustls-0_23-webpki-roots"] } diff --git a/Dockerfile b/Dockerfile index 5d83e202..f3ea20f1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,63 +1,25 @@ FROM --platform=$BUILDPLATFORM rust:1.90-slim AS builder + WORKDIR /usr/src/sqlpage ARG TARGETARCH ARG BUILDARCH -RUN apt-get update && \ - mkdir -p /opt/sqlpage-libs && \ - if [ "$TARGETARCH" = "$BUILDARCH" ]; then \ - rustup target list --installed > TARGET && \ - echo gcc > LINKER && \ - apt-get install -y gcc libgcc-s1 cmake unixodbc-dev libltdl-dev pkg-config && \ - LIBMULTIARCH=$(gcc -print-multiarch); \ - LIBDIR="/lib/$LIBMULTIARCH"; \ - USRLIBDIR="/usr/lib/$LIBMULTIARCH"; \ - HOST_TRIPLE=$(gcc -dumpmachine); \ - elif [ "$TARGETARCH" = "arm64" ]; then \ - echo aarch64-unknown-linux-gnu > TARGET && \ - echo aarch64-linux-gnu-gcc > LINKER && \ - dpkg --add-architecture arm64 && apt-get update && \ - apt-get install -y gcc-aarch64-linux-gnu libgcc-s1-arm64-cross unixodbc-dev:arm64 libltdl-dev:arm64 pkg-config && \ - LIBDIR="/lib/aarch64-linux-gnu"; \ - USRLIBDIR="/usr/lib/aarch64-linux-gnu"; \ - HOST_TRIPLE="aarch64-linux-gnu"; \ - elif [ "$TARGETARCH" = "arm" ]; then \ - echo armv7-unknown-linux-gnueabihf > TARGET && \ - echo arm-linux-gnueabihf-gcc > LINKER && \ - dpkg --add-architecture armhf && apt-get update && \ - apt-get install -y gcc-arm-linux-gnueabihf libgcc-s1-armhf-cross cmake libclang1 clang unixodbc-dev:armhf libltdl-dev:armhf pkg-config && \ - cargo install --force --locked bindgen-cli && \ - SYSROOT=$(arm-linux-gnueabihf-gcc -print-sysroot); \ - echo "--sysroot=$SYSROOT -I$SYSROOT/usr/include -I$SYSROOT/usr/include/arm-linux-gnueabihf" > BINDGEN_EXTRA_CLANG_ARGS; \ - LIBDIR="/lib/arm-linux-gnueabihf"; \ - USRLIBDIR="/usr/lib/arm-linux-gnueabihf"; \ - HOST_TRIPLE="arm-linux-gnueabihf"; \ - else \ - echo "Unsupported cross compilation target: $TARGETARCH"; \ - exit 1; \ - fi && \ - echo $USRLIBDIR > ODBC_LIBDIR && \ - cp $LIBDIR/libgcc_s.so.1 /opt/sqlpage-libs/ && \ - rustup target add $(cat TARGET) && \ - cargo init . + +# Copy build scripts +COPY scripts/ /usr/local/bin/ + +# Initialize cargo project +RUN cargo init . + +# Setup cross-compilation environment +RUN /usr/local/bin/setup-cross-compilation.sh "$TARGETARCH" "$BUILDARCH" # Build dependencies (creates a layer that avoids recompiling dependencies on every build) COPY Cargo.toml Cargo.lock ./ -RUN BINDGEN_EXTRA_CLANG_ARGS=$(cat BINDGEN_EXTRA_CLANG_ARGS || true) \ - RS_ODBC_LINK_SEARCH=$(cat ODBC_LIBDIR) \ - cargo build \ - --target $(cat TARGET) \ - --config target.$(cat TARGET).linker='"'$(cat LINKER)'"' \ - --profile superoptimized +RUN /usr/local/bin/build-dependencies.sh # Build the project COPY . . -RUN touch src/main.rs && \ - RS_ODBC_LINK_SEARCH=$(cat ODBC_LIBDIR) \ - cargo build \ - --target $(cat TARGET) \ - --config target.$(cat TARGET).linker='"'$(cat LINKER)'"' \ - --profile superoptimized && \ - mv target/$(cat TARGET)/superoptimized/sqlpage sqlpage.bin +RUN /usr/local/bin/build-project.sh FROM busybox:glibc RUN addgroup --gid 1000 --system sqlpage && \ @@ -70,7 +32,7 @@ ENV SQLPAGE_CONFIGURATION_DIRECTORY=/etc/sqlpage WORKDIR /var/www COPY --from=builder /usr/src/sqlpage/sqlpage.bin /usr/local/bin/sqlpage # Provide runtime helper libs in system lib directory for the glibc busybox base -COPY --from=builder /opt/sqlpage-libs/* /lib/ +COPY --from=builder /tmp/sqlpage-libs/* /lib/ USER sqlpage COPY --from=builder --chown=sqlpage:sqlpage /usr/src/sqlpage/sqlpage/sqlpage.db sqlpage/sqlpage.db EXPOSE 8080 diff --git a/README.md b/README.md index c25c8867..b4c99c33 100644 --- a/README.md +++ b/README.md @@ -186,15 +186,12 @@ An alternative for Mac OS users is to use [SQLPage's homebrew package](https://f ### ODBC Setup +SQLPage supports ODBC connections to connect to databases that don't have native drivers. You can skip this section if you want to use one of the built-in database drivers (SQLite, PostgreSQL, MySQL, Microsoft SQL Server). -SQLPage supports ODBC connections to connect to databases that don't have native drivers, such as Oracle, Snowflake, BigQuery, IBM DB2, and many others. - -On Linux, SQLPage supports both dynamic and static ODBC linking. The Docker image uses the system `unixODBC` (dynamic). -Linux and MacOS release binaries are built with a statically linked unixODBC. +Linux and MacOS release binaries conatain a built-in statically linked ODBC driver manager (unixODBC). You still need to install or provide the database-specific ODBC driver for the database you want to connect to. - #### Install your ODBC database driver - [DuckDB](https://duckdb.org/docs/stable/clients/odbc/overview.html) - [Snowflake](https://docs.snowflake.com/en/developer-guide/odbc/odbc) diff --git a/examples/official-site/llms.txt.sql b/examples/official-site/llms.txt.sql new file mode 100644 index 00000000..a1f5cda5 --- /dev/null +++ b/examples/official-site/llms.txt.sql @@ -0,0 +1,145 @@ +select + 'http_header' as component, + 'text/markdown; charset=utf-8' as "Content-Type", + 'inline; filename="llms.txt"' as "Content-Disposition"; + +select + 'shell-empty' as component, + '# SQLPage + +> SQLPage is a SQL-only web application framework. It lets you build entire websites and web applications using nothing but SQL queries. Write `.sql` files, and SQLPage executes them, maps results to UI components (handlebars templates), and streams HTML to the browser. + +SQLPage is designed for developers who are comfortable with SQL but want to avoid the complexity of traditional web frameworks. It works with SQLite, PostgreSQL, MySQL, and Microsoft SQL Server, and through ODBC with any other database that has an ODBC driver installed. + +Key features: +- No backend code needed: Your SQL files are your backend +- Component-based UI: Built-in components for forms, tables, charts, maps, and more +- Database-first: Every HTTP request triggers a sequence of SQL queries from a .sql file, the results are rendered with built-in or custom components, defined as .handlebars files in the sqlpage/templates folder. +- Simple deployment: Single binary with no runtime dependencies +- Secure by default: Parameterized queries prevent SQL injection + +## Getting Started + +- [Introduction to SQLPage: installation, guiding principles, and a first example](/your-first-sql-website/tutorial.md): Complete beginner tutorial covering setup, database connections, forms, and deployment + +## Core Documentation + +- [Components reference](/documentation.sql): List of all ' || ( + select + count(*) + from + component + ) || ' built-in UI components with parameters and examples +- [Functions reference](/functions.sql): SQLPage built-in functions for handling requests, encoding data, and more +- [Configuration guide](https://github.com/sqlpage/SQLPage/blob/main/configuration.md): Complete list of configuration options in sqlpage.json + +## Components + +' || ( + select + group_concat ( + '### [' || c.name || '](/component.sql?component=' || c.name || ') + +' || c.description || ' + +' || ( + select + case when exists ( + select + 1 + from + parameter + where + component = c.name + and top_level + ) then '#### Top-level parameters + +' || group_concat ( + '- `' || name || '` (' || type || ')' || case when not optional then ' **REQUIRED**' else '' end || ': ' || description, + char(10) + ) + else + '' + end + from + parameter + where + component = c.name + and top_level + ) || ' + +' || ( + select + case when exists ( + select + 1 + from + parameter + where + component = c.name + and not top_level + ) then '#### Row-level parameters + +' || group_concat ( + '- `' || name || '` (' || type || ')' || case when not optional then ' **REQUIRED**' else '' end || ': ' || description, + char(10) + ) + else + '' + end + from + parameter + where + component = c.name + and not top_level + ) || ' + +', + '' + ) + from + component c + order by + c.name + ) || ' + +## Functions + +' || ( + select + group_concat ( + '### [sqlpage.' || name || '()](/functions.sql?function=' || name || ') +' || replace ( + replace ( + description_md, + char(10) || '#', + char(10) || '###' + ), + ' ', + ' ' + ), + char(10) + ) + from + sqlpage_functions + order by + name + ) || ' + +## Examples + +- [Authentication example](https://github.com/sqlpage/SQLPage/tree/main/examples/user-authentication): Complete user registration and login system +- [CRUD application](https://github.com/sqlpage/SQLPage/tree/main/examples/CRUD%20-%20Authentication): Create, read, update, delete with authentication +- [Image gallery](https://github.com/sqlpage/SQLPage/tree/main/examples/image%20gallery%20with%20user%20uploads): File upload and image display +- [Todo application](https://github.com/sqlpage/SQLPage/tree/main/examples/todo%20application): Simple CRUD app +- [Master-detail forms](https://github.com/sqlpage/SQLPage/tree/main/examples/master-detail-forms): Working with related data +- [Charts example](https://github.com/sqlpage/SQLPage/tree/main/examples/plots%20tables%20and%20forms): Data visualization + +## Optional + +- [Custom components guide](/custom_components.sql): Create your own handlebars components +- [Safety and security](/safety.sql): Understanding SQL injection prevention +- [Docker deployment](https://github.com/sqlpage/SQLPage#with-docker): Running SQLPage in containers +- [Systemd service](https://github.com/sqlpage/SQLPage/blob/main/sqlpage.service): Production deployment setup +- [Repository structure](https://github.com/sqlpage/SQLPage/blob/main/CONTRIBUTING.md): Project organization and contribution guide +' as html; \ No newline at end of file diff --git a/examples/official-site/sqlpage/migrations/01_documentation.sql b/examples/official-site/sqlpage/migrations/01_documentation.sql index ee2b8b51..dabd6d76 100644 --- a/examples/official-site/sqlpage/migrations/01_documentation.sql +++ b/examples/official-site/sqlpage/migrations/01_documentation.sql @@ -810,11 +810,15 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S ('money', 'Name of a numeric column whose values should be displayed as currency amounts, in the currency defined by the `currency` property. This argument can be repeated multiple times.', 'TEXT', TRUE, TRUE), ('currency', 'The ISO 4217 currency code (e.g., USD, EUR, GBP, etc.) to use when formatting monetary values.', 'TEXT', TRUE, TRUE), ('number_format_digits', 'Maximum number of decimal digits to display for numeric values.', 'INTEGER', TRUE, TRUE), + ('edit_url', 'If set, an edit button will be added to each row. The value of this property should be a URL, possibly containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row. Clicking the edit button will take the user to that URL. Added in v0.39.0', 'TEXT', TRUE, TRUE), + ('delete_url', 'If set, a delete button will be added to each row. The value of this property should be a URL, possibly containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row. Clicking the delete button will take the user to that URL. Added in v0.39.0', 'TEXT', TRUE, TRUE), + ('custom_actions', 'If set, a column of custom action buttons will be added to each row. The value of this property should be a JSON array of objects, each object defining a button with the following properties: `name` (the text to display on the button), `icon` (the tabler icon name or image link to display on the button), `link` (the URL to navigate to when the button is clicked, possibly containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row), and `tooltip` (optional text to display when hovering over the button). Added in v0.39.0', 'JSON', TRUE, TRUE), -- row level ('_sqlpage_css_class', 'For advanced users. Sets a css class on the table row. Added in v0.8.0.', 'TEXT', FALSE, TRUE), ('_sqlpage_color', 'Sets the background color of the row. Added in v0.8.0.', 'COLOR', FALSE, TRUE), ('_sqlpage_footer', 'Sets this row as the table footer. It is recommended that this parameter is applied to the last row. Added in v0.34.0.', 'BOOLEAN', FALSE, TRUE), - ('_sqlpage_id', 'Sets the id of the html tabler row element. Allows you to make links targeting a specific row in a table.', 'TEXT', FALSE, TRUE) + ('_sqlpage_id', 'Sets the id of the html tabler row element. Allows you to make links targeting a specific row in a table.', 'TEXT', FALSE, TRUE), + ('_sqlpage_actions', 'Sets custom action buttons for this specific row in addition to any defined at the table level, The value of this property should be a JSON array of objects, each object defining a button with the following properties: `name` (the text to display on the button), `icon` (the tabler icon name or image link to display on the button), `link` (the URL to navigate to when the button is clicked, possibly containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row), and `tooltip` (optional text to display when hovering over the button). Added in v0.39.0', 'JSON', FALSE, TRUE) ) x; INSERT INTO example(component, description, properties) VALUES @@ -994,7 +998,124 @@ GROUP BY This will generate a table with the stores in the first column, and the items in the following columns, with the quantity sold in each store for each item. ', NULL - ); + ), + ( + 'table', +'## Using Action Buttons in a table. + +### Preset Actions: `edit_url` & `delete_url` +Since edit and delete are common actions, the `table` component has dedicated `edit_url` and `delete_url` properties to add buttons for these actions. +The value of these properties should be a URL, containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row. + +### Column with fixed action buttons + +You may want to add custom action buttons to your table rows, for instance to view details, download a file, or perform a custom operation. +For this, the `table` component has a `custom_actions` top-level property that lets you define a column of buttons, each button defined by a name, an icon, a link, and an optional tooltip. + +### Column with variable action buttons + +The `table` component also supports the row level `_sqlpage_actions` column in your data table. +This is helpful if you want a more complex logic, for instance to disable a button on some rows, or to change the link or icon based on the row data. + +> WARNING! +> If the number of array items in `_sqlpage_actions` is not consistent across all rows, the table may not render correctly. +> You can leave blank spaces by including an object with only the `name` property. + +The table has a column of buttons, each button defined by the `_sqlpage_actions` column at the table level, and by the `_sqlpage_actions` property at the row level. +### `custom_actions` & `_sqlpage_actions` JSON properties. +Each button is defined by the following properties: +* `name`: sets the column header and the tooltip if no tooltip is provided, +* `tooltip`: text to display when hovering over the button, +* `link`: the URL to navigate to when the button is clicked, possibly containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row, +* `icon`: the tabler icon name or image link to display on the button + +### Example using all of the above +' + , + json('[ + { + "component": "table", + "edit_url": "/examples/show_variables.sql?action=edit&update_id={id}", + "delete_url": "/examples/show_variables.sql?action=delete&delete_id={id}", + "custom_actions": [ + { + "name": "history", + "tooltip": "View Standard History", + "link": "/examples/show_variables.sql?action=history&standard_id={id}", + "icon": "history" + } + ] + }, + { + "name": "CalStd", + "vendor": "PharmaCo", + "Product": "P1234", + "lot number": "T23523", + "status": "Available", + "expires on": "2026-10-13", + "_sqlpage_id": 32, + "_sqlpage_actions": [ + { + "name": "View PDF", + "tooltip": "View Presentation", + "link": "https://sql-page.com/pgconf/2024-sqlpage-badass.pdf", + "icon": "file-type-pdf" + }, + { + "name": "Action", + "tooltip": "Set In Use", + "link": "/examples/show_variables.sql?action=set_in_use&standard_id=32", + "icon": "caret-right" + } + ] + }, + { + "name": "CalStd", + "vendor": "PharmaCo", + "Product": "P1234", + "lot number": "T2352", + "status": "In Use", + "expires on": "2026-10-14", + "_sqlpage_id": 33, + "_sqlpage_actions": [ + { + "name": "View PDF", + "tooltip": "View Presentation", + "link": "https://sql-page.com/pgconf/2024-sqlpage-badass.pdf", + "icon": "file-type-pdf" + }, + { + "name": "Action", + "tooltip": "Retire Standard", + "link": "/examples/show_variables.sql?action=retire&standard_id=33", + "icon": "test-pipe-off" + } + ] + }, + { + "name": "CalStd", + "vendor": "PharmaCo", + "Product": "P1234", + "lot number": "A123", + "status": "Discarded", + "expires on": "2026-09-30", + "_sqlpage_id": 31, + "_sqlpage_actions": [ + { + "name": "View PDF", + "tooltip": "View Presentation", + "link": "https://sql-page.com/pgconf/2024-sqlpage-badass.pdf", + "icon": "file-type-pdf" + }, + { + "name": "Action" + } + ] + } +]' +) +); + INSERT INTO component(name, icon, description) VALUES diff --git a/examples/official-site/sqlpage/templates/shell-home.handlebars b/examples/official-site/sqlpage/templates/shell-home.handlebars index 095c6b73..b4203fa4 100644 --- a/examples/official-site/sqlpage/templates/shell-home.handlebars +++ b/examples/official-site/sqlpage/templates/shell-home.handlebars @@ -1375,7 +1375,7 @@ -
+

More scalable than a spreadsheet

@@ -1391,7 +1391,7 @@
-
+

More dynamic than a dashboard

@@ -1411,7 +1411,7 @@
-
+
Database Compatibility
diff --git a/lambda.Dockerfile b/lambda.Dockerfile index fcd476d4..50b71423 100644 --- a/lambda.Dockerfile +++ b/lambda.Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.90-alpine as builder +FROM rust:1.90-alpine AS builder RUN rustup component add clippy rustfmt RUN apk add --no-cache musl-dev zip WORKDIR /usr/src/sqlpage @@ -13,7 +13,7 @@ RUN mv target/release/sqlpage bootstrap && \ ldd bootstrap && \ zip -9 -r deploy.zip bootstrap index.sql -FROM public.ecr.aws/lambda/provided:al2 as runner +FROM public.ecr.aws/lambda/provided:al2 AS runner COPY --from=builder /usr/src/sqlpage/bootstrap /main COPY --from=builder /usr/src/sqlpage/index.sql ./index.sql ENTRYPOINT ["/main"] \ No newline at end of file diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 00000000..59986f41 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,20 @@ +# Docker Build Scripts + +This directory contains scripts used by the Dockerfile to build SQLPage with cross-compilation support. + +## Scripts + +- **`setup-cross-compilation.sh`**: Sets up the cross-compilation environment based on target and build architectures. Handles system dependencies, cross-compiler installation, and libgcc extraction for runtime. +- **`build-dependencies.sh`**: Builds only the project dependencies for Docker layer caching +- **`build-project.sh`**: Builds the final SQLPage binary + +## Usage + +These scripts are automatically copied and executed by the Dockerfile during the build process. They handle: + +- Cross-compilation setup for different architectures (amd64, arm64, arm) +- System dependencies installation +- Cargo build configuration with appropriate linkers +- Library extraction for runtime + +The scripts use temporary files in `/tmp/` to pass configuration between stages and export environment variables for use in subsequent build steps. diff --git a/scripts/build-dependencies.sh b/scripts/build-dependencies.sh new file mode 100755 index 00000000..e732125f --- /dev/null +++ b/scripts/build-dependencies.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -euo pipefail + +# Source the environment variables set by setup-cross-compilation.sh +TARGET="$(cat /tmp/TARGET)" +LINKER="$(cat /tmp/LINKER)" +BINDGEN_EXTRA_CLANG_ARGS="$(cat /tmp/BINDGEN_EXTRA_CLANG_ARGS || true)" + +echo "Building dependencies for target: $TARGET" + +# Build dependencies only (for Docker layer caching) +cargo build \ + --target "$TARGET" \ + --config "target.$TARGET.linker=\"$LINKER\"" \ + --features odbc-static \ + --profile superoptimized diff --git a/scripts/build-project.sh b/scripts/build-project.sh new file mode 100755 index 00000000..6723fc17 --- /dev/null +++ b/scripts/build-project.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -euo pipefail + +# Source the environment variables set by setup-cross-compilation.sh +TARGET="$(cat /tmp/TARGET)" +LINKER="$(cat /tmp/LINKER)" + +echo "Building project for target: $TARGET" + +# Build the project +touch src/main.rs +cargo build \ + --target "$TARGET" \ + --config "target.$TARGET.linker=\"$LINKER\"" \ + --features odbc-static \ + --profile superoptimized + +# Move the binary to the expected location +mv "target/$TARGET/superoptimized/sqlpage" sqlpage.bin diff --git a/scripts/setup-cross-compilation.sh b/scripts/setup-cross-compilation.sh new file mode 100755 index 00000000..941c99b9 --- /dev/null +++ b/scripts/setup-cross-compilation.sh @@ -0,0 +1,48 @@ +#!/bin/bash +set -euox pipefail + +TARGETARCH="$1" +BUILDARCH="$2" + +apt-get update + +if [ "$TARGETARCH" = "$BUILDARCH" ]; then + # Native build + rustup target list --installed > /tmp/TARGET + echo "gcc" > /tmp/LINKER + apt-get install -y gcc libgcc-s1 make + + LIBDIR="/lib/$(gcc -print-multiarch)" + +elif [ "$TARGETARCH" = "arm64" ]; then + echo "aarch64-unknown-linux-gnu" > /tmp/TARGET + echo "aarch64-linux-gnu-gcc" > /tmp/LINKER + + apt-get install -y gcc-aarch64-linux-gnu libgcc-s1-arm64-cross make + + LIBDIR="/usr/aarch64-linux-gnu/lib" +elif [ "$TARGETARCH" = "arm" ]; then + echo "armv7-unknown-linux-gnueabihf" > /tmp/TARGET + echo "arm-linux-gnueabihf-gcc" > /tmp/LINKER + + apt-get install -y gcc-arm-linux-gnueabihf libgcc-s1-armhf-cross make cmake libclang-dev + + cargo install --force --locked bindgen-cli + + SYSROOT=$(arm-linux-gnueabihf-gcc -print-sysroot) + echo "--sysroot=$SYSROOT -I$SYSROOT/usr/include -I$SYSROOT/usr/include/arm-linux-gnueabihf" > /tmp/BINDGEN_EXTRA_CLANG_ARGS + + LIBDIR="/usr/arm-linux-gnueabihf/lib" +else + echo "Unsupported cross compilation target: $TARGETARCH" + exit 1 +fi + +# Copy libgcc_s.so.1 for runtime +mkdir -p /tmp/sqlpage-libs + +cp "$LIBDIR/libgcc_s.so.1" /tmp/sqlpage-libs/ + +# Add the target +rustup target add "$(cat /tmp/TARGET)" + diff --git a/sqlpage/templates/list.handlebars b/sqlpage/templates/list.handlebars index f8c46431..2837f9e5 100644 --- a/sqlpage/templates/list.handlebars +++ b/sqlpage/templates/list.handlebars @@ -67,9 +67,9 @@ {{#if (eq @row_index 0)}}
-
+
{{default empty_title 'No item'}} -
+
{{~empty_description~}} {{~#if empty_description_md~}}
{{{markdown empty_description_md}}}
diff --git a/sqlpage/templates/shell.handlebars b/sqlpage/templates/shell.handlebars index 35f31b91..0e1c7a8e 100644 --- a/sqlpage/templates/shell.handlebars +++ b/sqlpage/templates/shell.handlebars @@ -95,7 +95,7 @@ {{~#with (parse_json this)}} {{#if (or (or this.title this.icon) this.image)}}