From 67cf8ac78d6f468e40c216a2f209c7490dad2430 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Fri, 29 May 2026 13:44:57 +0200 Subject: [PATCH] Update outdated dependencies --- Cargo.lock | 167 +++++++------ sqlx-core/Cargo.toml | 8 +- sqlx-core/src/mysql/connection/auth.rs | 6 +- sqlx-core/src/odbc/connection/odbc_bridge.rs | 18 +- sqlx-core/src/odbc/value.rs | 237 +++++++++---------- tests/sqlite/types.rs | 2 +- 6 files changed, 225 insertions(+), 213 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d338ef1341..06832aaf65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -186,9 +186,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" @@ -418,9 +418,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytecheck" @@ -511,9 +511,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.62" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "jobserver", @@ -647,9 +647,9 @@ dependencies = [ [[package]] name = "cmov" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" [[package]] name = "colorchoice" @@ -870,9 +870,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "hybrid-array", ] @@ -1002,7 +1002,7 @@ checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", "const-oid 0.10.2", - "crypto-common 0.2.1", + "crypto-common 0.2.2", "ctutils", ] @@ -1056,9 +1056,9 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -1106,9 +1106,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" dependencies = [ "serde", ] @@ -1486,15 +1486,14 @@ dependencies = [ [[package]] name = "git2" -version = "0.20.4" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +checksum = "ddddbf932745a6be37109b6112d3ee09696106f848449069d3a57bba937ab82e" dependencies = [ "bitflags 2.11.1", "libc", "libgit2-sys", "log", - "url", ] [[package]] @@ -1594,9 +1593,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" dependencies = [ "bytes", "itoa", @@ -1648,9 +1647,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "eb92f162bf56536459fc83c79b974bb12837acfed43d6bc370a7916d0ae15ecc" dependencies = [ "atomic-waker", "bytes", @@ -1872,9 +1871,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.24" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" +checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" dependencies = [ "jiff-static", "log", @@ -1885,9 +1884,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.24" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" +checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" dependencies = [ "proc-macro2", "quote", @@ -1964,9 +1963,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -2025,21 +2024,21 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ "bitflags 2.11.1", "libc", "plain", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] name = "libsqlite3-sys" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f111c8c41e7c61a49cd34e44c7619462967221a6443b0ec299e0ac30cfb9b1" +checksum = "a76001fb4daed01e5f2b518aac0b4dc592e7c734da63dbffcf0c64fa612a8d0c" dependencies = [ "cc", "openssl-sys", @@ -2088,9 +2087,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" [[package]] name = "mac_address" @@ -2120,9 +2119,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "memoffset" @@ -2150,9 +2149,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi 0.11.1+wasi-snapshot-preview1", @@ -2295,9 +2294,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -2574,9 +2573,9 @@ dependencies = [ [[package]] name = "odbc-api" -version = "25.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9144219b357fb103b928a1ef1b4e466a84b8f52aa9f5d5e538c409e1ffb9d26" +checksum = "24d536fcaf240c7d6c47bd5be3701bc2effd779e25ae23ce95b2193137d90313" dependencies = [ "atoi", "log", @@ -2612,9 +2611,9 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "openssl" -version = "0.10.79" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0b434746ee2832f4f0baf10137e1cabb18cbe6912c69e2e33263c45250f542" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ "bitflags 2.11.1", "cfg-if", @@ -2652,9 +2651,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.115" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "158fe5b292746440aa6e7a7e690e55aeb72d41505e2804c23c6973ad0e9c9781" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -2671,9 +2670,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.54" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a570f6bca41d29acb2139229a7c873ec99bc9a313bd10804081d89bfac8ff329" +checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" dependencies = [ "libc", "libredox", @@ -3075,9 +3074,9 @@ checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] name = "rand_xoshiro" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f0b2cc7bfeef8f0320ca45f88b00157a03c67137022d59393614352d6bf4312" +checksum = "662effc7698e08ea324d3acccf8d9d7f7bf79b9785e270a174ea36e56900c91d" dependencies = [ "rand_core 0.10.1", ] @@ -3128,9 +3127,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" +checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d" dependencies = [ "bitflags 2.11.1", ] @@ -3520,9 +3519,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -3606,6 +3605,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha1" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", +] + [[package]] name = "sha2" version = "0.11.0" @@ -3619,9 +3629,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -3682,9 +3692,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -3795,7 +3805,8 @@ dependencies = [ "rustls", "serde", "serde_json", - "sha1", + "sha1 0.10.6", + "sha1 0.11.0", "sha2", "smallvec", "sqlx-oldapi", @@ -4303,9 +4314,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap 2.14.0", "toml_datetime", @@ -4597,9 +4608,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -4611,9 +4622,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -4621,9 +4632,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4631,9 +4642,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -4644,9 +4655,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -4687,9 +4698,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -5182,18 +5193,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "bce33a6288fa3f072a8c2c7d0f2fdbb90e28298f0135c1f99b96c3db2efcc60b" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "8fd425244944f4ab65ccff928e7323354c5a018c75838362fdce749dfad2ee1e" dependencies = [ "proc-macro2", "quote", diff --git a/sqlx-core/Cargo.toml b/sqlx-core/Cargo.toml index eb3f6e6bea..f35e2512d1 100644 --- a/sqlx-core/Cargo.toml +++ b/sqlx-core/Cargo.toml @@ -37,6 +37,7 @@ postgres = [ ] mysql = [ "sha1", + "sha1_0_10", "sha2", "num-bigint", "rand", @@ -140,7 +141,8 @@ rsa = { version = "0.9.2", optional = true, features = ["getrandom"] } rustls = { version = "0.23", optional = true, default-features = false } serde = { version = "1.0.132", features = ["derive", "rc"], optional = true } serde_json = { version = "1.0.73", features = ["raw_value"], optional = true } -sha1 = { version = "0.10.1", default-features = false, optional = true } +sha1 = { version = "0.11", default-features = false, optional = true } +sha1_0_10 = { version = "0.10.1", package = "sha1", default-features = false, optional = true } sha2 = { version = "0.11", default-features = false, optional = true } thiserror = "2.0.3" time = { version = "0.3.2", features = ["macros", "formatting", "parsing"], optional = true } @@ -153,7 +155,7 @@ webpki-roots = { version = "1.0.0", optional = true } whoami = { version = "2.1.1", optional = true } stringprep = "0.1.2" bstr = { version = "1.6.0", default-features = false, features = ["std"], optional = true } -git2 = { version = "0.20.4", default-features = false, optional = true } +git2 = { version = "0.21", default-features = false, optional = true } hashlink = "0.11.0" # NOTE: *must* remain below 1.7.0 to allow users to avoid the `ahash` cyclic dependency problem by pinning the version # https://github.com/tkaitchuck/aHash/issues/95#issuecomment-874150078 @@ -162,7 +164,7 @@ hkdf = { version = "0.13", optional = true } event-listener = "5.4.0" dotenvy = "0.15" -odbc-api = { version = "25", optional = true } +odbc-api = { version = "28", optional = true } [dev-dependencies] sqlx = { package = "sqlx-oldapi", path = "..", features = ["postgres", "sqlite", "mysql", "rustls"] } diff --git a/sqlx-core/src/mysql/connection/auth.rs b/sqlx-core/src/mysql/connection/auth.rs index 2f235c8d67..49f69df905 100644 --- a/sqlx-core/src/mysql/connection/auth.rs +++ b/sqlx-core/src/mysql/connection/auth.rs @@ -1,8 +1,8 @@ use bytes::buf::Chain; use bytes::Bytes; use rsa::{pkcs8::DecodePublicKey, Oaep, RsaPublicKey}; -use sha1::{Digest as Sha1Digest, Sha1}; -use sha2::{Digest as Sha2Digest, Sha256}; +use sha1::{Digest, Sha1}; +use sha2::Sha256; use crate::error::Error; use crate::mysql::connection::stream::MySqlStream; @@ -147,7 +147,7 @@ async fn encrypt_rsa<'s>( // client sends an RSA encrypted password let pkey = parse_rsa_pub_key(rsa_pub_key)?; - let padding = Oaep::new::(); + let padding = Oaep::new::(); pkey.encrypt(&mut rsa::rand_core::OsRng, padding, &pass[..]) .map_err(Error::protocol) } diff --git a/sqlx-core/src/odbc/connection/odbc_bridge.rs b/sqlx-core/src/odbc/connection/odbc_bridge.rs index 451e441086..917382bde0 100644 --- a/sqlx-core/src/odbc/connection/odbc_bridge.rs +++ b/sqlx-core/src/odbc/connection/odbc_bridge.rs @@ -8,7 +8,7 @@ use crate::odbc::{ }; use either::Either; use flume::{SendError, Sender}; -use odbc_api::buffers::{AnySlice, BufferDesc, ColumnarAnyBuffer}; +use odbc_api::buffers::{AnyColumnBufferSlice, BufferDesc, ColumnarDynBuffer}; use odbc_api::handles::{AsStatementRef, Nullability, Statement}; use odbc_api::{Cursor, IntoParameter, ResultSetMetadata}; use std::sync::Arc; @@ -311,8 +311,12 @@ fn map_buffer_desc(type_info: &OdbcTypeInfo, nullable: bool, max_column_size: us } } -fn create_column_data(slice: AnySlice<'_>, column: &OdbcColumn) -> Result, Error> { - let (values, nulls) = crate::odbc::value::convert_any_slice_to_value_vec(slice)?; +fn create_column_data( + slice: AnyColumnBufferSlice<'_>, + buffer_desc: BufferDesc, + column: &OdbcColumn, +) -> Result, Error> { + let (values, nulls) = crate::odbc::value::convert_dyn_slice_to_value_vec(slice, buffer_desc)?; Ok(Arc::new(ColumnData { values, type_info: column.type_info.clone(), @@ -391,7 +395,7 @@ where C: Cursor + ResultSetMetadata, { let buffer_descriptions: Vec<_> = bindings.iter().map(|b| b.buffer_desc).collect(); - let buffer = ColumnarAnyBuffer::from_descs(batch_size, buffer_descriptions); + let buffer = ColumnarDynBuffer::from_descs(batch_size, buffer_descriptions); let mut row_set_cursor = cursor.bind_buffer(buffer)?; let mut receiver_open = true; @@ -404,7 +408,11 @@ where .iter() .enumerate() .map(|(col_index, binding)| { - create_column_data(batch.column(col_index), &binding.column) + create_column_data( + batch.column(col_index), + binding.buffer_desc, + &binding.column, + ) }) .collect::>()?; diff --git a/sqlx-core/src/odbc/value.rs b/sqlx-core/src/odbc/value.rs index ce566b523b..15ed507e20 100644 --- a/sqlx-core/src/odbc/value.rs +++ b/sqlx-core/src/odbc/value.rs @@ -2,10 +2,9 @@ use crate::error::Error; use crate::odbc::{Odbc, OdbcBatch, OdbcTypeInfo}; use crate::type_info::TypeInfo; use crate::value::{Value, ValueRef}; -use odbc_api::buffers::{AnySlice, NullableSlice}; +use odbc_api::buffers::{AnyColumnBufferSlice, BufferDesc, NullableSlice}; use odbc_api::handles::CDataMut; use odbc_api::parameter::CElement; -use odbc_api::sys::NULL_DATA; use odbc_api::{DataType, Nullable}; use std::borrow::Cow; use std::sync::Arc; @@ -368,158 +367,149 @@ pub enum OdbcValueType { Timestamp(odbc_api::sys::Timestamp), } -/// Generic helper function to handle non-nullable slices -fn handle_non_nullable_slice( +fn handle_non_nullable_slice_with( slice: &[T], - constructor: fn(Vec) -> OdbcValueVec, + constructor: fn(Vec) -> OdbcValueVec, + convert: impl FnMut(T) -> U, ) -> (OdbcValueVec, Vec) { - let vec = slice.to_vec(); - (constructor(vec), vec![false; slice.len()]) + let values = slice.iter().copied().map(convert).collect(); + (constructor(values), vec![false; slice.len()]) } -/// Generic helper function to handle nullable slices with custom default values -fn handle_nullable_slice<'a, T: Default + Copy>( - slice: NullableSlice<'a, T>, - constructor: fn(Vec) -> OdbcValueVec, +fn handle_nullable_slice_with( + slice: NullableSlice<'_, T>, + constructor: fn(Vec) -> OdbcValueVec, + mut convert: impl FnMut(T) -> U, ) -> (OdbcValueVec, Vec) { let size = slice.size_hint().1.unwrap_or(0); let mut values = Vec::with_capacity(size); let mut nulls = Vec::with_capacity(size); for opt in slice { - values.push(opt.copied().unwrap_or_default()); - nulls.push(opt.is_none()); + let is_null = opt.is_none(); + values.push(opt.copied().map(&mut convert).unwrap_or_default()); + nulls.push(is_null); } (constructor(values), nulls) } -/// Generic helper function to handle nullable slices with NULL_DATA indicators -fn handle_nullable_with_indicators( - raw_values: &[T], - indicators: &[isize], - constructor: fn(Vec) -> OdbcValueVec, -) -> (OdbcValueVec, Vec) { - let nulls = indicators.iter().map(|&ind| ind == NULL_DATA).collect(); - (constructor(raw_values.to_vec()), nulls) +fn handle_buffer_slice( + slice: &AnyColumnBufferSlice<'_>, + desc: BufferDesc, + nullable: bool, + constructor: fn(Vec) -> OdbcValueVec, + convert: impl FnMut(T) -> U, +) -> Result<(OdbcValueVec, Vec), Error> { + if nullable { + Ok(handle_nullable_slice_with( + expect_slice(slice.as_nullable_slice::(), desc)?, + constructor, + convert, + )) + } else { + Ok(handle_non_nullable_slice_with( + expect_slice(slice.as_slice::(), desc)?, + constructor, + convert, + )) + } } -fn handle_non_nullable_u8_slice(slice: &[u8]) -> (OdbcValueVec, Vec) { - ( - OdbcValueVec::BigInt(slice.iter().map(|&value| i64::from(value)).collect()), - vec![false; slice.len()], - ) +fn buffer_slice_mismatch(desc: BufferDesc) -> Error { + Error::Protocol(format!( + "ODBC column buffer {desc:?} did not match fetched slice" + )) } -fn handle_nullable_u8_slice(slice: NullableSlice<'_, u8>) -> (OdbcValueVec, Vec) { - let size = slice.size_hint().1.unwrap_or(0); - let mut values = Vec::with_capacity(size); - let mut nulls = Vec::with_capacity(size); +fn expect_slice(slice: Option, desc: BufferDesc) -> Result { + slice.ok_or_else(|| buffer_slice_mismatch(desc)) +} - for opt in slice { - values.push(opt.copied().map(i64::from).unwrap_or_default()); - nulls.push(opt.is_none()); +fn handle_optional_values( + len: usize, + values: impl IntoIterator>, + constructor: fn(Vec) -> OdbcValueVec, + mut convert: impl FnMut(T) -> U, +) -> (OdbcValueVec, Vec) { + let mut converted = Vec::with_capacity(len); + let mut nulls = Vec::with_capacity(len); + + for value in values { + let is_null = value.is_none(); + converted.push(value.map(&mut convert).unwrap_or_default()); + nulls.push(is_null); } - (OdbcValueVec::BigInt(values), nulls) + (constructor(converted), nulls) } -/// Convert AnySlice to owned OdbcValueVec and nulls vector, preserving original types -pub(crate) fn convert_any_slice_to_value_vec( - slice: AnySlice<'_>, +/// Convert a dynamic ODBC column slice to owned values, preserving original types. +pub(crate) fn convert_dyn_slice_to_value_vec( + slice: AnyColumnBufferSlice<'_>, + desc: BufferDesc, ) -> Result<(OdbcValueVec, Vec), Error> { - Ok(match slice { - // Non-nullable integer types - AnySlice::I8(s) => handle_non_nullable_slice(s, OdbcValueVec::TinyInt), - AnySlice::I16(s) => handle_non_nullable_slice(s, OdbcValueVec::SmallInt), - AnySlice::I32(s) => handle_non_nullable_slice(s, OdbcValueVec::Integer), - AnySlice::I64(s) => handle_non_nullable_slice(s, OdbcValueVec::BigInt), - AnySlice::U8(s) => handle_non_nullable_u8_slice(s), - - // Non-nullable floating point types - AnySlice::F32(s) => handle_non_nullable_slice(s, OdbcValueVec::Real), - AnySlice::F64(s) => handle_non_nullable_slice(s, OdbcValueVec::Double), - - // Non-nullable other types - AnySlice::Bit(s) => { - let vec: Vec = s.iter().map(|bit| bit.as_bool()).collect(); - (OdbcValueVec::Bit(vec), vec![false; s.len()]) + Ok(match desc { + BufferDesc::I8 { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::TinyInt, |value| value)? } - AnySlice::Date(s) => handle_non_nullable_slice(s, OdbcValueVec::Date), - AnySlice::Time(s) => handle_non_nullable_slice(s, OdbcValueVec::Time), - AnySlice::Timestamp(s) => handle_non_nullable_slice(s, OdbcValueVec::Timestamp), - - // Nullable integer types - AnySlice::NullableI8(s) => handle_nullable_slice(s, OdbcValueVec::TinyInt), - AnySlice::NullableI16(s) => handle_nullable_slice(s, OdbcValueVec::SmallInt), - AnySlice::NullableI32(s) => handle_nullable_slice(s, OdbcValueVec::Integer), - AnySlice::NullableI64(s) => handle_nullable_slice(s, OdbcValueVec::BigInt), - AnySlice::NullableU8(s) => handle_nullable_u8_slice(s), - AnySlice::NullableF32(s) => handle_nullable_slice(s, OdbcValueVec::Real), - AnySlice::NullableF64(s) => handle_nullable_slice(s, OdbcValueVec::Double), - AnySlice::NullableBit(s) => { - let values: Vec> = s.map(|opt| opt.copied()).collect(); - let nulls = values.iter().map(|opt| opt.is_none()).collect(); - ( - OdbcValueVec::Bit( - values - .into_iter() - .map(|opt| opt.is_some_and(|bit| bit.as_bool())) - .collect(), - ), - nulls, - ) + BufferDesc::I16 { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::SmallInt, |value| { + value + })? } - - // Text and binary types (inherently nullable) - AnySlice::Text(s) => { - let mut values = Vec::with_capacity(s.len()); - let mut nulls = Vec::with_capacity(s.len()); - for bytes_opt in s.iter() { - nulls.push(bytes_opt.is_none()); - values.push(String::from_utf8_lossy(bytes_opt.unwrap_or_default()).into_owned()); - } - (OdbcValueVec::Text(values), nulls) + BufferDesc::I32 { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::Integer, |value| value)? } - AnySlice::WText(s) => { - let mut values = Vec::with_capacity(s.len()); - let mut nulls = Vec::with_capacity(s.len()); - for chars_opt in s.iter() { - nulls.push(chars_opt.is_none()); - values.push( - chars_opt - .map(|chars| String::from_utf16_lossy(chars.into())) - .unwrap_or_default(), - ); - } - (OdbcValueVec::Text(values), nulls) + BufferDesc::I64 { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::BigInt, |value| value)? } - AnySlice::Binary(s) => { - let mut values = Vec::with_capacity(s.len()); - let mut nulls = Vec::with_capacity(s.len()); - for bytes_opt in s.iter() { - nulls.push(bytes_opt.is_none()); - values.push(bytes_opt.unwrap_or_default().to_vec()); - } - (OdbcValueVec::Binary(values), nulls) + BufferDesc::U8 { nullable } => { + handle_buffer_slice::(&slice, desc, nullable, OdbcValueVec::BigInt, i64::from)? } - - // Nullable date/time types with NULL_DATA indicators - AnySlice::NullableDate(s) => { - let (raw_values, indicators) = s.raw_values(); - handle_nullable_with_indicators(raw_values, indicators, OdbcValueVec::Date) + BufferDesc::F32 { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::Real, |value| value)? } - AnySlice::NullableTime(s) => { - let (raw_values, indicators) = s.raw_values(); - handle_nullable_with_indicators(raw_values, indicators, OdbcValueVec::Time) + BufferDesc::F64 { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::Double, |value| value)? } - AnySlice::NullableTimestamp(s) => { - let (raw_values, indicators) = s.raw_values(); - handle_nullable_with_indicators(raw_values, indicators, OdbcValueVec::Timestamp) + BufferDesc::Bit { nullable } => handle_buffer_slice( + &slice, + desc, + nullable, + OdbcValueVec::Bit, + |value: odbc_api::Bit| value.as_bool(), + )?, + BufferDesc::Date { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::Date, |value| value)? } - - unsupported => { + BufferDesc::Time { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::Time, |value| value)? + } + BufferDesc::Timestamp { nullable } => { + handle_buffer_slice(&slice, desc, nullable, OdbcValueVec::Timestamp, |value| { + value + })? + } + BufferDesc::Text { .. } => { + let s = expect_slice(slice.as_text(), desc)?; + handle_optional_values(s.len(), s.iter(), OdbcValueVec::Text, |bytes| { + String::from_utf8_lossy(bytes).into_owned() + }) + } + BufferDesc::WText { .. } => { + let s = expect_slice(slice.as_wide_text(), desc)?; + handle_optional_values(s.len(), s.iter(), OdbcValueVec::Text, |chars| { + String::from_utf16_lossy(chars.into()) + }) + } + BufferDesc::Binary { .. } => { + let s = expect_slice(slice.as_binary(), desc)?; + handle_optional_values(s.len(), s.iter(), OdbcValueVec::Binary, |bytes| { + bytes.to_vec() + }) + } + BufferDesc::Numeric => { return Err(Error::Protocol(format!( - "unsupported ODBC buffer slice variant: {:?}", - std::mem::discriminant(&unsupported) + "unsupported ODBC buffer descriptor: {desc:?}" ))); } }) @@ -531,7 +521,8 @@ mod tests { #[test] fn converts_unsigned_tinyint_slices() { - let (values, nulls) = convert_any_slice_to_value_vec(AnySlice::U8(&[0, 255])).unwrap(); + let (values, nulls) = + handle_non_nullable_slice_with(&[0, 255], OdbcValueVec::BigInt, i64::from); assert_eq!(nulls, vec![false, false]); assert!(matches!(values, OdbcValueVec::BigInt(values) if values == vec![0, 255])); diff --git a/tests/sqlite/types.rs b/tests/sqlite/types.rs index 121f4ba2fb..962823d894 100644 --- a/tests/sqlite/types.rs +++ b/tests/sqlite/types.rs @@ -196,7 +196,7 @@ mod git2 { test_type!(oid( Sqlite, - "x'0000000000000000000000000000000000000000'" == Oid::zero(), + "x'0000000000000000000000000000000000000000'" == Oid::ZERO_SHA1, "x'000102030405060708090a0b0c0d0e0f10111213'" == Oid::from_str("000102030405060708090a0b0c0d0e0f10111213").unwrap() ));