diff --git a/src/addins/postgres/Cargo.lock b/src/addins/postgres/Cargo.lock index 8b6cfab4dd..f3634290f9 100644 --- a/src/addins/postgres/Cargo.lock +++ b/src/addins/postgres/Cargo.lock @@ -27,6 +27,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -57,6 +68,12 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "async-trait" version = "0.1.88" @@ -65,7 +82,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -101,6 +118,18 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -110,12 +139,57 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borsh" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "bumpalo" version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -143,6 +217,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.40" @@ -236,7 +316,7 @@ dependencies = [ "cfg-if", "crossbeam-utils", "equivalent", - "hashbrown", + "hashbrown 0.15.5", "lock_api", "parking_lot_core", ] @@ -272,7 +352,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -327,6 +407,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures-channel" version = "0.3.31" @@ -351,7 +437,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -391,6 +477,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.3.2" @@ -409,12 +506,27 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "hmac" version = "0.12.1" @@ -556,6 +668,16 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "indexmap" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +dependencies = [ + "equivalent", + "hashbrown 0.16.0", +] + [[package]] name = "itoa" version = "1.0.15" @@ -712,7 +834,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -746,6 +868,7 @@ dependencies = [ "dateparser", "postgres", "postgres-native-tls", + "rust_decimal", "serde_json", "uuid", ] @@ -854,7 +977,7 @@ dependencies = [ "hmac", "md-5", "memchr", - "rand", + "rand 0.9.0", "sha2", "stringprep", ] @@ -892,6 +1015,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.94" @@ -901,6 +1033,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "quote" version = "1.0.40" @@ -916,17 +1068,44 @@ version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ - "rand_chacha", - "rand_core", + "rand_chacha 0.9.0", + "rand_core 0.9.3", "zerocopy", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -934,7 +1113,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", ] [[package]] @@ -943,7 +1131,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom", + "getrandom 0.3.2", ] [[package]] @@ -984,6 +1172,61 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "rkyv" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35affe401787a9bd846712274d97654355d21b2a2c092a3139aabe31e9022282" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "postgres-types", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1030,6 +1273,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "security-framework" version = "2.11.1" @@ -1070,7 +1319,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1102,6 +1351,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "1.0.1" @@ -1167,6 +1422,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.100" @@ -1186,9 +1452,15 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.19.1" @@ -1196,7 +1468,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.59.0", @@ -1271,7 +1543,7 @@ dependencies = [ "pin-project-lite", "postgres-protocol", "postgres-types", - "rand", + "rand 0.9.0", "socket2", "tokio", "tokio-util", @@ -1291,6 +1563,36 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml_datetime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7211ff1b8f0d3adae1663b7da9ffe396eabe1ca25f0b0bee42b0da29a9ddce93" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ + "winnow", +] + [[package]] name = "typenum" version = "1.18.0" @@ -1354,7 +1656,7 @@ version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom", + "getrandom 0.3.2", "js-sys", "wasm-bindgen", ] @@ -1414,7 +1716,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.100", "wasm-bindgen-shared", ] @@ -1436,7 +1738,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1590,6 +1892,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen-rt" version = "0.39.0" @@ -1605,6 +1916,15 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "yoke" version = "0.8.1" @@ -1624,7 +1944,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", "synstructure", ] @@ -1645,7 +1965,7 @@ checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1665,7 +1985,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", "synstructure", ] @@ -1699,5 +2019,5 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] diff --git a/src/addins/postgres/Cargo.toml b/src/addins/postgres/Cargo.toml index 2546e2783f..d367056cc1 100644 --- a/src/addins/postgres/Cargo.toml +++ b/src/addins/postgres/Cargo.toml @@ -23,6 +23,7 @@ chrono = "0.4.39" uuid = { version = "1.12.1", features = ["v4"] } postgres-native-tls = "0.5" dateparser = "0.2.1" +rust_decimal = { version = "1.37.2" , features = ["db-postgres", "serde-float", "serde-str"] } common-tcp = { path = "../!commons/common-tcp" } common-utils = { path = "../!commons/common-utils" } common-dataset = { path = "../!commons/common-dataset" } diff --git a/src/addins/postgres/dependencies.log b/src/addins/postgres/dependencies.log index 1650a3bbc0..fac4ab1694 100644 --- a/src/addins/postgres/dependencies.log +++ b/src/addins/postgres/dependencies.log @@ -1,12 +1,12 @@ "MAIN ---" - linux-vdso.so.1 (0x00007fff86784000) - libssl.so.3 => /lib64/libssl.so.3 (0x00007df57fe00000) - libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007df57f600000) - libpthread.so.0 => /lib64/libpthread.so.0 (0x00007df57f200000) - libc.so.6 => /lib64/libc.so.6 (0x00007df57ee00000) - libdl.so.2 => /lib64/libdl.so.2 (0x00007df57ea00000) - /lib64/ld-linux-x86-64.so.2 (0x00007df580400000) - libz.so.1 => /lib64/libz.so.1 (0x00007df57e600000) + linux-vdso.so.1 (0x00007ffdfefdf000) + libssl.so.3 => /lib64/libssl.so.3 (0x0000755644c00000) + libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000755644400000) + libpthread.so.0 => /lib64/libpthread.so.0 (0x0000755644000000) + libc.so.6 => /lib64/libc.so.6 (0x0000755643c00000) + libdl.so.2 => /lib64/libdl.so.2 (0x0000755643800000) + /lib64/ld-linux-x86-64.so.2 (0x0000755645200000) + libz.so.1 => /lib64/libz.so.1 (0x0000755643400000) GLIBC_2.2.5 GLIBC_2.12 GLIBC_2.3 diff --git a/src/addins/postgres/src/component/methods.rs b/src/addins/postgres/src/component/methods.rs index 2e9447f87a..34cd12c847 100644 --- a/src/addins/postgres/src/component/methods.rs +++ b/src/addins/postgres/src/component/methods.rs @@ -4,10 +4,13 @@ use base64::{engine::general_purpose, Engine as _}; use crate::component::AddIn; use std::collections::HashMap; use std::net::IpAddr; +use std::str::FromStr; use chrono::{NaiveDate, NaiveTime, FixedOffset, NaiveDateTime, DateTime}; use common_utils::utils::json_error; use uuid::Uuid; use dateparser::parse; +use rust_decimal::Decimal; +use rust_decimal::prelude::FromPrimitive; pub fn execute_query(add_in: &mut AddIn, key: &str) -> String { @@ -123,6 +126,22 @@ fn process_object(object: &Map) -> Result, .as_f64() .map(|v| Box::new(v) as Box) .ok_or_else(|| "Invalid value for DOUBLE PRECISION".to_string()), + "NUMERIC" | "DECIMAL" => { + + if let Some(num_str) = value.as_str() { + Decimal::from_str(num_str) + .map(|decimal| Box::new(decimal) as Box) + .map_err(|e| format!("Invalid numeric string '{}': {}", num_str, e)) + } else if let Some(num) = value.as_f64() { + Decimal::from_f64(num) + .map(|decimal| Box::new(decimal) as Box) + .ok_or_else(|| "Cannot convert f64 to Decimal".to_string()) + } else if let Some(num) = value.as_i64() { + Ok(Box::new(Decimal::from(num)) as Box) + } else { + Err("Invalid value for NUMERIC/DECIMAL: must be string or number".to_string()) + } + } "VARCHAR" | "TEXT" | "CHAR" | "CITEXT" | "NAME" | "LTREE" | "LQUERY" | "LTXTQUERY" => value .as_str() .map(|v| Box::new(v.to_string()) as Box) @@ -236,7 +255,6 @@ fn rows_to_json(rows: Vec) -> Vec { } fn process_sql_value(column_name: &str, column_type: &str, row: &postgres::Row) -> Result { - let value = match column_type.to_uppercase().as_str() { "BOOL" => row.try_get::<_, Option>(column_name)? .map(Value::Bool) @@ -281,7 +299,7 @@ fn process_sql_value(column_name: &str, column_type: &str, row: &postgres::Row) .unwrap_or("Unable to make Base64 string".to_string()); let mut blob_object = serde_json::Map::new(); - blob_object.insert("BYTEA".to_string(), Value::String(base64_string)); // Оборачиваем в объект + blob_object.insert("BYTEA".to_string(), Value::String(base64_string)); Value::Object(blob_object) }, "HSTORE" => row.try_get::<_, Option>>>(column_name)? @@ -297,7 +315,7 @@ fn process_sql_value(column_name: &str, column_type: &str, row: &postgres::Row) .map(|timestamp| Value::String(timestamp.format("%Y-%m-%dT%H:%M:%S").to_string())) .unwrap_or(Value::Null), "TIMESTAMP WITH TIME ZONE" | "TIMESTAMPTZ" => row.try_get::<_, Option>>(column_name)? - .map(|timestamp| Value::String(timestamp.to_rfc3339())) // RFC3339 - это профиль ISO8601 + .map(|timestamp| Value::String(timestamp.to_rfc3339())) .unwrap_or(Value::Null), "INET" => row.try_get::<_, Option>(column_name)? .map(|ip| Value::String(ip.to_string())) @@ -316,10 +334,15 @@ fn process_sql_value(column_name: &str, column_type: &str, row: &postgres::Row) row.try_get::<_, Option>(column_name)? .map(|uuid| Value::String(uuid.to_string())) .unwrap_or(Value::Null) - } + }, + "NUMERIC" | "DECIMAL" => { + row.try_get::<_, Option>(column_name)? + .map(|decimal| Value::String(decimal.to_string())) + .unwrap_or(Value::Null) + }, current_type => { - match row.try_get::<_, Option>(column_name){ - Ok(v) => v.map(Value::String).unwrap_or(Value::Null), + match try_get_unknown_type(column_name, row) { + Ok(value) => value, Err(_) => Value::String(format!("Unsupported type: {}", current_type)), } }, @@ -327,6 +350,56 @@ fn process_sql_value(column_name: &str, column_type: &str, row: &postgres::Row) Ok(value) } +fn try_get_unknown_type(column_name: &str, row: &postgres::Row) -> Result { + + if let Ok(value) = row.try_get::<_, Option>(column_name) { + return Ok(value.map(|v| Value::Number(v.into())).unwrap_or(Value::Null)); + } + + if let Ok(value) = row.try_get::<_, Option>(column_name) { + return Ok(value.map(|v| Value::Number(v.into())).unwrap_or(Value::Null)); + } + + if let Ok(value) = row.try_get::<_, Option>(column_name) { + return Ok(value.map(|v| Value::Number(v.into())).unwrap_or(Value::Null)); + } + + if let Ok(value) = row.try_get::<_, Option>(column_name) { + return Ok(value.map(|v| { + serde_json::Number::from_f64(v) + .map(Value::Number) + .unwrap_or_else(|| Value::String(v.to_string())) + }).unwrap_or(Value::Null)); + } + + if let Ok(value) = row.try_get::<_, Option>(column_name) { + if let Some(ref str_val) = value { + if str_val.parse::().is_ok() || str_val.parse::().is_ok() { + return Ok(Value::String(str_val.clone())); + } + } + return Ok(value.map(Value::String).unwrap_or(Value::Null)); + } + + if let Ok(value) = row.try_get::<_, Option>(column_name) { + return Ok(value.map(Value::Bool).unwrap_or(Value::Null)); + } + + if let Ok(value) = row.try_get::<_, Option>(column_name) { + return Ok(value.map(Value::String).unwrap_or(Value::Null)); + } + + if let Ok(value) = row.try_get::<_, Option>>(column_name) { + let base64_string = value.map(|v| general_purpose::STANDARD.encode(v)) + .unwrap_or_else(|| "Unable to make Base64 string".to_string()); + let mut blob_object = serde_json::Map::new(); + blob_object.insert("BYTEA".to_string(), Value::String(base64_string)); + return Ok(Value::Object(blob_object)); + } + + Err(()) +} + fn parse_date(input: &str) -> Result { parse(input) .map(|dt| dt.naive_local()) diff --git a/src/en/OInt/addins/OPI_PostgreSQL.zip b/src/en/OInt/addins/OPI_PostgreSQL.zip index 27b57a502b..cc441db4a2 100644 Binary files a/src/en/OInt/addins/OPI_PostgreSQL.zip and b/src/en/OInt/addins/OPI_PostgreSQL.zip differ diff --git a/src/en/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin b/src/en/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin index 27b57a502b..cc441db4a2 100644 Binary files a/src/en/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin and b/src/en/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin differ diff --git a/src/ru/OInt/addins/OPI_PostgreSQL.zip b/src/ru/OInt/addins/OPI_PostgreSQL.zip index 27b57a502b..cc441db4a2 100644 Binary files a/src/ru/OInt/addins/OPI_PostgreSQL.zip and b/src/ru/OInt/addins/OPI_PostgreSQL.zip differ diff --git a/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl index 119fcc4287..c03982386b 100644 --- a/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl @@ -8143,7 +8143,7 @@ Функция Проверка_PostgreSQL_ПолучитьИнформациюОТаблице(Знач Результат, Знач Вариант) Если Не ЗначениеЗаполнено(Вариант) Тогда - ОжидаетЧто(Результат["data"].Количество()).Равно(25); + ОжидаетЧто(Результат["data"].Количество()).Равно(26); Иначе ОжидаетЧто(Результат["data"].Количество()).Равно(0); КонецЕсли; diff --git a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl index 612cac69fd..6b16ed77d2 100644 --- a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl @@ -15040,8 +15040,8 @@ ТипПрокси = "socks5"; // http, socks5, socks4 - АдресПрокси = ПараметрыФункции["Proxy_IP"]; - ПортПрокси = ПараметрыФункции["Proxy_Port"]; + АдресПрокси = ПараметрыФункции["Socks5_IP"]; + ПортПрокси = ПараметрыФункции["Socks5_Port"]; ЛогинПрокси = ПараметрыФункции["Proxy_User"]; ПарольПрокси = ПараметрыФункции["Proxy_Password"]; @@ -15929,6 +15929,7 @@ СтруктураКолонок.Вставить("date_field" , "DATE"); СтруктураКолонок.Вставить("time_field" , "TIME"); СтруктураКолонок.Вставить("uuid_field" , "UUID"); + СтруктураКолонок.Вставить("numeric_field" , "NUMERIC(15, 2)"); OPI_PostgreSQL.УдалитьТаблицу(Таблица, СтрокаПодключения, НастройкиTLS); // SKIP @@ -16056,6 +16057,7 @@ СтруктураЗаписи.Вставить("date_field" , Новый Структура("DATE" , ТекущаяДата)); СтруктураЗаписи.Вставить("time_field" , Новый Структура("TIME" , ТекущаяДата)); СтруктураЗаписи.Вставить("uuid_field" , Новый Структура("UUID" , Новый УникальныйИдентификатор)); + СтруктураЗаписи.Вставить("numeric_field" , Новый Структура("NUMERIC" , 15.2)); МассивЗаписей.Добавить(СтруктураЗаписи); diff --git a/src/ru/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin b/src/ru/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin index 27b57a502b..cc441db4a2 100644 Binary files a/src/ru/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin and b/src/ru/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin differ