diff --git a/Cargo.lock b/Cargo.lock index d0fe568e..4cd277a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -30,24 +30,31 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "anes" version = "0.1.6" @@ -56,50 +63,51 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -110,39 +118,50 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "auto-build" version = "0.1.0" dependencies = [ - "cornucopia", - "cornucopia_async", + "auto_build_codegen", "deadpool-postgres", "futures", - "postgres-types", "tokio", "tokio-postgres", ] +[[package]] +name = "auto_build_codegen" +version = "0.9.0" +dependencies = [ + "async-trait", + "deadpool-postgres", + "fallible-iterator", + "futures", + "postgres-protocol", + "postgres-types", + "tokio-postgres", +] + [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -164,28 +183,49 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.4" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "basic-async" version = "0.1.0" dependencies = [ - "cornucopia_async", + "basic_async_codegen", "deadpool-postgres", "futures", - "postgres-types", "tokio", "tokio-postgres", ] +[[package]] +name = "basic_async_codegen" +version = "0.9.0" +dependencies = [ + "async-trait", + "deadpool-postgres", + "fallible-iterator", + "futures", + "postgres-protocol", + "postgres-types", + "tokio-postgres", +] + [[package]] name = "basic_sync" version = "0.1.0" dependencies = [ - "cornucopia_sync", + "basic_sync_codegen", + "postgres", +] + +[[package]] +name = "basic_sync_codegen" +version = "0.9.0" +dependencies = [ + "fallible-iterator", "postgres", + "postgres-protocol", "postgres-types", ] @@ -194,13 +234,13 @@ name = "benches" version = "0.1.0" dependencies = [ "cornucopia", - "cornucopia_async", - "cornucopia_sync", "criterion", "diesel", "futures", + "generated", "postgres", "postgres-types", + "tempfile", "tokio", "tokio-postgres", ] @@ -213,9 +253,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -240,60 +280,39 @@ dependencies = [ [[package]] name = "borsh" -version = "0.10.3" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" dependencies = [ "borsh-derive", - "hashbrown 0.13.2", + "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "0.10.3" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", + "once_cell", "proc-macro-crate", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "borsh-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "borsh-schema-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" -dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", + "syn_derive", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -302,9 +321,9 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ "proc-macro2", "quote", @@ -319,9 +338,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cast" @@ -331,12 +350,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.83" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" [[package]] name = "cfg-if" @@ -344,21 +360,27 @@ 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 = "chumsky" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23170228b96236b5a7299057ac284a321457700bc8c41a4476052f0f4ba5349d" +checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" dependencies = [ - "hashbrown 0.12.3", + "hashbrown 0.14.5", "stacker", ] [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -367,15 +389,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", @@ -383,9 +405,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", "clap_derive", @@ -393,9 +415,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", @@ -405,21 +427,41 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + +[[package]] +name = "codegen" +version = "0.9.0" +dependencies = [ + "async-trait", + "deadpool-postgres", + "eui48", + "fallible-iterator", + "futures", + "postgres", + "postgres-protocol", + "postgres-types", + "rust_decimal", + "serde", + "serde_json", + "time", + "tokio-postgres", + "uuid", +] [[package]] name = "codegen_template" @@ -431,9 +473,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "cornucopia" @@ -442,48 +484,21 @@ dependencies = [ "chumsky", "clap", "codegen_template", - "heck", + "heck 0.5.0", "indexmap", + "indoc", "miette", "postgres", "postgres-types", + "tempfile", "thiserror", ] -[[package]] -name = "cornucopia_async" -version = "0.4.0" -dependencies = [ - "async-trait", - "cornucopia_client_core", - "deadpool-postgres", - "tokio-postgres", -] - -[[package]] -name = "cornucopia_client_core" -version = "0.4.0" -dependencies = [ - "fallible-iterator", - "postgres-protocol", - "postgres-types", - "serde", - "serde_json", -] - -[[package]] -name = "cornucopia_sync" -version = "0.4.0" -dependencies = [ - "cornucopia_client_core", - "postgres", -] - [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -526,36 +541,34 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-common" @@ -567,13 +580,47 @@ dependencies = [ "typenum", ] +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.72", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.72", +] + [[package]] name = "deadpool" -version = "0.10.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490" +checksum = "6541a3916932fe57768d4be0b1ffb5ec7cbf74ca8c903fdfd5c0fe8aa958f0ed" dependencies = [ - "async-trait", "deadpool-runtime", "num_cpus", "tokio", @@ -581,11 +628,13 @@ dependencies = [ [[package]] name = "deadpool-postgres" -version = "0.11.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b75ba49590d27f677d3bebaf76cd15889ca8b308bc7ba99bfa25f1d7269c13" +checksum = "1ab8a4ea925ce79678034870834602a2980f4b88c09e97feb266496dbb4493d2" dependencies = [ + "async-trait", "deadpool", + "getrandom", "tokio", "tokio-postgres", "tracing", @@ -593,18 +642,18 @@ dependencies = [ [[package]] name = "deadpool-runtime" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" +checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" dependencies = [ "tokio", ] [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", "serde", @@ -612,11 +661,11 @@ dependencies = [ [[package]] name = "diesel" -version = "2.1.3" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2268a214a6f118fce1838edba3d1561cf0e78d8de785475957a580a7f8c69d33" +checksum = "bf97ee7261bb708fa3402fa9c17a54b70e90e3cb98afb3dc8999d5512cb03f94" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "byteorder", "diesel_derives", "itoa", @@ -625,23 +674,24 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.1.2" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" +checksum = "d6ff2be1e7312c858b2ef974f5c7089833ae57b5311b334b30923af58e5718d8" dependencies = [ "diesel_table_macro_syntax", + "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "diesel_table_macro_syntax" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" +checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" dependencies = [ - "syn 2.0.38", + "syn 2.0.72", ] [[package]] @@ -655,11 +705,34 @@ dependencies = [ "subtle", ] +[[package]] +name = "dir-diff" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ad16bf5f84253b50d6557681c58c3ab67c47c77d39fed9aeb56e947290bd10" +dependencies = [ + "walkdir", +] + +[[package]] +name = "dsl_auto_type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607" +dependencies = [ + "darling", + "either", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "equivalent" @@ -669,12 +742,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -696,15 +769,15 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] -name = "finl_unicode" -version = "1.2.0" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "funty" @@ -714,9 +787,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -729,9 +802,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -739,15 +812,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -756,38 +829,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -801,6 +874,20 @@ dependencies = [ "slab", ] +[[package]] +name = "generated" +version = "0.9.0" +dependencies = [ + "async-trait", + "deadpool-postgres", + "fallible-iterator", + "futures", + "postgres", + "postgres-protocol", + "postgres-types", + "tokio-postgres", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -813,26 +900,32 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "half" -version = "1.8.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "hashbrown" @@ -840,35 +933,36 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] name = "hashbrown" -version = "0.13.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", + "allocator-api2", ] [[package]] -name = "hashbrown" -version = "0.14.1" +name = "heck" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hmac" @@ -879,32 +973,50 @@ dependencies = [ "digest", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "indexmap" -version = "2.0.2" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.5", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", - "rustix", - "windows-sys", + "libc", + "windows-sys 0.52.0", ] [[package]] name = "is_ci" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" [[package]] name = "itertools" @@ -917,36 +1029,36 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] [[package]] name = "libc" -version = "0.2.149" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -954,9 +1066,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "md-5" @@ -970,30 +1082,20 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miette" -version = "5.10.0" +version = "7.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" dependencies = [ "backtrace", "backtrace-ext", - "is-terminal", + "cfg-if", "miette-derive", - "once_cell", "owo-colors", "supports-color", "supports-hyperlinks", @@ -1006,40 +1108,46 @@ dependencies = [ [[package]] name = "miette-derive" -version = "5.10.0" +version = "7.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -1056,36 +1164,36 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "owo-colors" -version = "3.5.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1093,22 +1201,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.3", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "phf" @@ -1130,9 +1238,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1142,9 +1250,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ "num-traits", "plotters-backend", @@ -1155,24 +1263,24 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ "plotters-backend", ] [[package]] name = "postgres" -version = "0.19.7" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7915b33ed60abc46040cbcaa25ffa1c7ec240668e0477c4f3070786f5916d451" +checksum = "6c9ec84ab55b0f9e418675de50052d494ba893fd28c65769a6e68fcdacbee2b8" dependencies = [ "bytes", "fallible-iterator", @@ -1188,17 +1296,17 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83145eba741b050ef981a9a1838c843fa7665e154383325aa8b440ae703180a2" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "postgres-protocol" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" +checksum = "acda0ebdebc28befa84bee35e651e4c5f09073d668c7aed4cf7e23c3cda84b23" dependencies = [ "base64", "byteorder", @@ -1214,9 +1322,9 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" +checksum = "02048d9e032fb3cc3413bbf7b83a15d84a5d419778e2628751896d856498eee9" dependencies = [ "bytes", "eui48", @@ -1243,27 +1351,50 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pq-sys" -version = "0.4.8" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0052426df997c0cbd30789eb44ca097e3541717a7b8fa36b1c464ee7edebd" +checksum = "a24ff9e4cf6945c988f0db7005d87747bf72864965c3529d259ad155ac41d584" dependencies = [ "vcpkg", ] [[package]] name = "proc-macro-crate" -version = "0.1.5" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ - "toml 0.5.11", + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -1299,9 +1430,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1344,9 +1475,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -1354,9 +1485,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -1364,18 +1495,27 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "regex" -version = "1.10.2" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -1385,9 +1525,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -1396,27 +1536,28 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rend" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] [[package]] name = "rkyv" -version = "0.7.42" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", + "bytes", "hashbrown 0.12.3", "ptr_meta", "rend", @@ -1428,9 +1569,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.42" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" dependencies = [ "proc-macro2", "quote", @@ -1439,15 +1580,15 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.32.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" dependencies = [ "arrayvec", "borsh", "bytes", "num-traits", - "postgres", + "postgres-types", "rand", "rkyv", "serde", @@ -1456,34 +1597,34 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-serialize" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" [[package]] name = "rustix" -version = "0.38.19" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1508,29 +1649,29 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -1539,9 +1680,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -1557,15 +1698,6 @@ dependencies = [ "digest", ] -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "simdutf8" version = "0.1.4" @@ -1589,9 +1721,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smawk" @@ -1601,12 +1733,12 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1624,54 +1756,47 @@ dependencies = [ [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "supports-color" -version = "2.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89" +checksum = "9829b314621dfc575df4e409e79f9d6a66a3bd707ab73f23cb4aa3a854ac854f" dependencies = [ - "is-terminal", "is_ci", ] [[package]] name = "supports-hyperlinks" -version = "2.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d" -dependencies = [ - "is-terminal", -] +checksum = "2c0a1e5168041f5f3ff68ff7d95dcb9c8749df29f6e7e89ada40dd4c9de404ee" [[package]] name = "supports-unicode" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6c2cb240ab5dd21ed4906895ee23fe5a48acdbd15a3ce388e7b62a9b66baf7" -dependencies = [ - "is-terminal", -] +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" @@ -1686,15 +1811,27 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "tap" version = "1.0.1" @@ -1703,37 +1840,34 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "terminal_size" -version = "0.1.17" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "libc", - "winapi", + "rustix", + "windows-sys 0.48.0", ] [[package]] name = "test_codegen" version = "0.1.0" dependencies = [ - "cornucopia_async", - "cornucopia_sync", + "codegen", "eui48", "futures", "postgres", - "postgres-types", "rust_decimal", "serde", "serde_json", @@ -1748,18 +1882,19 @@ version = "0.1.0" dependencies = [ "clap", "cornucopia", + "dir-diff", "owo-colors", "postgres", "serde", "tempfile", - "toml 0.8.2", + "toml", ] [[package]] name = "textwrap" -version = "0.15.2" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" dependencies = [ "smawk", "unicode-linebreak", @@ -1768,31 +1903,32 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", + "num-conv", "powerfmt", "serde", "time-core", @@ -1807,10 +1943,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -1826,9 +1963,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -1841,39 +1978,37 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] name = "tokio-postgres" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" +checksum = "03adcf0147e203b6032c0b2d30be1415ba03bc348901f3ff1cc0df6a733e60c3" dependencies = [ "async-trait", "byteorder", @@ -1897,66 +2032,67 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.5.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" dependencies = [ "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.16", ] [[package]] -name = "toml" -version = "0.8.2" +name = "toml_datetime" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", ] [[package]] -name = "toml_datetime" -version = "0.6.3" +name = "toml_edit" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "serde", + "indexmap", + "toml_datetime", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.15", ] [[package]] name = "tracing" -version = "0.1.39" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2ef2af84856a50c1d430afce2fdded0a4ec7eda868db86409b4543df0797f9" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -1971,7 +2107,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", ] [[package]] @@ -1991,9 +2127,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -2009,18 +2145,24 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -2036,15 +2178,15 @@ checksum = "e9df2af067a7953e9c3831320f35c1cc0600c30d44d9f7a12b01db1cd88d6b47" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.4.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "serde", ] @@ -2063,9 +2205,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -2077,11 +2219,17 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2089,24 +2237,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2114,28 +2262,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -2143,11 +2291,12 @@ dependencies = [ [[package]] name = "whoami" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" dependencies = [ - "wasm-bindgen", + "redox_syscall 0.4.1", + "wasite", "web-sys", ] @@ -2169,11 +2318,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2188,7 +2337,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -2197,13 +2355,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2212,47 +2386,104 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" -version = "0.5.17" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0" dependencies = [ "memchr", ] @@ -2265,3 +2496,23 @@ checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] diff --git a/Cargo.toml b/Cargo.toml index 44ea6ac4..3f33dc65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,4 @@ members = [ "test_codegen", "benches", "crates/*", -] +] \ No newline at end of file diff --git a/benches/Cargo.toml b/benches/Cargo.toml index d609523c..d03d8de6 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -8,23 +8,26 @@ edition = "2021" [dependencies] # Path dependencies cornucopia = { path = "../crates/cornucopia" } -cornucopia_sync = { path = "../crates/client_sync" } -cornucopia_async = { path = "../crates/client_async" } # benchmarking criterion = { version = "0.5.1", features = ["html_reports"] } # async -tokio = { version = "1.24.2", features = ["full"] } -futures = "0.3.25" +tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread"] } +futures = "0.3.28" # rust-postgres interaction -postgres = "0.19.4" -tokio-postgres = "0.7.7" -postgres-types = "0.2.4" +postgres = "0.19.5" +tokio-postgres = "0.7.8" +postgres-types = "0.2.5" # diesel -diesel = { version = "2.0.2", features = ["postgres"] } +diesel = { version = "2.0.4", features = ["postgres"] } + +# Temporary files +tempfile = "3.5.0" + +generated = { path = "generated" } [[bench]] name = "execution" diff --git a/benches/codegen.rs b/benches/codegen.rs index 4eabc30f..f8a85151 100644 --- a/benches/codegen.rs +++ b/benches/codegen.rs @@ -5,14 +5,14 @@ fn bench(c: &mut Criterion) { cornucopia::container::cleanup(false).ok(); cornucopia::container::setup(false).unwrap(); let client = &mut cornucopia_conn().unwrap(); - - cornucopia::load_schema(client, &["../codegen_test/schema.sql"]).unwrap(); + let tmp = tempfile::tempdir().unwrap(); + cornucopia::load_schema(client, &["../test_codegen/schema.sql"]).unwrap(); c.bench_function("codegen_sync", |b| { b.iter(|| { - cornucopia::generate_live( + cornucopia::gen_live( client, - "../test_codegen/queries", - None, + "../test_codegen/queries".as_ref(), + tmp.path(), CodegenSettings { gen_sync: true, gen_async: false, @@ -24,10 +24,10 @@ fn bench(c: &mut Criterion) { }); c.bench_function("codegen_async", |b| { b.iter(|| { - cornucopia::generate_live( + cornucopia::gen_live( client, - "../test_codegen/queries", - None, + "../test_codegen/queries".as_ref(), + tmp.path(), CodegenSettings { gen_sync: true, gen_async: false, diff --git a/benches/execution/cornucopia_benches.rs b/benches/execution/cornucopia_benches.rs index 46343a75..3aa7a0c5 100644 --- a/benches/execution/cornucopia_benches.rs +++ b/benches/execution/cornucopia_benches.rs @@ -4,13 +4,11 @@ use criterion::Bencher; use futures::executor::block_on; use tokio_postgres::Client; -use self::generated::queries::bench::{ +use generated::queries::bench::{ async_::{comments_by_post_id, insert_user, post_by_user_ids, select_complex, users}, Comment, Post, User, }; -mod generated; - pub fn bench_trivial_query(b: &mut Bencher, client: &Client) { let mut stmt = users(); b.iter(|| block_on(async { stmt.bind(client).all().await.unwrap() })) @@ -113,7 +111,7 @@ pub mod sync { use criterion::Bencher; use postgres::Client; - use super::generated::queries::bench::{ + use generated::queries::bench::{ sync::{comments_by_post_id, insert_user, post_by_user_ids, select_complex, users}, Comment, Post, User, }; diff --git a/benches/execution/cornucopia_benches/generated.rs b/benches/execution/cornucopia_benches/generated.rs deleted file mode 100644 index 33f68dd2..00000000 --- a/benches/execution/cornucopia_benches/generated.rs +++ /dev/null @@ -1,963 +0,0 @@ -// This file was generated with `cornucopia`. Do not modify. - -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod types {} -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod queries { - pub mod bench { - #[derive(Debug)] - pub struct InsertUserParams< - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - > { - pub name: T1, - pub hair_color: Option, - } - #[derive(Debug, Clone, PartialEq)] - pub struct User { - pub id: i32, - pub name: String, - pub hair_color: Option, - } - pub struct UserBorrowed<'a> { - pub id: i32, - pub name: &'a str, - pub hair_color: Option<&'a str>, - } - impl<'a> From> for User { - fn from( - UserBorrowed { - id, - name, - hair_color, - }: UserBorrowed<'a>, - ) -> Self { - Self { - id, - name: name.into(), - hair_color: hair_color.map(|v| v.into()), - } - } - } - #[derive(Debug, Clone, PartialEq)] - pub struct Post { - pub id: i32, - pub user_id: i32, - pub title: String, - pub body: Option, - } - pub struct PostBorrowed<'a> { - pub id: i32, - pub user_id: i32, - pub title: &'a str, - pub body: Option<&'a str>, - } - impl<'a> From> for Post { - fn from( - PostBorrowed { - id, - user_id, - title, - body, - }: PostBorrowed<'a>, - ) -> Self { - Self { - id, - user_id, - title: title.into(), - body: body.map(|v| v.into()), - } - } - } - #[derive(Debug, Clone, PartialEq)] - pub struct Comment { - pub id: i32, - pub post_id: i32, - pub text: String, - } - pub struct CommentBorrowed<'a> { - pub id: i32, - pub post_id: i32, - pub text: &'a str, - } - impl<'a> From> for Comment { - fn from(CommentBorrowed { id, post_id, text }: CommentBorrowed<'a>) -> Self { - Self { - id, - post_id, - text: text.into(), - } - } - } - #[derive(Debug, Clone, PartialEq)] - pub struct SelectComplex { - pub myuser_id: i32, - pub name: String, - pub hair_color: Option, - pub post_id: Option, - pub user_id: Option, - pub title: Option, - pub body: Option, - } - pub struct SelectComplexBorrowed<'a> { - pub myuser_id: i32, - pub name: &'a str, - pub hair_color: Option<&'a str>, - pub post_id: Option, - pub user_id: Option, - pub title: Option<&'a str>, - pub body: Option<&'a str>, - } - impl<'a> From> for SelectComplex { - fn from( - SelectComplexBorrowed { - myuser_id, - name, - hair_color, - post_id, - user_id, - title, - body, - }: SelectComplexBorrowed<'a>, - ) -> Self { - Self { - myuser_id, - name: name.into(), - hair_color: hair_color.map(|v| v.into()), - post_id, - user_id, - title: title.map(|v| v.into()), - body: body.map(|v| v.into()), - } - } - } - pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct UserQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::UserBorrowed, - mapper: fn(super::UserBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> UserQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::UserBorrowed) -> R, - ) -> UserQuery<'a, C, R, N> { - UserQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct PostQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::PostBorrowed, - mapper: fn(super::PostBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PostQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::PostBorrowed) -> R, - ) -> PostQuery<'a, C, R, N> { - PostQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct CommentQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::CommentBorrowed, - mapper: fn(super::CommentBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> CommentQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::CommentBorrowed) -> R, - ) -> CommentQuery<'a, C, R, N> { - CommentQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct SelectComplexQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::SelectComplexBorrowed, - mapper: fn(super::SelectComplexBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectComplexQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::SelectComplexBorrowed) -> R, - ) -> SelectComplexQuery<'a, C, R, N> { - SelectComplexQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn users() -> UsersStmt { - UsersStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM users")) - } - pub struct UsersStmt(cornucopia_sync::private::Stmt); - impl UsersStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> UserQuery<'a, C, super::User, 0> { - UserQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::UserBorrowed { - id: row.get(0), - name: row.get(1), - hair_color: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - pub fn insert_user() -> InsertUserStmt { - InsertUserStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO users (name, hair_color) VALUES ($1, $2)", - )) - } - pub struct InsertUserStmt(cornucopia_sync::private::Stmt); - impl InsertUserStmt { - pub fn bind< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::StringSql, - >( - &'a mut self, - client: &'a mut C, - name: &'a T1, - hair_color: &'a Option, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[name, hair_color]) - } - } - impl< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::StringSql, - > - cornucopia_sync::Params< - 'a, - super::InsertUserParams, - Result, - C, - > for InsertUserStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::InsertUserParams, - ) -> Result { - self.bind(client, ¶ms.name, ¶ms.hair_color) - } - } - pub fn posts() -> PostsStmt { - PostsStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM posts")) - } - pub struct PostsStmt(cornucopia_sync::private::Stmt); - impl PostsStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> PostQuery<'a, C, super::Post, 0> { - PostQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::PostBorrowed { - id: row.get(0), - user_id: row.get(1), - title: row.get(2), - body: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn post_by_user_ids() -> PostByUserIdsStmt { - PostByUserIdsStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM posts WHERE user_id = ANY($1)", - )) - } - pub struct PostByUserIdsStmt(cornucopia_sync::private::Stmt); - impl PostByUserIdsStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::ArraySql>( - &'a mut self, - client: &'a mut C, - ids: &'a T1, - ) -> PostQuery<'a, C, super::Post, 1> { - PostQuery { - client, - params: [ids], - stmt: &mut self.0, - extractor: |row| super::PostBorrowed { - id: row.get(0), - user_id: row.get(1), - title: row.get(2), - body: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn comments() -> CommentsStmt { - CommentsStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM comments", - )) - } - pub struct CommentsStmt(cornucopia_sync::private::Stmt); - impl CommentsStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> CommentQuery<'a, C, super::Comment, 0> { - CommentQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::CommentBorrowed { - id: row.get(0), - post_id: row.get(1), - text: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - pub fn comments_by_post_id() -> CommentsByPostIdStmt { - CommentsByPostIdStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM comments WHERE post_id = ANY($1)", - )) - } - pub struct CommentsByPostIdStmt(cornucopia_sync::private::Stmt); - impl CommentsByPostIdStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::ArraySql>( - &'a mut self, - client: &'a mut C, - ids: &'a T1, - ) -> CommentQuery<'a, C, super::Comment, 1> { - CommentQuery { - client, - params: [ids], - stmt: &mut self.0, - extractor: |row| super::CommentBorrowed { - id: row.get(0), - post_id: row.get(1), - text: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - pub fn select_complex() -> SelectComplexStmt { - SelectComplexStmt(cornucopia_sync :: private :: Stmt :: new("SELECT u.id as myuser_id, u.name, u.hair_color, p.id as post_id, p.user_id, p.title, p.body FROM users as u LEFT JOIN posts as p on u.id = p.user_id")) - } - pub struct SelectComplexStmt(cornucopia_sync::private::Stmt); - impl SelectComplexStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> SelectComplexQuery<'a, C, super::SelectComplex, 0> { - SelectComplexQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::SelectComplexBorrowed { - myuser_id: row.get(0), - name: row.get(1), - hair_color: row.get(2), - post_id: row.get(3), - user_id: row.get(4), - title: row.get(5), - body: row.get(6), - }, - mapper: |it| ::from(it), - } - } - } - } - pub mod async_ { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct UserQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::UserBorrowed, - mapper: fn(super::UserBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> UserQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::UserBorrowed) -> R, - ) -> UserQuery<'a, C, R, N> { - UserQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct PostQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::PostBorrowed, - mapper: fn(super::PostBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PostQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::PostBorrowed) -> R, - ) -> PostQuery<'a, C, R, N> { - PostQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct CommentQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::CommentBorrowed, - mapper: fn(super::CommentBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> CommentQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::CommentBorrowed) -> R, - ) -> CommentQuery<'a, C, R, N> { - CommentQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct SelectComplexQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::SelectComplexBorrowed, - mapper: fn(super::SelectComplexBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectComplexQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::SelectComplexBorrowed) -> R, - ) -> SelectComplexQuery<'a, C, R, N> { - SelectComplexQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn users() -> UsersStmt { - UsersStmt(cornucopia_async::private::Stmt::new("SELECT * FROM users")) - } - pub struct UsersStmt(cornucopia_async::private::Stmt); - impl UsersStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> UserQuery<'a, C, super::User, 0> { - UserQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::UserBorrowed { - id: row.get(0), - name: row.get(1), - hair_color: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - pub fn insert_user() -> InsertUserStmt { - InsertUserStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO users (name, hair_color) VALUES ($1, $2)", - )) - } - pub struct InsertUserStmt(cornucopia_async::private::Stmt); - impl InsertUserStmt { - pub async fn bind< - 'a, - C: GenericClient, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - >( - &'a mut self, - client: &'a C, - name: &'a T1, - hair_color: &'a Option, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[name, hair_color]).await - } - } - impl< - 'a, - C: GenericClient + Send + Sync, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - > - cornucopia_async::Params< - 'a, - super::InsertUserParams, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for InsertUserStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::InsertUserParams, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.name, ¶ms.hair_color)) - } - } - pub fn posts() -> PostsStmt { - PostsStmt(cornucopia_async::private::Stmt::new("SELECT * FROM posts")) - } - pub struct PostsStmt(cornucopia_async::private::Stmt); - impl PostsStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> PostQuery<'a, C, super::Post, 0> { - PostQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::PostBorrowed { - id: row.get(0), - user_id: row.get(1), - title: row.get(2), - body: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn post_by_user_ids() -> PostByUserIdsStmt { - PostByUserIdsStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM posts WHERE user_id = ANY($1)", - )) - } - pub struct PostByUserIdsStmt(cornucopia_async::private::Stmt); - impl PostByUserIdsStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::ArraySql>( - &'a mut self, - client: &'a C, - ids: &'a T1, - ) -> PostQuery<'a, C, super::Post, 1> { - PostQuery { - client, - params: [ids], - stmt: &mut self.0, - extractor: |row| super::PostBorrowed { - id: row.get(0), - user_id: row.get(1), - title: row.get(2), - body: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn comments() -> CommentsStmt { - CommentsStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM comments", - )) - } - pub struct CommentsStmt(cornucopia_async::private::Stmt); - impl CommentsStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> CommentQuery<'a, C, super::Comment, 0> { - CommentQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::CommentBorrowed { - id: row.get(0), - post_id: row.get(1), - text: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - pub fn comments_by_post_id() -> CommentsByPostIdStmt { - CommentsByPostIdStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM comments WHERE post_id = ANY($1)", - )) - } - pub struct CommentsByPostIdStmt(cornucopia_async::private::Stmt); - impl CommentsByPostIdStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::ArraySql>( - &'a mut self, - client: &'a C, - ids: &'a T1, - ) -> CommentQuery<'a, C, super::Comment, 1> { - CommentQuery { - client, - params: [ids], - stmt: &mut self.0, - extractor: |row| super::CommentBorrowed { - id: row.get(0), - post_id: row.get(1), - text: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - pub fn select_complex() -> SelectComplexStmt { - SelectComplexStmt(cornucopia_async :: private :: Stmt :: new("SELECT u.id as myuser_id, u.name, u.hair_color, p.id as post_id, p.user_id, p.title, p.body FROM users as u LEFT JOIN posts as p on u.id = p.user_id")) - } - pub struct SelectComplexStmt(cornucopia_async::private::Stmt); - impl SelectComplexStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> SelectComplexQuery<'a, C, super::SelectComplex, 0> { - SelectComplexQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::SelectComplexBorrowed { - myuser_id: row.get(0), - name: row.get(1), - hair_color: row.get(2), - post_id: row.get(3), - user_id: row.get(4), - title: row.get(5), - body: row.get(6), - }, - mapper: |it| ::from(it), - } - } - } - } - } -} diff --git a/benches/execution/main.rs b/benches/execution/main.rs index 64d07a86..bf9e2b33 100644 --- a/benches/execution/main.rs +++ b/benches/execution/main.rs @@ -144,7 +144,7 @@ fn bench(c: &mut Criterion) { &mut PgConnection::establish("postgresql://postgres:postgres@127.0.0.1:5435/postgres") .unwrap(); - cornucopia::load_schema(client, &["usage/cornucopia_benches/schema.sql"]).unwrap(); + cornucopia::load_schema(client, &["schema.sql"]).unwrap(); { let mut group = c.benchmark_group("bench_trivial_query"); for size in QUERY_SIZE { diff --git a/benches/generated/Cargo.toml b/benches/generated/Cargo.toml new file mode 100644 index 00000000..353d4423 --- /dev/null +++ b/benches/generated/Cargo.toml @@ -0,0 +1,33 @@ +# This file was generated with `cornucopia`. Do not modify +[package] +name = "generated" +version = "0.9.0" +edition = "2021" + +[features] +default = ["deadpool"] +deadpool = ["dep:deadpool-postgres"] + +[dependencies] +## Core dependencies +# Postgres types +postgres-types = { version = "0.2.6", features = ["derive"] } +# Postgres interaction +postgres-protocol = "0.6.6" +# Iterator utils required for working with `postgres_protocol::types::ArrayValues` +fallible-iterator = "0.2.0" + +## Sync client dependencies +# Postgres sync client +postgres = { version = "0.19.7", features = [] } + +## Async client dependencies +# Postgres async client +tokio-postgres = { version = "0.7.10", features = [] } +# Async utils +async-trait = "0.1.78" +futures = "0.3.30" + +## Async features dependencies +# Async connection pooling +deadpool-postgres = { version = "0.14.0", optional = true } diff --git a/crates/client_core/src/array_iterator.rs b/benches/generated/src/array_iterator.rs similarity index 95% rename from crates/client_core/src/array_iterator.rs rename to benches/generated/src/array_iterator.rs index d8089afc..429ac0d6 100644 --- a/crates/client_core/src/array_iterator.rs +++ b/benches/generated/src/array_iterator.rs @@ -1,11 +1,11 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::utils::escape_domain; use fallible_iterator::FallibleIterator; use postgres_protocol::types::{array_from_sql, ArrayValues}; use postgres_types::{FromSql, Kind, Type}; use std::fmt::Debug; use std::marker::PhantomData; - -use crate::utils::escape_domain; - /// Iterator over the items in a PostgreSQL array. You only need this if you are /// working with custom zero-cost type mapping of rows containing PostgreSQL arrays. pub struct ArrayIterator<'a, T: FromSql<'a>> { @@ -13,7 +13,6 @@ pub struct ArrayIterator<'a, T: FromSql<'a>> { ty: Type, _type: PhantomData, } - impl<'a, T: FromSql<'a>> Debug for ArrayIterator<'a, T> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ArrayIterator") @@ -23,10 +22,8 @@ impl<'a, T: FromSql<'a>> Debug for ArrayIterator<'a, T> { .finish() } } - impl<'a, T: FromSql<'a>> Iterator for ArrayIterator<'a, T> { type Item = T; - fn next(&mut self) -> Option { self.values .next() @@ -34,7 +31,6 @@ impl<'a, T: FromSql<'a>> Iterator for ArrayIterator<'a, T> { .map(|raw| T::from_sql_nullable(&self.ty, raw).unwrap()) } } - impl<'a, T: FromSql<'a>> FromSql<'a> for ArrayIterator<'a, T> { fn from_sql( ty: &Type, @@ -44,19 +40,16 @@ impl<'a, T: FromSql<'a>> FromSql<'a> for ArrayIterator<'a, T> { Kind::Array(ref member) => escape_domain(member), _ => panic!("expected array type got {ty}"), }; - let array = array_from_sql(raw)?; if array.dimensions().count()? > 1 { return Err("array contains too many dimensions".into()); } - Ok(ArrayIterator { ty: member_type.clone(), values: array.values(), _type: PhantomData, }) } - fn accepts(ty: &Type) -> bool { match *ty.kind() { Kind::Array(ref inner) => T::accepts(escape_domain(inner)), diff --git a/benches/generated/src/client.rs b/benches/generated/src/client.rs new file mode 100644 index 00000000..c0a0df64 --- /dev/null +++ b/benches/generated/src/client.rs @@ -0,0 +1,2 @@ +pub mod async_; +pub mod sync; diff --git a/crates/client_async/src/private.rs b/benches/generated/src/client/async_.rs similarity index 59% rename from crates/client_async/src/private.rs rename to benches/generated/src/client/async_.rs index 5ab675d9..a40fc681 100644 --- a/crates/client_async/src/private.rs +++ b/benches/generated/src/client/async_.rs @@ -1,14 +1,21 @@ -pub use cornucopia_client_core::{slice_iter, Domain, DomainArray}; +// This file was generated with `cornucopia`. Do not modify. -use crate::generic_client::GenericClient; +pub use generic_client::GenericClient; use tokio_postgres::{Error, Statement}; - +#[cfg(feature = "deadpool")] +mod deadpool; +mod generic_client; +/// This trait allows you to bind parameters to a query using a single +/// struct, rather than passing each bind parameter as a function parameter. +pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a C, params: &'a P) -> O; +} /// Cached statement +#[doc(hidden)] pub struct Stmt { query: &'static str, cached: Option, } - impl Stmt { #[must_use] pub fn new(query: &'static str) -> Self { @@ -17,7 +24,6 @@ impl Stmt { cached: None, } } - pub async fn prepare<'a, C: GenericClient>( &'a mut self, client: &C, @@ -26,7 +32,6 @@ impl Stmt { let stmt = client.prepare(self.query).await?; self.cached = Some(stmt); } - // the statement is always prepared at this point Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) } } diff --git a/crates/client_async/src/deadpool.rs b/benches/generated/src/client/async_/deadpool.rs similarity index 97% rename from crates/client_async/src/deadpool.rs rename to benches/generated/src/client/async_/deadpool.rs index 8d0a78cd..641a31c1 100644 --- a/crates/client_async/src/deadpool.rs +++ b/benches/generated/src/client/async_/deadpool.rs @@ -1,3 +1,6 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::generic_client::GenericClient; use async_trait::async_trait; use deadpool_postgres::{ Client as DeadpoolClient, ClientWrapper, Transaction as DeadpoolTransaction, @@ -6,15 +9,11 @@ use tokio_postgres::{ types::BorrowToSql, Client as PgClient, Error, RowStream, Statement, ToStatement, Transaction as PgTransaction, }; - -use crate::generic_client::GenericClient; - #[async_trait] impl GenericClient for DeadpoolClient { async fn prepare(&self, query: &str) -> Result { ClientWrapper::prepare_cached(self, query).await } - async fn execute( &self, query: &T, @@ -25,7 +24,6 @@ impl GenericClient for DeadpoolClient { { PgClient::execute(self, query, params).await } - async fn query_one( &self, statement: &T, @@ -36,7 +34,6 @@ impl GenericClient for DeadpoolClient { { PgClient::query_one(self, statement, params).await } - async fn query_opt( &self, statement: &T, @@ -47,7 +44,6 @@ impl GenericClient for DeadpoolClient { { PgClient::query_opt(self, statement, params).await } - async fn query( &self, query: &T, @@ -58,7 +54,6 @@ impl GenericClient for DeadpoolClient { { PgClient::query(self, query, params).await } - async fn query_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, @@ -69,13 +64,11 @@ impl GenericClient for DeadpoolClient { PgClient::query_raw(self, statement, params).await } } - #[async_trait] impl GenericClient for DeadpoolTransaction<'_> { async fn prepare(&self, query: &str) -> Result { DeadpoolTransaction::prepare_cached(self, query).await } - async fn execute( &self, query: &T, @@ -86,7 +79,6 @@ impl GenericClient for DeadpoolTransaction<'_> { { PgTransaction::execute(self, query, params).await } - async fn query_one( &self, statement: &T, @@ -97,7 +89,6 @@ impl GenericClient for DeadpoolTransaction<'_> { { PgTransaction::query_one(self, statement, params).await } - async fn query_opt( &self, statement: &T, @@ -108,7 +99,6 @@ impl GenericClient for DeadpoolTransaction<'_> { { PgTransaction::query_opt(self, statement, params).await } - async fn query( &self, query: &T, @@ -119,7 +109,6 @@ impl GenericClient for DeadpoolTransaction<'_> { { PgTransaction::query(self, query, params).await } - async fn query_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, diff --git a/crates/client_async/src/generic_client.rs b/benches/generated/src/client/async_/generic_client.rs similarity index 98% rename from crates/client_async/src/generic_client.rs rename to benches/generated/src/client/async_/generic_client.rs index e0042c9b..b1b6314a 100644 --- a/crates/client_async/src/generic_client.rs +++ b/benches/generated/src/client/async_/generic_client.rs @@ -1,8 +1,9 @@ +// This file was generated with `cornucopia`. Do not modify. + use async_trait::async_trait; use tokio_postgres::{ types::BorrowToSql, Client, Error, RowStream, Statement, ToStatement, Transaction, }; - /// Abstraction over multiple types of asynchronous clients. /// This allows you to use tokio_postgres clients and transactions interchangeably. /// @@ -39,7 +40,6 @@ pub trait GenericClient: Send + Sync { ) -> Result, Error> where T: ?Sized + tokio_postgres::ToStatement + Sync + Send; - async fn query_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, @@ -47,13 +47,11 @@ pub trait GenericClient: Send + Sync { I: IntoIterator + Sync + Send, I::IntoIter: ExactSizeIterator; } - #[async_trait] impl GenericClient for Transaction<'_> { async fn prepare(&self, query: &str) -> Result { Transaction::prepare(self, query).await } - async fn execute( &self, query: &T, @@ -64,7 +62,6 @@ impl GenericClient for Transaction<'_> { { Transaction::execute(self, query, params).await } - async fn query_one( &self, statement: &T, @@ -75,7 +72,6 @@ impl GenericClient for Transaction<'_> { { Transaction::query_one(self, statement, params).await } - async fn query_opt( &self, statement: &T, @@ -86,7 +82,6 @@ impl GenericClient for Transaction<'_> { { Transaction::query_opt(self, statement, params).await } - async fn query( &self, query: &T, @@ -97,7 +92,6 @@ impl GenericClient for Transaction<'_> { { Transaction::query(self, query, params).await } - async fn query_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, @@ -108,13 +102,11 @@ impl GenericClient for Transaction<'_> { Transaction::query_raw(self, statement, params).await } } - #[async_trait] impl GenericClient for Client { async fn prepare(&self, query: &str) -> Result { Client::prepare(self, query).await } - async fn execute( &self, query: &T, @@ -125,7 +117,6 @@ impl GenericClient for Client { { Client::execute(self, query, params).await } - async fn query_one( &self, statement: &T, @@ -136,7 +127,6 @@ impl GenericClient for Client { { Client::query_one(self, statement, params).await } - async fn query_opt( &self, statement: &T, @@ -147,7 +137,6 @@ impl GenericClient for Client { { Client::query_opt(self, statement, params).await } - async fn query( &self, query: &T, @@ -158,7 +147,6 @@ impl GenericClient for Client { { Client::query(self, query, params).await } - async fn query_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, diff --git a/crates/client_sync/src/private.rs b/benches/generated/src/client/sync.rs similarity index 63% rename from crates/client_sync/src/private.rs rename to benches/generated/src/client/sync.rs index fa01d7c8..64188901 100644 --- a/crates/client_sync/src/private.rs +++ b/benches/generated/src/client/sync.rs @@ -1,13 +1,17 @@ -pub use cornucopia_client_core::{slice_iter, Domain, DomainArray}; +// This file was generated with `cornucopia`. Do not modify. use postgres::Statement; - +/// This trait allows you to bind parameters to a query using a single +/// struct, rather than passing each bind parameter as a function parameter. +pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a mut C, params: &'a P) -> O; +} /// Cached statement -pub struct Stmt { +#[doc(hidden)] +pub(crate) struct Stmt { query: &'static str, cached: Option, } - impl Stmt { #[must_use] pub fn new(query: &'static str) -> Self { @@ -16,7 +20,6 @@ impl Stmt { cached: None, } } - pub fn prepare<'a, C: postgres::GenericClient>( &'a mut self, client: &mut C, @@ -25,7 +28,6 @@ impl Stmt { let stmt = client.prepare(self.query)?; self.cached = Some(stmt); } - // the statement is always prepared at this point Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) } } diff --git a/crates/client_core/src/domain.rs b/benches/generated/src/domain.rs similarity index 93% rename from crates/client_core/src/domain.rs rename to benches/generated/src/domain.rs index 67b35ad7..d0510159 100644 --- a/crates/client_core/src/domain.rs +++ b/benches/generated/src/domain.rs @@ -1,20 +1,18 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::{type_traits::ArraySql, utils::escape_domain}; use postgres_protocol::types::{array_to_sql, ArrayDimension}; use postgres_types::{private::BytesMut, IsNull, Kind, ToSql, Type}; use std::{ error::Error, fmt::{Debug, Formatter}, }; - -use crate::{type_traits::ArraySql, utils::escape_domain}; - pub struct Domain(pub T); - impl Debug for Domain { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_tuple("DomainWrapper").field(&self.0).finish() } } - impl ToSql for Domain { fn to_sql(&self, ty: &Type, out: &mut BytesMut) -> Result> where @@ -22,14 +20,12 @@ impl ToSql for Domain { { postgres_types::ToSql::to_sql(&self.0, escape_domain(ty), out) } - fn accepts(ty: &Type) -> bool where Self: Sized, { return T::accepts(escape_domain(ty)); } - fn to_sql_checked( &self, ty: &Type, @@ -38,27 +34,22 @@ impl ToSql for Domain { postgres_types::__to_sql_checked(self, ty, out) } } - pub struct DomainArray<'a, T: ToSql + Sync, A: ArraySql>(pub &'a A); - impl<'a, T: ToSql + Sync, A: ArraySql> Debug for DomainArray<'a, T, A> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_tuple("ArrayDomain").field(&self.0).finish() } } - impl<'a, T: ToSql + Sync + 'a, A: ArraySql> ToSql for DomainArray<'a, T, A> { fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { self.0.escape_domain_to_sql(ty, w) } - fn accepts(ty: &Type) -> bool { match *ty.kind() { Kind::Array(ref member) => T::accepts(escape_domain(member)), _ => false, } } - fn to_sql_checked( &self, ty: &Type, @@ -67,22 +58,19 @@ impl<'a, T: ToSql + Sync + 'a, A: ArraySql> ToSql for DomainArray<'a, postgres_types::__to_sql_checked(self, ty, out) } } - pub fn escape_domain_to_sql( ty: &Type, w: &mut BytesMut, - iter: impl Iterator + ExactSizeIterator, + iter: impl ExactSizeIterator, ) -> Result> { let member_type = match *ty.kind() { Kind::Array(ref member) => escape_domain(member), _ => panic!("expected array type got {ty}"), }; - let dimension = ArrayDimension { len: downcast(iter.len())?, lower_bound: 1, }; - array_to_sql( Some(dimension), member_type.oid(), @@ -95,9 +83,8 @@ pub fn escape_domain_to_sql( )?; Ok(IsNull::No) } - fn downcast(len: usize) -> Result> { - if len > i32::max_value() as usize { + if len > i32::MAX as usize { Err("value too large to transmit".into()) } else { Ok(len as i32) diff --git a/benches/generated/src/lib.rs b/benches/generated/src/lib.rs new file mode 100644 index 00000000..996a9387 --- /dev/null +++ b/benches/generated/src/lib.rs @@ -0,0 +1,21 @@ +// This file was generated with `cornucopia`. Do not modify. + +mod array_iterator; +pub mod client; +mod domain; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod queries; +mod type_traits; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod types; +mod utils; +pub use array_iterator::ArrayIterator; +pub use domain::{Domain, DomainArray}; +pub use type_traits::{ArraySql, BytesSql, IterSql, StringSql}; +pub(crate) use utils::slice_iter; diff --git a/benches/generated/src/queries.rs b/benches/generated/src/queries.rs new file mode 100644 index 00000000..ca62f15b --- /dev/null +++ b/benches/generated/src/queries.rs @@ -0,0 +1,15 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub mod bench; +pub mod sync { + pub mod bench { + pub use super::super::bench::sync::*; + pub use super::super::bench::*; + } +} +pub mod async_ { + pub mod bench { + pub use super::super::bench::async_::*; + pub use super::super::bench::*; + } +} diff --git a/benches/generated/src/queries/bench.rs b/benches/generated/src/queries/bench.rs new file mode 100644 index 00000000..9a421d6e --- /dev/null +++ b/benches/generated/src/queries/bench.rs @@ -0,0 +1,896 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct InsertUserParams { + pub name: T1, + pub hair_color: Option, +} +#[derive(Debug, Clone, PartialEq)] +pub struct User { + pub id: i32, + pub name: String, + pub hair_color: Option, +} +pub struct UserBorrowed<'a> { + pub id: i32, + pub name: &'a str, + pub hair_color: Option<&'a str>, +} +impl<'a> From> for User { + fn from( + UserBorrowed { + id, + name, + hair_color, + }: UserBorrowed<'a>, + ) -> Self { + Self { + id, + name: name.into(), + hair_color: hair_color.map(|v| v.into()), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub struct Post { + pub id: i32, + pub user_id: i32, + pub title: String, + pub body: Option, +} +pub struct PostBorrowed<'a> { + pub id: i32, + pub user_id: i32, + pub title: &'a str, + pub body: Option<&'a str>, +} +impl<'a> From> for Post { + fn from( + PostBorrowed { + id, + user_id, + title, + body, + }: PostBorrowed<'a>, + ) -> Self { + Self { + id, + user_id, + title: title.into(), + body: body.map(|v| v.into()), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub struct Comment { + pub id: i32, + pub post_id: i32, + pub text: String, +} +pub struct CommentBorrowed<'a> { + pub id: i32, + pub post_id: i32, + pub text: &'a str, +} +impl<'a> From> for Comment { + fn from(CommentBorrowed { id, post_id, text }: CommentBorrowed<'a>) -> Self { + Self { + id, + post_id, + text: text.into(), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub struct SelectComplex { + pub myuser_id: i32, + pub name: String, + pub hair_color: Option, + pub post_id: Option, + pub user_id: Option, + pub title: Option, + pub body: Option, +} +pub struct SelectComplexBorrowed<'a> { + pub myuser_id: i32, + pub name: &'a str, + pub hair_color: Option<&'a str>, + pub post_id: Option, + pub user_id: Option, + pub title: Option<&'a str>, + pub body: Option<&'a str>, +} +impl<'a> From> for SelectComplex { + fn from( + SelectComplexBorrowed { + myuser_id, + name, + hair_color, + post_id, + user_id, + title, + body, + }: SelectComplexBorrowed<'a>, + ) -> Self { + Self { + myuser_id, + name: name.into(), + hair_color: hair_color.map(|v| v.into()), + post_id, + user_id, + title: title.map(|v| v.into()), + body: body.map(|v| v.into()), + } + } +} +pub mod sync { + use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + pub struct UserQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::UserBorrowed, + mapper: fn(super::UserBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> UserQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::UserBorrowed) -> R) -> UserQuery<'a, C, R, N> { + UserQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct PostQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::PostBorrowed, + mapper: fn(super::PostBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> PostQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::PostBorrowed) -> R) -> PostQuery<'a, C, R, N> { + PostQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct CommentQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::CommentBorrowed, + mapper: fn(super::CommentBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> CommentQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::CommentBorrowed) -> R) -> CommentQuery<'a, C, R, N> { + CommentQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct SelectComplexQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::SelectComplexBorrowed, + mapper: fn(super::SelectComplexBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SelectComplexQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::SelectComplexBorrowed) -> R, + ) -> SelectComplexQuery<'a, C, R, N> { + SelectComplexQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub fn users() -> UsersStmt { + UsersStmt(crate::client::sync::Stmt::new("SELECT * FROM users")) + } + pub struct UsersStmt(crate::client::sync::Stmt); + impl UsersStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> UserQuery<'a, C, super::User, 0> { + UserQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::UserBorrowed { + id: row.get(0), + name: row.get(1), + hair_color: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } + pub fn insert_user() -> InsertUserStmt { + InsertUserStmt(crate::client::sync::Stmt::new( + "INSERT INTO users (name, hair_color) VALUES ($1, $2)", + )) + } + pub struct InsertUserStmt(crate::client::sync::Stmt); + impl InsertUserStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql>( + &'a mut self, + client: &'a mut C, + name: &'a T1, + hair_color: &'a Option, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[name, hair_color]) + } + } + impl<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql> + crate::client::sync::Params< + 'a, + super::InsertUserParams, + Result, + C, + > for InsertUserStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::InsertUserParams, + ) -> Result { + self.bind(client, ¶ms.name, ¶ms.hair_color) + } + } + pub fn posts() -> PostsStmt { + PostsStmt(crate::client::sync::Stmt::new("SELECT * FROM posts")) + } + pub struct PostsStmt(crate::client::sync::Stmt); + impl PostsStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> PostQuery<'a, C, super::Post, 0> { + PostQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::PostBorrowed { + id: row.get(0), + user_id: row.get(1), + title: row.get(2), + body: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn post_by_user_ids() -> PostByUserIdsStmt { + PostByUserIdsStmt(crate::client::sync::Stmt::new( + "SELECT * FROM posts WHERE user_id = ANY($1)", + )) + } + pub struct PostByUserIdsStmt(crate::client::sync::Stmt); + impl PostByUserIdsStmt { + pub fn bind<'a, C: GenericClient, T1: crate::ArraySql>( + &'a mut self, + client: &'a mut C, + ids: &'a T1, + ) -> PostQuery<'a, C, super::Post, 1> { + PostQuery { + client, + params: [ids], + stmt: &mut self.0, + extractor: |row| super::PostBorrowed { + id: row.get(0), + user_id: row.get(1), + title: row.get(2), + body: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn comments() -> CommentsStmt { + CommentsStmt(crate::client::sync::Stmt::new("SELECT * FROM comments")) + } + pub struct CommentsStmt(crate::client::sync::Stmt); + impl CommentsStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> CommentQuery<'a, C, super::Comment, 0> { + CommentQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::CommentBorrowed { + id: row.get(0), + post_id: row.get(1), + text: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } + pub fn comments_by_post_id() -> CommentsByPostIdStmt { + CommentsByPostIdStmt(crate::client::sync::Stmt::new( + "SELECT * FROM comments WHERE post_id = ANY($1)", + )) + } + pub struct CommentsByPostIdStmt(crate::client::sync::Stmt); + impl CommentsByPostIdStmt { + pub fn bind<'a, C: GenericClient, T1: crate::ArraySql>( + &'a mut self, + client: &'a mut C, + ids: &'a T1, + ) -> CommentQuery<'a, C, super::Comment, 1> { + CommentQuery { + client, + params: [ids], + stmt: &mut self.0, + extractor: |row| super::CommentBorrowed { + id: row.get(0), + post_id: row.get(1), + text: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } + pub fn select_complex() -> SelectComplexStmt { + SelectComplexStmt(crate::client::sync::Stmt::new("SELECT u.id as myuser_id, u.name, u.hair_color, p.id as post_id, p.user_id, p.title, p.body FROM users as u LEFT JOIN posts as p on u.id = p.user_id")) + } + pub struct SelectComplexStmt(crate::client::sync::Stmt); + impl SelectComplexStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> SelectComplexQuery<'a, C, super::SelectComplex, 0> { + SelectComplexQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::SelectComplexBorrowed { + myuser_id: row.get(0), + name: row.get(1), + hair_color: row.get(2), + post_id: row.get(3), + user_id: row.get(4), + title: row.get(5), + body: row.get(6), + }, + mapper: |it| ::from(it), + } + } + } +} +pub mod async_ { + use crate::client::async_::GenericClient; + use futures::{self, StreamExt, TryStreamExt}; + pub struct UserQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::UserBorrowed, + mapper: fn(super::UserBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> UserQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::UserBorrowed) -> R) -> UserQuery<'a, C, R, N> { + UserQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct PostQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::PostBorrowed, + mapper: fn(super::PostBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> PostQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::PostBorrowed) -> R) -> PostQuery<'a, C, R, N> { + PostQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct CommentQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::CommentBorrowed, + mapper: fn(super::CommentBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> CommentQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::CommentBorrowed) -> R) -> CommentQuery<'a, C, R, N> { + CommentQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct SelectComplexQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::SelectComplexBorrowed, + mapper: fn(super::SelectComplexBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SelectComplexQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::SelectComplexBorrowed) -> R, + ) -> SelectComplexQuery<'a, C, R, N> { + SelectComplexQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub fn users() -> UsersStmt { + UsersStmt(crate::client::async_::Stmt::new("SELECT * FROM users")) + } + pub struct UsersStmt(crate::client::async_::Stmt); + impl UsersStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> UserQuery<'a, C, super::User, 0> { + UserQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::UserBorrowed { + id: row.get(0), + name: row.get(1), + hair_color: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } + pub fn insert_user() -> InsertUserStmt { + InsertUserStmt(crate::client::async_::Stmt::new( + "INSERT INTO users (name, hair_color) VALUES ($1, $2)", + )) + } + pub struct InsertUserStmt(crate::client::async_::Stmt); + impl InsertUserStmt { + pub async fn bind<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql>( + &'a mut self, + client: &'a C, + name: &'a T1, + hair_color: &'a Option, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[name, hair_color]).await + } + } + impl<'a, C: GenericClient + Send + Sync, T1: crate::StringSql, T2: crate::StringSql> + crate::client::async_::Params< + 'a, + super::InsertUserParams, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for InsertUserStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::InsertUserParams, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.name, ¶ms.hair_color)) + } + } + pub fn posts() -> PostsStmt { + PostsStmt(crate::client::async_::Stmt::new("SELECT * FROM posts")) + } + pub struct PostsStmt(crate::client::async_::Stmt); + impl PostsStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> PostQuery<'a, C, super::Post, 0> { + PostQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::PostBorrowed { + id: row.get(0), + user_id: row.get(1), + title: row.get(2), + body: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn post_by_user_ids() -> PostByUserIdsStmt { + PostByUserIdsStmt(crate::client::async_::Stmt::new( + "SELECT * FROM posts WHERE user_id = ANY($1)", + )) + } + pub struct PostByUserIdsStmt(crate::client::async_::Stmt); + impl PostByUserIdsStmt { + pub fn bind<'a, C: GenericClient, T1: crate::ArraySql>( + &'a mut self, + client: &'a C, + ids: &'a T1, + ) -> PostQuery<'a, C, super::Post, 1> { + PostQuery { + client, + params: [ids], + stmt: &mut self.0, + extractor: |row| super::PostBorrowed { + id: row.get(0), + user_id: row.get(1), + title: row.get(2), + body: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn comments() -> CommentsStmt { + CommentsStmt(crate::client::async_::Stmt::new("SELECT * FROM comments")) + } + pub struct CommentsStmt(crate::client::async_::Stmt); + impl CommentsStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> CommentQuery<'a, C, super::Comment, 0> { + CommentQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::CommentBorrowed { + id: row.get(0), + post_id: row.get(1), + text: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } + pub fn comments_by_post_id() -> CommentsByPostIdStmt { + CommentsByPostIdStmt(crate::client::async_::Stmt::new( + "SELECT * FROM comments WHERE post_id = ANY($1)", + )) + } + pub struct CommentsByPostIdStmt(crate::client::async_::Stmt); + impl CommentsByPostIdStmt { + pub fn bind<'a, C: GenericClient, T1: crate::ArraySql>( + &'a mut self, + client: &'a C, + ids: &'a T1, + ) -> CommentQuery<'a, C, super::Comment, 1> { + CommentQuery { + client, + params: [ids], + stmt: &mut self.0, + extractor: |row| super::CommentBorrowed { + id: row.get(0), + post_id: row.get(1), + text: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } + pub fn select_complex() -> SelectComplexStmt { + SelectComplexStmt(crate::client::async_::Stmt::new("SELECT u.id as myuser_id, u.name, u.hair_color, p.id as post_id, p.user_id, p.title, p.body FROM users as u LEFT JOIN posts as p on u.id = p.user_id")) + } + pub struct SelectComplexStmt(crate::client::async_::Stmt); + impl SelectComplexStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> SelectComplexQuery<'a, C, super::SelectComplex, 0> { + SelectComplexQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::SelectComplexBorrowed { + myuser_id: row.get(0), + name: row.get(1), + hair_color: row.get(2), + post_id: row.get(3), + user_id: row.get(4), + title: row.get(5), + body: row.get(6), + }, + mapper: |it| ::from(it), + } + } + } +} diff --git a/benches/generated/src/type_traits.rs b/benches/generated/src/type_traits.rs new file mode 100644 index 00000000..68727072 --- /dev/null +++ b/benches/generated/src/type_traits.rs @@ -0,0 +1,121 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::domain::escape_domain_to_sql; +use postgres_protocol::types::{self, ArrayDimension}; +use postgres_types::{private::BytesMut, to_sql_checked, IsNull, Kind, ToSql, Type}; +use std::borrow::Cow; +pub trait StringSql: std::fmt::Debug + ToSql + Sync {} +impl StringSql for &T {} +impl StringSql for String {} +impl StringSql for &str {} +impl StringSql for Cow<'_, str> {} +impl StringSql for Box {} +pub trait BytesSql: std::fmt::Debug + ToSql + Send + Sync {} +impl BytesSql for &T {} +impl BytesSql for Vec {} +impl BytesSql for &[u8] {} +pub trait ArraySql: std::fmt::Debug + ToSql + Send + Sync { + type Item; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result>; +} +impl> ArraySql for &A { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + A::escape_domain_to_sql(self, ty, w) + } +} +impl ArraySql for Vec { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } +} +impl ArraySql for &[T] { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } +} +impl< + T: std::fmt::Debug + ToSql + Send + Sync, + I: Iterator + ExactSizeIterator, + F: Fn() -> I + Send + Sync, + > ArraySql for IterSql +{ + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, (self.0)()) + } +} +pub struct IterSql + ExactSizeIterator, F: Fn() -> I + Sync>(pub F); +impl + ExactSizeIterator, F: Fn() -> I + Sync> std::fmt::Debug + for IterSql +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayFn").finish() + } +} +impl + ExactSizeIterator, F: Fn() -> I + Sync> ToSql + for IterSql +{ + fn to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => member, + _ => panic!("expected array type"), + }; + let iter = (self.0)(); + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + types::array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match e.to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(member), + _ => false, + } + } + to_sql_checked!(); +} +fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } +} diff --git a/benches/generated/src/types.rs b/benches/generated/src/types.rs new file mode 100644 index 00000000..f5372d93 --- /dev/null +++ b/benches/generated/src/types.rs @@ -0,0 +1 @@ +// This file was generated with `cornucopia`. Do not modify. diff --git a/crates/client_core/src/utils.rs b/benches/generated/src/utils.rs similarity index 83% rename from crates/client_core/src/utils.rs rename to benches/generated/src/utils.rs index d046783d..fca59fa2 100644 --- a/crates/client_core/src/utils.rs +++ b/benches/generated/src/utils.rs @@ -1,12 +1,12 @@ -use postgres_types::{Kind, ToSql, Type}; +// This file was generated with `cornucopia`. Do not modify. +use postgres_types::{Kind, ToSql, Type}; pub fn escape_domain(ty: &Type) -> &Type { match ty.kind() { Kind::Domain(ty) => ty, _ => ty, } } - pub fn slice_iter<'a>( s: &'a [&'a (dyn ToSql + Sync)], ) -> impl ExactSizeIterator + 'a { diff --git a/benches/execution/cornucopia_benches/queries/bench.sql b/benches/queries/bench.sql similarity index 100% rename from benches/execution/cornucopia_benches/queries/bench.sql rename to benches/queries/bench.sql diff --git a/benches/execution/cornucopia_benches/schema.sql b/benches/schema.sql similarity index 100% rename from benches/execution/cornucopia_benches/schema.sql rename to benches/schema.sql diff --git a/crates/client_async/Cargo.toml b/crates/client_async/Cargo.toml deleted file mode 100644 index 38ee5aff..00000000 --- a/crates/client_async/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "cornucopia_async" -version = "0.4.0" -edition = "2021" -license = "MIT/Apache-2.0" -description = "Asynchronous client library for Cornucopia users." -homepage = "https://cornucopia-rs.netlify.app/" -repository = "https://github.com/cornucopia-rs/cornucopia" -readme = "README.md" -categories = ["database"] -keywords = ["postgresql", "query", "generator", "sql", "tokio-postgres"] - -[features] -default = ["deadpool"] -deadpool = ["dep:deadpool-postgres"] -with-serde_json-1 = ["cornucopia_client_core/with-serde_json-1"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -# Path dependencies -cornucopia_client_core = { path = "../client_core", version = "0.4.0" } - -# async -async-trait = "0.1.63" - -# rust-postgres interaction -tokio-postgres = "0.7.7" - -# connection pooling -deadpool-postgres = { version = "0.11.0", optional = true } diff --git a/crates/client_async/README.md b/crates/client_async/README.md deleted file mode 100644 index 2a616d51..00000000 --- a/crates/client_async/README.md +++ /dev/null @@ -1,47 +0,0 @@ -
-

Cornucopia

-
- - Generate type-checked Rust from your SQL - -
- -
- -
- - - Crates.io version - - - - - book - - - - - docs.rs - - - - - License - - - - - Chat - -
- ---- - -**Note:** This crate is the *asynchronous* client. You can find the *synchronous* client [here](https://crates.io/crates/cornucopia_sync). - -This is a client crate for [Cornucopia](https://crates.io/crates/cornucopia). This dependency provides -1. Internals required by the generated code. -2. Public items that you may find useful when working with Cornucopia (you can find more info about these in the [docs](https://docs.rs/cornucopia_async/latest/cornucopia_async/)). - -***You need to depend on this crate for Cornucopia's generated code to work properly.*** \ No newline at end of file diff --git a/crates/client_async/src/lib.rs b/crates/client_async/src/lib.rs deleted file mode 100644 index ddded593..00000000 --- a/crates/client_async/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[doc(hidden)] -pub mod private; - -pub use crate::generic_client::GenericClient; -pub use cornucopia_client_core::{ArrayIterator, ArraySql, BytesSql, IterSql, StringSql}; - -#[cfg(feature = "with-serde_json-1")] -pub use cornucopia_client_core::JsonSql; - -#[cfg(feature = "deadpool")] -mod deadpool; -mod generic_client; - -/// This trait allows you to bind parameters to a query using a single -/// struct, rather than passing each bind parameter as a function parameter. -pub trait Params<'a, P, O, C> { - fn params(&'a mut self, client: &'a C, params: &'a P) -> O; -} diff --git a/crates/client_core/Cargo.toml b/crates/client_core/Cargo.toml deleted file mode 100644 index 37bc00a4..00000000 --- a/crates/client_core/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "cornucopia_client_core" -version = "0.4.0" -edition = "2021" -license = "MIT/Apache-2.0" -description = "Private abstractions for Cornucopia clients." -homepage = "https://cornucopia-rs.netlify.app/" -repository = "https://github.com/cornucopia-rs/cornucopia" -readme = "README.md" -categories = ["database"] -keywords = ["postgresql", "query", "generator", "sql", "tokio-postgres"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[features] -with-serde_json-1 = ["postgres-types/with-serde_json-1", "serde", "serde_json"] - -[dependencies] -# Postgres interaction -postgres-protocol = "0.6.4" -postgres-types = "0.2.4" -## Iterator utils required for working with `postgres_protocol::types::ArrayValues` -fallible-iterator = "0.2.0" - -# json -## This crate implements the "ergonomic paramters" for -## `serde_json::Value` and `serde_json::raw::RawValue`. -serde_json = { version = "1.0.91", optional = true } -## Used for `postgres_types::Json` `Serialize` trait bounds -serde = { version = "1.0.152", optional = true } diff --git a/crates/client_core/README.md b/crates/client_core/README.md deleted file mode 100644 index f5d5262b..00000000 --- a/crates/client_core/README.md +++ /dev/null @@ -1 +0,0 @@ -Private abstractions for Cornucopia clients. You should not depend on this whatsoever. The clients are available [here](https://crates.io/crates/cornucopia_sync) (sync version) and [here](https://crates.io/crates/cornucopia_async) (async version). \ No newline at end of file diff --git a/crates/client_core/src/lib.rs b/crates/client_core/src/lib.rs deleted file mode 100644 index 974ec690..00000000 --- a/crates/client_core/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -mod array_iterator; -mod domain; -mod type_traits; -mod utils; - -pub use array_iterator::ArrayIterator; -pub use domain::{Domain, DomainArray}; -pub use type_traits::{ArraySql, BytesSql, IterSql, StringSql}; - -#[cfg(feature = "with-serde_json-1")] -pub use type_traits::JsonSql; - -pub use utils::slice_iter; diff --git a/crates/client_sync/Cargo.toml b/crates/client_sync/Cargo.toml deleted file mode 100644 index 8662bab6..00000000 --- a/crates/client_sync/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "cornucopia_sync" -version = "0.4.0" -edition = "2021" -license = "MIT/Apache-2.0" -description = "Synchronous client library for Cornucopia users." -homepage = "https://cornucopia-rs.netlify.app/" -repository = "https://github.com/cornucopia-rs/cornucopia" -readme = "README.md" -categories = ["database"] -keywords = ["postgresql", "query", "generator", "sql", "tokio-postgres"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[features] -with-serde_json-1 = ["cornucopia_client_core/with-serde_json-1"] - -[dependencies] -# Path dependencies -cornucopia_client_core = { path = "../client_core", version = "0.4.0" } - -# postgres interaction -postgres = "0.19.4" diff --git a/crates/client_sync/README.md b/crates/client_sync/README.md deleted file mode 100644 index 49c97151..00000000 --- a/crates/client_sync/README.md +++ /dev/null @@ -1,47 +0,0 @@ -
-

Cornucopia

-
- - Generate type-checked Rust from your SQL - -
- -
- -
- - - Crates.io version - - - - - book - - - - - docs.rs - - - - - License - - - - - Chat - -
- ---- - -**Note:** This crate is the *synchronous* client. You can find the *asynchronous* client [here](https://crates.io/crates/cornucopia_async). - -This is a client crate for [Cornucopia](https://crates.io/crates/cornucopia). This dependency provides -1. Internals required by the generated code. -2. Public items that you may find useful when working with Cornucopia (you can find more info about these in the [docs](https://docs.rs/cornucopia_sync/latest/cornucopia_sync/)). - -***You need to depend on this crate for Cornucopia's generated code to work properly.*** \ No newline at end of file diff --git a/crates/client_sync/src/lib.rs b/crates/client_sync/src/lib.rs deleted file mode 100644 index 84c4c7f5..00000000 --- a/crates/client_sync/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[doc(hidden)] -pub mod private; - -pub use cornucopia_client_core::{ArrayIterator, ArraySql, BytesSql, IterSql, StringSql}; - -#[cfg(feature = "with-serde_json-1")] -pub use cornucopia_client_core::JsonSql; - -/// This trait allows you to bind parameters to a query using a single -/// struct, rather than passing each bind parameter as a function parameter. -pub trait Params<'a, P, O, C> { - fn params(&'a mut self, client: &'a mut C, params: &'a P) -> O; -} diff --git a/crates/codegen_template/src/lib.rs b/crates/codegen_template/src/lib.rs index 6e1e940f..e0137d86 100644 --- a/crates/codegen_template/src/lib.rs +++ b/crates/codegen_template/src/lib.rs @@ -149,7 +149,11 @@ fn gen_recursive(scan: &mut Scanner, s: &mut String, out: &str) { match pattern { Kind::Display(ident) => gen_disp(s, out, ident), Kind::Call(ident) => { - s.push_str("let w = &mut*w;"); + s.push_str("let "); + s.push_str(out); + s.push_str(" = &mut *"); + s.push_str(out); + s.push(';'); s.push_str(ident); s.push_str("(&mut *"); s.push_str(out); @@ -224,8 +228,8 @@ pub fn code(pattern: TokenStream) -> TokenStream { if let Some(out) = out { gen_recursive(&mut scan, &mut s, out); } else { - s.push_str("let mut out = String::new();\n"); - gen_recursive(&mut scan, &mut s, "out"); + s.push_str("let mut out = String::new();\nlet w = &mut out;"); + gen_recursive(&mut scan, &mut s, "w"); s.push_str("out") } s.push('}'); diff --git a/crates/cornucopia/Cargo.toml b/crates/cornucopia/Cargo.toml index 04773127..1ca2dd81 100644 --- a/crates/cornucopia/Cargo.toml +++ b/crates/cornucopia/Cargo.toml @@ -11,25 +11,29 @@ categories = ["database"] keywords = ["postgresql", "query", "generator", "sql", "tokio-postgres"] [dependencies] -# Path dependencies +# Ergonomic codegen tools codegen_template = { path = "../codegen_template", version = "0.1.0" } +indoc = "2.0.1" # Postgres interaction -postgres = "0.19.4" -postgres-types = "0.2.4" +postgres = "0.19.5" +postgres-types = "0.2.5" # Error handling and reporting -thiserror = "1.0.38" -miette = { version = "5.5.0", features = ["fancy"] } +thiserror = "1.0.40" +miette = { version = "7.2.0", features = ["fancy"] } # Parser -chumsky = "0.9.0" +chumsky = "0.9.2" # CLI handling -clap = { version = "4.1.1", features = ["derive"] } +clap = { version = "4.3.5", features = ["derive"] } # Word case -heck = "0.4.0" +heck = "0.5.0" # Order-preserving map to work around borrowing issues indexmap = "2.0.2" + +# Generate temporary files +tempfile = "3.6.0" diff --git a/crates/cornucopia/src/cli.rs b/crates/cornucopia/src/cli.rs index 73692260..a5587a9b 100644 --- a/crates/cornucopia/src/cli.rs +++ b/crates/cornucopia/src/cli.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use clap::{Parser, Subcommand}; -use crate::{conn, container, error::Error, generate_live, generate_managed, CodegenSettings}; +use crate::{conn, container, error::Error, gen_live, gen_managed, CodegenSettings}; /// Command line interface to interact with Cornucopia SQL. #[derive(Parser, Debug)] @@ -15,7 +15,7 @@ struct Args { #[clap(short, long, default_value = "queries/")] queries_path: PathBuf, /// Destination folder for generated modules - #[clap(short, long, default_value = "src/cornucopia.rs")] + #[clap(short, long, default_value = "cornucopia")] destination: PathBuf, #[clap(subcommand)] action: Action, @@ -65,17 +65,12 @@ pub fn run() -> Result<(), Error> { match action { Action::Live { url } => { let mut client = conn::from_url(&url)?; - generate_live(&mut client, &queries_path, Some(&destination), settings)?; + gen_live(&mut client, &queries_path, &destination, settings)?; } Action::Schema { schema_files } => { // Run the generate command. If the command is unsuccessful, cleanup Cornucopia's container - if let Err(e) = generate_managed( - queries_path, - &schema_files, - Some(destination), - podman, - settings, - ) { + if let Err(e) = gen_managed(queries_path, &schema_files, destination, podman, settings) + { container::cleanup(podman).ok(); return Err(e); } diff --git a/crates/cornucopia/src/codegen.rs b/crates/cornucopia/src/codegen.rs index d4e2165f..e6d63895 100644 --- a/crates/cornucopia/src/codegen.rs +++ b/crates/cornucopia/src/codegen.rs @@ -1,20 +1,33 @@ use core::str; -use std::fmt::{Display, Write}; - -use codegen_template::code; -use indexmap::IndexMap; use crate::{ - prepare_queries::{ - Ident, Preparation, PreparedContent, PreparedField, PreparedItem, PreparedModule, - PreparedQuery, PreparedType, - }, + prepare_queries::{Preparation, PreparedField}, CodegenSettings, }; +mod cargo; +mod client; +mod queries; +mod types; +mod vfs; + +pub use cargo::DependencyAnalysis; + +use self::{types::gen_type_modules, vfs::Vfs}; + +const WARNING: &str = "// This file was generated with `cornucopia`. Do not modify.\n\n"; + +/// Module when codegen is happening +pub enum ModCtx { + Types, // crate::types + SchemaTypes, // crate::types::schema + Queries, // crate::queries + CLientQueries, // crate::queries::sync +} + pub struct GenCtx { - // Current module depth - pub depth: u8, + // Generated module position in the hierarchy + pub hierarchy: ModCtx, // Should use async client and generate async code pub is_async: bool, // Should serializable struct @@ -22,24 +35,39 @@ pub struct GenCtx { } impl GenCtx { - pub fn new(depth: u8, is_async: bool, gen_derive: bool) -> Self { + pub fn new(hierarchy: ModCtx, is_async: bool, gen_derive: bool) -> Self { Self { - depth, + hierarchy, is_async, gen_derive, } } - pub fn path(&self, depth: u8, name: impl Display) -> String { - let depth = std::iter::repeat("super::").take(depth as usize); - code!($($depth)$name) + pub fn custom_ty_path(&self, schema: &str, struct_name: &str) -> String { + if schema == "public" { + match self.hierarchy { + ModCtx::Types => struct_name.to_string(), + ModCtx::SchemaTypes => format!("super::{struct_name}"), + ModCtx::Queries | ModCtx::CLientQueries => { + format!("crate::types::{struct_name}") + } + } + } else { + match self.hierarchy { + ModCtx::Types => format!("{schema}::{struct_name}"), + ModCtx::SchemaTypes => format!("super::{schema}::{struct_name}"), + ModCtx::Queries | ModCtx::CLientQueries => { + format!("crate::types::{schema}::{struct_name}") + } + } + } } pub fn client_name(&self) -> &'static str { if self.is_async { - "cornucopia_async" + "crate::client::async_" } else { - "cornucopia_sync" + "crate::client::sync" } } } @@ -99,742 +127,21 @@ impl PreparedField { } } -fn enum_sql(w: &mut impl Write, name: &str, enum_name: &str, variants: &[Ident]) { - let enum_names = std::iter::repeat(enum_name); - let db_variants_ident = variants.iter().map(|v| &v.db); - let rs_variants_ident = variants.iter().map(|v| &v.rs); - - let nb_variants = variants.len(); - code!(w => - impl<'a> postgres_types::ToSql for $enum_name { - fn to_sql( - &self, - ty: &postgres_types::Type, - buf: &mut postgres_types::private::BytesMut, - ) -> Result,> { - let s = match *self { - $($enum_names::$rs_variants_ident => "$db_variants_ident",) - }; - buf.extend_from_slice(s.as_bytes()); - std::result::Result::Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "$name" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != $nb_variants { - return false; - } - variants.iter().all(|v| match &**v { - $("$db_variants_ident" => true,) - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> { - postgres_types::__to_sql_checked(self, ty, out) - } - } - impl<'a> postgres_types::FromSql<'a> for $enum_name { - fn from_sql( - ty: &postgres_types::Type, - buf: &'a [u8], - ) -> Result<$enum_name, Box,> { - match std::str::from_utf8(buf)? { - $("$db_variants_ident" => Ok($enum_names::$rs_variants_ident),) - s => Result::Err(Into::into(format!( - "invalid variant `{}`", - s - ))), - } - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "$name" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != $nb_variants { - return false; - } - variants.iter().all(|v| match &**v { - $("$db_variants_ident" => true,) - _ => false, - }) - } - _ => false, - } - } - } - ); -} - -fn struct_tosql( - w: &mut impl Write, - struct_name: &str, - fields: &[PreparedField], - name: &str, - is_borrow: bool, - is_params: bool, - ctx: &GenCtx, -) { - let (post, lifetime) = if is_borrow { - if is_params { - ("Borrowed", "<'a>") - } else { - ("Params", "<'a>") - } - } else { - ("", "") - }; - let db_fields_ident = fields.iter().map(|p| &p.ident.db); - let rs_fields_ident = fields.iter().map(|p| &p.ident.rs); - let write_ty = fields.iter().map(|p| p.ty.sql_wrapped(&p.ident.rs, ctx)); - let accept_ty = fields.iter().map(|p| p.ty.accept_to_sql(ctx)); - let nb_fields = fields.len(); - - code!(w => - impl<'a> postgres_types::ToSql for $struct_name$post $lifetime { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result,> { - let $struct_name$post { - $($rs_fields_ident,) - } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - $("$db_fields_ident" => postgres_types::ToSql::to_sql($write_ty,field.type_(), out),) - _ => unreachable!() - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "$name" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != $nb_fields { - return false; - } - fields.iter().all(|f| match f.name() { - $("$db_fields_ident" => <$accept_ty as postgres_types::ToSql>::accepts(f.type_()),) - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> { - postgres_types::__to_sql_checked(self, ty, out) - } - } - ); -} - -fn composite_fromsql( - w: &mut impl Write, - struct_name: &str, - fields: &[PreparedField], - name: &str, - schema: &str, -) { - let field_names = fields.iter().map(|p| &p.ident.rs); - let read_idx = 0..fields.len(); - code!(w => - impl<'a> postgres_types::FromSql<'a> for ${struct_name}Borrowed<'a> { - fn from_sql(ty: &postgres_types::Type, out: &'a [u8]) -> - Result<${struct_name}Borrowed<'a>, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err( - std::convert::Into::into(format!("invalid field count: {} vs {}", num_fields, fields.len()))); - } - $( - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let $field_names = postgres_types::private::read_value(fields[$read_idx].type_(), &mut out)?; - ) - Ok(${struct_name}Borrowed { $($field_names,) }) - } - - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "$name" && ty.schema() == "$schema" - } - } - ); -} - -fn gen_params_struct(w: &mut impl Write, params: &PreparedItem, ctx: &GenCtx) { - let PreparedItem { - name, - fields, - is_copy, - is_named, - is_ref, - .. - } = params; - if *is_named { - let traits = &mut Vec::new(); - - let copy = if *is_copy { "Clone,Copy," } else { "" }; - let lifetime = if *is_ref { "'a," } else { "" }; - let fields_ty = fields - .iter() - .map(|p| p.param_ergo_ty(traits, ctx)) - .collect::>(); - let fields_name = fields.iter().map(|p| &p.ident.rs); - let traits_idx = (1..=traits.len()).map(idx_char); - code!(w => - #[derive($copy Debug)] - pub struct $name<$lifetime $($traits_idx: $traits,)> { - $(pub $fields_name: $fields_ty,) - } - ); - } -} - -fn gen_row_structs(w: &mut impl Write, row: &PreparedItem, ctx: &GenCtx) { - let PreparedItem { - name, - fields, - is_copy, - is_named, - .. - } = row; - if *is_named { - // Generate row struct - let fields_name = fields.iter().map(|p| &p.ident.rs); - let fields_ty = fields.iter().map(|p| p.own_struct(ctx)); - let copy = if *is_copy { "Copy" } else { "" }; - let ser_str = if ctx.gen_derive { - "serde::Serialize," - } else { - "" - }; - code!(w => - #[derive($ser_str Debug, Clone, PartialEq,$copy)] - pub struct $name { - $(pub $fields_name : $fields_ty,) - } - ); - - if !is_copy { - let fields_name = fields.iter().map(|p| &p.ident.rs); - let fields_ty = fields.iter().map(|p| p.brw_ty(true, ctx)); - let from_own_assign = fields.iter().map(|f| f.owning_assign()); - code!(w => - pub struct ${name}Borrowed<'a> { - $(pub $fields_name : $fields_ty,) - } - impl<'a> From<${name}Borrowed<'a>> for $name { - fn from(${name}Borrowed { $($fields_name,) }: ${name}Borrowed<'a>) -> Self { - Self { - $($from_own_assign,) - } - } - } - ); - }; - } -} - -fn gen_row_query(w: &mut impl Write, row: &PreparedItem, ctx: &GenCtx) { - let PreparedItem { - name, - fields, - is_copy, - is_named, - .. - } = row; - // Generate query struct - let borrowed_str = if *is_copy { "" } else { "Borrowed" }; - let (client_mut, fn_async, fn_await, backend, collect, raw_type, raw_pre, raw_post, client) = - if ctx.is_async { - ( - "", - "async", - ".await", - "tokio_postgres", - "try_collect().await", - "futures::Stream", - "", - ".into_stream()", - "cornucopia_async", - ) - } else { - ( - "mut", - "", - "", - "postgres", - "collect()", - "Iterator", - ".iterator()", - "", - "cornucopia_sync", - ) - }; - - let row_struct = if *is_named { - format!("{}{borrowed_str}", row.path(ctx)) - } else { - fields[0].brw_ty(false, ctx) - }; - - code!(w => - pub struct ${name}Query<'a, C: GenericClient, T, const N: usize> { - client: &'a $client_mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut $client::private::Stmt, - extractor: fn(&$backend::Row) -> $row_struct, - mapper: fn($row_struct) -> T, - } - impl<'a, C, T:'a, const N: usize> ${name}Query<'a, C, T, N> where C: GenericClient { - pub fn map(self, mapper: fn($row_struct) -> R) -> ${name}Query<'a,C,R,N> { - ${name}Query { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - - pub $fn_async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)$fn_await?; - let row = self.client.query_one(stmt, &self.params)$fn_await?; - Ok((self.mapper)((self.extractor)(&row))) - } - - pub $fn_async fn all(self) -> Result, $backend::Error> { - self.iter()$fn_await?.$collect - } - - pub $fn_async fn opt(self) -> Result, $backend::Error> { - let stmt = self.stmt.prepare(self.client)$fn_await?; - Ok(self - .client - .query_opt(stmt, &self.params) - $fn_await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - - pub $fn_async fn iter( - self, - ) -> Result> + 'a, $backend::Error> { - let stmt = self.stmt.prepare(self.client)$fn_await?; - let it = self - .client - .query_raw(stmt, $client::private::slice_iter(&self.params)) - $fn_await? - $raw_pre - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - $raw_post; - Ok(it) - } - }); -} - pub fn idx_char(idx: usize) -> String { format!("T{idx}") } -fn gen_query_fn(w: &mut W, module: &PreparedModule, query: &PreparedQuery, ctx: &GenCtx) { - let PreparedQuery { - ident, - row, - sql, - param, - } = query; - - let (client_mut, fn_async, fn_await, backend, client) = if ctx.is_async { - ("", "async", ".await", "tokio_postgres", "cornucopia_async") - } else { - ("mut", "", "", "postgres", "cornucopia_sync") - }; - - let struct_name = ident.type_ident(); - let (param, param_field, order) = match param { - Some((idx, order)) => { - let it = module.params.get_index(*idx).unwrap().1; - (Some(it), it.fields.as_slice(), order.as_slice()) - } - None => (None, [].as_slice(), [].as_slice()), - }; - let traits = &mut Vec::new(); - let params_ty: Vec<_> = order - .iter() - .map(|idx| param_field[*idx].param_ergo_ty(traits, ctx)) - .collect(); - let params_name = order.iter().map(|idx| ¶m_field[*idx].ident.rs); - let traits_idx = (1..=traits.len()).map(idx_char); - let lazy_impl = |w: &mut W| { - if let Some((idx, index)) = row { - let item = module.rows.get_index(*idx).unwrap().1; - let PreparedItem { - name: row_name, - fields, - is_copy, - is_named, - .. - } = &item; - // Query fn - let nb_params = param_field.len(); - - // TODO find a way to clean this mess - #[allow(clippy::type_complexity)] - let (row_struct_name, extractor, mapper): (_, Box, _) = if *is_named { - let path = item.path(ctx); - ( - path.clone(), - Box::new(|w: _| { - let path = item.path(ctx); - let post = if *is_copy { "" } else { "Borrowed" }; - let fields_name = fields.iter().map(|p| &p.ident.rs); - let fields_idx = (0..fields.len()).map(|i| index[i]); - code!(w => $path$post { - $($fields_name: row.get($fields_idx),) - }) - }), - code!(<$path>::from(it)), - ) - } else { - let field = &fields[0]; - ( - field.own_struct(ctx), - Box::new(|w: _| code!(w => row.get(0))), - field.owning_call(Some("it")), - ) - }; - code!(w => - pub fn bind<'a, C: GenericClient,$($traits_idx: $traits,)>(&'a mut self, client: &'a $client_mut C, $($params_name: &'a $params_ty,) ) -> ${row_name}Query<'a,C, $row_struct_name, $nb_params> { - ${row_name}Query { - client, - params: [$($params_name,)], - stmt: &mut self.0, - extractor: |row| { $!extractor }, - mapper: |it| { $mapper }, - } - } - ); - } else { - // Execute fn - let params_wrap = order.iter().map(|idx| { - let p = ¶m_field[*idx]; - p.ty.sql_wrapped(&p.ident.rs, ctx) - }); - code!(w => - pub $fn_async fn bind<'a, C: GenericClient,$($traits_idx: $traits,)>(&'a mut self, client: &'a $client_mut C, $($params_name: &'a $params_ty,)) -> Result { - let stmt = self.0.prepare(client)$fn_await?; - client.execute(stmt, &[ $($params_wrap,) ])$fn_await - } - ); - } - }; - // Gen statement struct - { - let sql = sql.replace('"', "\\\""); // Rust string format escaping - let name = &ident.rs; - code!(w => - pub fn $name() -> ${struct_name}Stmt { - ${struct_name}Stmt($client::private::Stmt::new("$sql")) - } - pub struct ${struct_name}Stmt($client::private::Stmt); - impl ${struct_name}Stmt { - $!lazy_impl - } - ); - } - - // Param impl - if let Some(param) = param { - if param.is_named { - let param_path = ¶m.path(ctx); - let lifetime = if param.is_copy || !param.is_ref { - "" - } else { - "'a," - }; - if let Some((idx, _)) = row { - let prepared_row = &module.rows.get_index(*idx).unwrap().1; - let query_row_struct = if prepared_row.is_named { - prepared_row.path(ctx) - } else { - prepared_row.fields[0].own_struct(ctx) - }; - let name = &module.rows.get_index(*idx).unwrap().1.name; - let nb_params = param_field.len(); - code!(w => - impl <'a, C: GenericClient,$($traits_idx: $traits,)> $client::Params<'a, $param_path<$lifetime $($traits_idx,)>, ${name}Query<'a, C, $query_row_struct, $nb_params>, C> for ${struct_name}Stmt { - fn params(&'a mut self, client: &'a $client_mut C, params: &'a $param_path<$lifetime $($traits_idx,)>) -> ${name}Query<'a, C, $query_row_struct, $nb_params> { - self.bind(client, $(¶ms.$params_name,)) - } - } - ); - } else { - let (send_sync, pre_ty, post_ty_lf, pre, post) = if ctx.is_async { - ( - "+ Send + Sync", - "std::pin::Pin + Send + 'a>>", - "Box::pin(self", - ")", - ) - } else { - ("", "Result", "", "self", "") - }; - code!(w => - impl <'a, C: GenericClient $send_sync, $($traits_idx: $traits,)> $client::Params<'a, $param_path<$lifetime $($traits_idx,)>, $pre_ty$post_ty_lf, C> for ${struct_name}Stmt { - fn params(&'a mut self, client: &'a $client_mut C, params: &'a $param_path<$lifetime $($traits_idx,)>) -> $pre_ty$post_ty_lf { - $pre.bind(client, $(¶ms.$params_name,))$post - } - } - ); - } - } - } -} - -/// Generates type definitions for custom user types. This includes domains, composites and enums. -/// If the type is not `Copy`, then a Borrowed version will be generated. -fn gen_custom_type(w: &mut impl Write, schema: &str, prepared: &PreparedType, ctx: &GenCtx) { - let PreparedType { - struct_name, - content, - is_copy, - is_params, - name, - } = prepared; - let copy = if *is_copy { "Copy," } else { "" }; - let ser_str = if ctx.gen_derive { - "serde::Serialize," - } else { - "" - }; - match content { - PreparedContent::Enum(variants) => { - let variants_ident = variants.iter().map(|v| &v.rs); - code!(w => - #[derive($ser_str Debug, Clone, Copy, PartialEq, Eq)] - #[allow(non_camel_case_types)] - pub enum $struct_name { - $($variants_ident,) - } - ); - enum_sql(w, name, struct_name, variants); - } - PreparedContent::Composite(fields) => { - let fields_original_name = fields.iter().map(|p| &p.ident.db); - let fields_name = fields.iter().map(|p| &p.ident.rs); - { - let fields_ty = fields.iter().map(|p| p.own_struct(ctx)); - code!(w => - #[derive($ser_str Debug,postgres_types::FromSql,$copy Clone, PartialEq)] - #[postgres(name = "$name")] - pub struct $struct_name { - $( - #[postgres(name = "$fields_original_name")] - pub $fields_name: $fields_ty, - ) - } - ); - } - if *is_copy { - struct_tosql(w, struct_name, fields, name, false, *is_params, ctx); - } else { - let fields_owning = fields.iter().map(|p| p.owning_assign()); - let fields_brw = fields.iter().map(|p| p.brw_ty(true, ctx)); - code!(w => - #[derive(Debug)] - pub struct ${struct_name}Borrowed<'a> { - $(pub $fields_name: $fields_brw,) - } - impl<'a> From<${struct_name}Borrowed<'a>> for $struct_name { - fn from( - ${struct_name}Borrowed { - $($fields_name,) - }: ${struct_name}Borrowed<'a>, - ) -> Self { - Self { - $($fields_owning,) - } - } - } - ); - composite_fromsql(w, struct_name, fields, name, schema); - if !is_params { - let fields_ty = fields.iter().map(|p| p.param_ty(ctx)); - let derive = if *is_copy { ",Copy,Clone" } else { "" }; - code!(w => - #[derive(Debug $derive)] - pub struct ${struct_name}Params<'a> { - $(pub $fields_name: $fields_ty,) - } - ); - } - struct_tosql(w, struct_name, fields, name, true, *is_params, ctx); - } - } - } -} - -fn gen_type_modules( - w: &mut W, - prepared: &IndexMap>, - ctx: &GenCtx, -) { - let modules = prepared.iter().map(|(schema, types)| { - move |w: &mut W| { - let lazy = |w: &mut W| { - for ty in types { - gen_custom_type(w, schema, ty, ctx) - } - }; - - code!(w => - pub mod $schema { - $!lazy - }); - } - }); - code!(w => - #[allow(clippy::all, clippy::pedantic)] - #[allow(unused_variables)] - #[allow(unused_imports)] - #[allow(dead_code)] - pub mod types { - $($!modules) - } - ); -} - -pub(crate) fn generate(preparation: Preparation, settings: CodegenSettings) -> String { - let mut buff = "// This file was generated with `cornucopia`. Do not modify.\n\n".to_string(); - let w = &mut buff; - // Generate database type - gen_type_modules( - w, - &preparation.types, - &GenCtx::new(1, settings.gen_async, settings.derive_ser), - ); - // Generate queries - let query_modules = preparation.modules.iter().map(|module| { - move |w: &mut String| { - let name = &module.info.name; - let ctx = GenCtx::new(2, settings.gen_async, settings.derive_ser); - let params_string = module - .params - .values() - .map(|params| |w: &mut String| gen_params_struct(w, params, &ctx)); - let rows_struct_string = module - .rows - .values() - .map(|row| |w: &mut String| gen_row_structs(w, row, &ctx)); - - let sync_specific = |w: &mut String| { - let gen_specific = |depth: u8, is_async: bool| { - move |w: &mut String| { - let ctx = GenCtx::new(depth, is_async, settings.derive_ser); - let import = if is_async { - "use futures::{StreamExt, TryStreamExt};use futures; use cornucopia_async::GenericClient;" - } else { - "use postgres::{fallible_iterator::FallibleIterator,GenericClient};" - }; - let rows_query_string = module - .rows - .values() - .map(|row| |w: &mut String| gen_row_query(w, row, &ctx)); - let queries_string = module.queries.values().map(|query| { - |w: &mut String| gen_query_fn(w, module, query, &ctx) - }); - code!(w => - $import - $($!rows_query_string) - $($!queries_string) - ) - } - }; - - if settings.gen_async != settings.gen_sync { - if settings.gen_async { - let gen = gen_specific(2, true); - code!(w => $!gen) - } else { - let gen = gen_specific(2, false); - code!(w => $!gen) - } - } else { - let sync = gen_specific(3, false); - let async_ = gen_specific(3, true); - code!(w => - pub mod sync { - $!sync - } - pub mod async_ { - $!async_ - } - ) - - } - }; - - code!(w => - pub mod $name { - $($!params_string) - $($!rows_struct_string) - $!sync_specific - } - ); - } - }); - code!(w => - #[allow(clippy::all, clippy::pedantic)] - #[allow(unused_variables)] - #[allow(unused_imports)] - #[allow(dead_code)] - pub mod queries { - $($!query_modules) - } +pub(crate) fn gen(name: &str, preparation: Preparation, settings: CodegenSettings) -> Vfs { + let mut vfs = Vfs::empty(); + let cargo = cargo::gen_cargo_file(name, &preparation.dependency_analysis, settings); + vfs.add("Cargo.toml", cargo); + vfs.add( + "src/lib.rs", + client::gen_lib(&preparation.dependency_analysis), ); - buff + let types = gen_type_modules(&preparation.types, &settings); + vfs.add("src/types.rs", types); + queries::gen_queries(&mut vfs, &preparation, settings); + client::gen_clients(&mut vfs, &preparation.dependency_analysis, &settings); + vfs } diff --git a/crates/cornucopia/src/codegen/cargo.rs b/crates/cornucopia/src/codegen/cargo.rs new file mode 100644 index 00000000..8755d547 --- /dev/null +++ b/crates/cornucopia/src/codegen/cargo.rs @@ -0,0 +1,156 @@ +use std::fmt::Write; + +use indoc::{formatdoc, writedoc}; +use postgres_types::{Kind, Type}; + +use crate::CodegenSettings; + +/// Register use of typed requiring specific dependencies +#[derive(Debug, Clone, Default)] +pub struct DependencyAnalysis { + pub time: bool, + pub json: bool, + pub uuid: bool, + pub mac_addr: bool, + pub decimal: bool, +} + +impl DependencyAnalysis { + pub fn analyse(&mut self, ty: &Type) { + match ty.kind() { + Kind::Simple => match *ty { + Type::TIME | Type::DATE | Type::TIMESTAMP | Type::TIMESTAMPTZ => self.time = true, + Type::JSON | Type::JSONB => self.json = true, + Type::UUID => self.uuid = true, + Type::MACADDR => self.mac_addr = true, + Type::NUMERIC => self.decimal = true, + _ => {} + }, + Kind::Array(ty) => self.analyse(ty), + Kind::Domain(ty) => self.analyse(ty), + Kind::Composite(fields) => { + for field in fields { + self.analyse(field.type_()) + } + } + _ => {} + } + } + + pub fn has_dependency(&self) -> bool { + self.time | self.json | self.uuid | self.mac_addr | self.decimal + } +} + +pub fn gen_cargo_file( + name: &str, + dependency_analysis: &DependencyAnalysis, + settings: CodegenSettings, +) -> String { + const VERSION: &str = env!("CARGO_PKG_VERSION"); + let mut buf = formatdoc! {r#" + # This file was generated with `cornucopia`. Do not modify + [package] + name = "{name}" + version = "{VERSION}" + edition = "2021" + "#}; + + if settings.gen_async { + writedoc! { buf, r#" + + [features] + default = ["deadpool"] + deadpool = ["dep:deadpool-postgres"] + "#} + .unwrap() + } + + writedoc! { buf, r#" + + [dependencies] + ## Core dependencies + # Postgres types + postgres-types = {{ version = "0.2.6", features = ["derive"] }} + # Postgres interaction + postgres-protocol = "0.6.6" + # Iterator utils required for working with `postgres_protocol::types::ArrayValues` + fallible-iterator = "0.2.0" + "#} + .unwrap(); + + let mut client_features = String::new(); + + if dependency_analysis.has_dependency() { + writeln!(buf, "\n## Types dependencies").unwrap(); + if dependency_analysis.json { + writedoc! { buf, r#" + # JSON or JSONB + serde_json = {{ version = "1.0.113", features = ["raw_value"] }} + serde = {{ version = "1.0.197", features = ["derive"] }} + "#} + .unwrap(); + write!(client_features, r#""with-serde_json-1","#).unwrap(); + } + if dependency_analysis.time { + writedoc! { buf, r#" + # TIME, DATE, TIMESTAMP or TIMESTAMPZ + time = "0.3.34" + "#} + .unwrap(); + write!(client_features, r#""with-time-0_3","#).unwrap(); + } + if dependency_analysis.uuid { + writedoc! { buf, r#" + # UUID + uuid = "1.8.0" + "#} + .unwrap(); + write!(client_features, r#""with-uuid-1","#).unwrap(); + } + if dependency_analysis.mac_addr { + writedoc! { buf, r#" + # MAC ADDRESS + eui48 = "1.1.0" + "#} + .unwrap(); + write!(client_features, r#""with-eui48-1","#).unwrap(); + } + if dependency_analysis.decimal { + writedoc! { buf, r#" + # DECIMAL + rust_decimal = {{ version = "1.29.1", features = ["db-postgres"] }} + "#} + .unwrap(); + } + } + + if settings.gen_sync { + writedoc! { buf, r#" + + ## Sync client dependencies + # Postgres sync client + postgres = {{ version = "0.19.7", features = [{client_features}] }} + "#} + .unwrap(); + } + + if settings.gen_async { + writedoc! { buf, r#" + + ## Async client dependencies + # Postgres async client + tokio-postgres = {{ version = "0.7.10", features = [{client_features}] }} + # Async utils + async-trait = "0.1.78" + futures = "0.3.30" + + ## Async features dependencies + # Async connection pooling + deadpool-postgres = {{ version = "0.14.0", optional = true }} + "#} + .unwrap(); + } + + buf +} diff --git a/crates/cornucopia/src/codegen/client.rs b/crates/cornucopia/src/codegen/client.rs new file mode 100644 index 00000000..e16ba441 --- /dev/null +++ b/crates/cornucopia/src/codegen/client.rs @@ -0,0 +1,847 @@ +use codegen_template::code; +use std::fmt::Write; + +use crate::CodegenSettings; + +use super::{vfs::Vfs, DependencyAnalysis, WARNING}; + +pub(crate) fn gen_lib(dependency_analysis: &DependencyAnalysis) -> String { + let mut w = code!($WARNING + #[allow(clippy::all, clippy::pedantic)] + #[allow(unused_variables)] + #[allow(unused_imports)] + #[allow(dead_code)] + pub mod types; + #[allow(clippy::all, clippy::pedantic)] + #[allow(unused_variables)] + #[allow(unused_imports)] + #[allow(dead_code)] + pub mod queries; + pub mod client; + + mod array_iterator; + mod domain; + mod type_traits; + mod utils; + + pub (crate) use utils::slice_iter; + + pub use array_iterator::ArrayIterator; + pub use domain::{Domain, DomainArray}; + pub use type_traits::{ArraySql, BytesSql, IterSql, StringSql}; + ); + if dependency_analysis.json { + code!(w => pub use type_traits::JsonSql; ) + } + + w +} + +pub(crate) fn gen_clients( + vfs: &mut Vfs, + dependency_analysis: &DependencyAnalysis, + settings: &CodegenSettings, +) { + // Generate common files + vfs.add("src/utils.rs", core_utils()); + vfs.add("src/domain.rs", core_domain()); + vfs.add("src/array_iterator.rs", core_array()); + vfs.add("src/type_traits.rs", core_type_traits(dependency_analysis)); + if settings.gen_sync { + vfs.add("src/client/sync.rs", sync()); + } + if settings.gen_async { + vfs.add("src/client/async_.rs", async_()); + vfs.add( + "src/client/async_/generic_client.rs", + async_generic_client(), + ); + vfs.add("src/client/async_/deadpool.rs", async_deadpool()); + } + vfs.add("src/client.rs", client(settings)) +} + +pub fn client(settings: &CodegenSettings) -> String { + match (settings.gen_async, settings.gen_sync) { + (true, false) => code!( + pub(crate) mod async_; + pub use async_::*; + ), + (false, true) => code!( + pub(crate) mod sync; + pub use sync::*; + ), + _ => code!( + pub mod sync; + pub mod async_; + ), + } +} + +pub fn core_utils() -> String { + code!($WARNING + use postgres_types::{Kind, ToSql, Type}; + + pub fn escape_domain(ty: &Type) -> &Type { + match ty.kind() { + Kind::Domain(ty) => ty, + _ => ty, + } + } + + pub fn slice_iter<'a>( + s: &'a [&'a (dyn ToSql + Sync)], + ) -> impl ExactSizeIterator + 'a { + s.iter().map(|s| *s as _) + } + ) +} + +pub fn core_domain() -> String { + code!($WARNING + use postgres_protocol::types::{array_to_sql, ArrayDimension}; + use postgres_types::{private::BytesMut, IsNull, Kind, ToSql, Type}; + use std::{ + error::Error, + fmt::{Debug, Formatter}, + }; + + use super::{type_traits::ArraySql, utils::escape_domain}; + + pub struct Domain(pub T); + + impl Debug for Domain { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("DomainWrapper").field(&self.0).finish() + } + } + + impl ToSql for Domain { + fn to_sql( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> + where + Self: Sized, + { + postgres_types::ToSql::to_sql(&self.0, escape_domain(ty), out) + } + + fn accepts(ty: &Type) -> bool + where + Self: Sized, + { + return T::accepts(escape_domain(ty)); + } + + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } + } + + pub struct DomainArray<'a, T: ToSql + Sync, A: ArraySql>(pub &'a A); + + impl<'a, T: ToSql + Sync, A: ArraySql> Debug for DomainArray<'a, T, A> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayDomain").field(&self.0).finish() + } + } + + impl<'a, T: ToSql + Sync + 'a, A: ArraySql> ToSql for DomainArray<'a, T, A> { + fn to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + self.0.escape_domain_to_sql(ty, w) + } + + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(escape_domain(member)), + _ => false, + } + } + + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } + } + + pub fn escape_domain_to_sql( + ty: &Type, + w: &mut BytesMut, + iter: impl ExactSizeIterator, + ) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + + array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match Domain(e).to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) + } + + fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } + } + ) +} + +pub fn core_array() -> String { + code!($WARNING + use fallible_iterator::FallibleIterator; + use postgres_protocol::types::{array_from_sql, ArrayValues}; + use postgres_types::{FromSql, Kind, Type}; + use std::fmt::Debug; + use std::marker::PhantomData; + + use super::utils::escape_domain; + + /// Iterator over the items in a PostgreSQL array. You only need this if you are + /// working with custom zero-cost type mapping of rows containing PostgreSQL arrays. + pub struct ArrayIterator<'a, T: FromSql<'a>> { + values: ArrayValues<'a>, + ty: Type, + _type: PhantomData, + } + + impl<'a, T: FromSql<'a>> Debug for ArrayIterator<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ArrayIterator") + .field("values", &"[T]") + .field("ty", &self.ty) + .field("_type", &self._type) + .finish() + } + } + + impl<'a, T: FromSql<'a>> Iterator for ArrayIterator<'a, T> { + type Item = T; + + fn next(&mut self) -> Option { + self.values + .next() + .unwrap() + .map(|raw| T::from_sql_nullable(&self.ty, raw).unwrap()) + } + } + + impl<'a, T: FromSql<'a>> FromSql<'a> for ArrayIterator<'a, T> { + fn from_sql( + ty: &Type, + raw: &'a [u8], + ) -> Result, Box> + { + let member_type = match *escape_domain(ty).kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + + let array = array_from_sql(raw)?; + if array.dimensions().count()? > 1 { + return Err("array contains too many dimensions".into()); + } + + Ok(ArrayIterator { + ty: member_type.clone(), + values: array.values(), + _type: PhantomData, + }) + } + + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref inner) => T::accepts(escape_domain(inner)), + _ => false, + } + } + } + ) +} + +pub fn core_type_traits(dependency_analysis: &DependencyAnalysis) -> String { + let mut w = code!($WARNING + use std::borrow::Cow; + + use super::domain::escape_domain_to_sql; + use postgres_protocol::types::{self, ArrayDimension}; + use postgres_types::{private::BytesMut, to_sql_checked, IsNull, Kind, ToSql, Type}; + + pub trait StringSql: std::fmt::Debug + ToSql + Sync {} + impl StringSql for &T {} + impl StringSql for String {} + impl StringSql for &str {} + impl StringSql for Cow<'_, str> {} + impl StringSql for Box {} + + pub trait BytesSql: std::fmt::Debug + ToSql + Send + Sync {} + impl BytesSql for &T {} + impl BytesSql for Vec {} + impl BytesSql for &[u8] {} + ); + if dependency_analysis.json { + code!(w => + pub trait JsonSql: std::fmt::Debug + ToSql + Sync + Send {} + impl JsonSql for &T {} + impl JsonSql for serde_json::value::Value {} + impl JsonSql for postgres_types::Json {} + ); + } + code!(w => + pub trait ArraySql: std::fmt::Debug + ToSql + Send + Sync { + type Item; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result>; + } + impl> ArraySql for &A { + type Item = T; + + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + A::escape_domain_to_sql(self, ty, w) + } + } + impl ArraySql for Vec { + type Item = T; + + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } + } + + impl ArraySql for &[T] { + type Item = T; + + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } + } + + impl< + T: std::fmt::Debug + ToSql + Send + Sync, + I: Iterator + ExactSizeIterator, + F: Fn() -> I + Send + Sync, + > ArraySql for IterSql + { + type Item = T; + + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, (self.0)()) + } + } + + pub struct IterSql + ExactSizeIterator, F: Fn() -> I + Sync>(pub F); + + impl + ExactSizeIterator, F: Fn() -> I + Sync> std::fmt::Debug + for IterSql + { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayFn").finish() + } + } + + // Taken from `postgres` + impl + ExactSizeIterator, F: Fn() -> I + Sync> ToSql + for IterSql + { + fn to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => member, + _ => panic!("expected array type"), + }; + + let iter = (self.0)(); + + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + + types::array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match e.to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) + } + + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(member), + _ => false, + } + } + + to_sql_checked!(); + } + + // https://github.com/sfackler/rust-postgres/blob/765395f288861209a644c621bf72172acd482515/postgres-types/src/lib.rs + fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } + } + ); + w +} + +pub fn sync() -> String { + code!($WARNING + use postgres::Statement; + + /// This trait allows you to bind parameters to a query using a single + /// struct, rather than passing each bind parameter as a function parameter. + pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a mut C, params: &'a P) -> O; + } + + /// Cached statement + #[doc(hidden)] + pub(crate) struct Stmt { + query: &'static str, + cached: Option, + } + + impl Stmt { + #[must_use] + pub fn new(query: &'static str) -> Self { + Self { + query, + cached: None, + } + } + + pub fn prepare<'a, C: postgres::GenericClient>( + &'a mut self, + client: &mut C, + ) -> Result<&'a Statement, postgres::Error> { + if self.cached.is_none() { + let stmt = client.prepare(self.query)?; + self.cached = Some(stmt); + } + // the statement is always prepared at this point + Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) + } + } + ) +} + +pub fn async_() -> String { + code!($WARNING + pub use generic_client::GenericClient; + use tokio_postgres::{Error, Statement}; + + #[cfg(feature = "deadpool")] + mod deadpool; + mod generic_client; + + /// This trait allows you to bind parameters to a query using a single + /// struct, rather than passing each bind parameter as a function parameter. + pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a C, params: &'a P) -> O; + } + + /// Cached statement + #[doc(hidden)] + pub struct Stmt { + query: &'static str, + cached: Option, + } + + impl Stmt { + #[must_use] + pub fn new(query: &'static str) -> Self { + Self { + query, + cached: None, + } + } + + pub async fn prepare<'a, C: GenericClient>( + &'a mut self, + client: &C, + ) -> Result<&'a Statement, Error> { + if self.cached.is_none() { + let stmt = client.prepare(self.query).await?; + self.cached = Some(stmt); + } + // the statement is always prepared at this point + Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) + } + } + ) +} + +pub fn async_generic_client() -> String { + code!($WARNING + use async_trait::async_trait; + use tokio_postgres::{ + types::BorrowToSql, Client, Error, RowStream, Statement, ToStatement, Transaction, + }; + + /// Abstraction over multiple types of asynchronous clients. + /// This allows you to use tokio_postgres clients and transactions interchangeably. + /// + /// In addition, when the `deadpool` feature is enabled (default), this trait also + /// abstracts over deadpool clients and transactions + #[async_trait] + pub trait GenericClient: Send + Sync { + async fn prepare(&self, query: &str) -> Result; + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + + async fn query_raw( + &self, + statement: &T, + params: I, + ) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator; + } + + #[async_trait] + impl GenericClient for Transaction<'_> { + async fn prepare(&self, query: &str) -> Result { + Transaction::prepare(self, query).await + } + + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::execute(self, query, params).await + } + + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query_one(self, statement, params).await + } + + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query_opt(self, statement, params).await + } + + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query(self, query, params).await + } + + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + Transaction::query_raw(self, statement, params).await + } + } + + #[async_trait] + impl GenericClient for Client { + async fn prepare(&self, query: &str) -> Result { + Client::prepare(self, query).await + } + + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::execute(self, query, params).await + } + + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query_one(self, statement, params).await + } + + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query_opt(self, statement, params).await + } + + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query(self, query, params).await + } + + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + Client::query_raw(self, statement, params).await + } + } + ) +} + +pub fn async_deadpool() -> String { + code!($WARNING + use async_trait::async_trait; + use deadpool_postgres::{ + Client as DeadpoolClient, ClientWrapper, Transaction as DeadpoolTransaction, + }; + use tokio_postgres::{ + types::BorrowToSql, Client as PgClient, Error, RowStream, Statement, ToStatement, + Transaction as PgTransaction, + }; + + use super::generic_client::GenericClient; + + #[async_trait] + impl GenericClient for DeadpoolClient { + async fn prepare(&self, query: &str) -> Result { + ClientWrapper::prepare_cached(self, query).await + } + + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::execute(self, query, params).await + } + + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query_one(self, statement, params).await + } + + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query_opt(self, statement, params).await + } + + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query(self, query, params).await + } + + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + PgClient::query_raw(self, statement, params).await + } + } + + #[async_trait] + impl GenericClient for DeadpoolTransaction<'_> { + async fn prepare(&self, query: &str) -> Result { + DeadpoolTransaction::prepare_cached(self, query).await + } + + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::execute(self, query, params).await + } + + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query_one(self, statement, params).await + } + + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query_opt(self, statement, params).await + } + + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query(self, query, params).await + } + + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + PgTransaction::query_raw(self, statement, params).await + } + } + ) +} diff --git a/crates/cornucopia/src/codegen/queries.rs b/crates/cornucopia/src/codegen/queries.rs new file mode 100644 index 00000000..43e29a68 --- /dev/null +++ b/crates/cornucopia/src/codegen/queries.rs @@ -0,0 +1,444 @@ +use std::fmt::Write; + +use codegen_template::code; + +use crate::{ + codegen::ModCtx, + prepare_queries::{Preparation, PreparedItem, PreparedModule, PreparedQuery}, + CodegenSettings, +}; + +use super::{idx_char, vfs::Vfs, GenCtx, WARNING}; + +fn gen_params_struct(w: &mut impl Write, params: &PreparedItem, ctx: &GenCtx) { + let PreparedItem { + name, + fields, + is_copy, + is_named, + is_ref, + .. + } = params; + if *is_named { + let traits = &mut Vec::new(); + + let copy = if *is_copy { "Clone,Copy," } else { "" }; + let lifetime = if *is_ref { "'a," } else { "" }; + let fields_ty = fields + .iter() + .map(|p| p.param_ergo_ty(traits, ctx)) + .collect::>(); + let fields_name = fields.iter().map(|p| &p.ident.rs); + let traits_idx = (1..=traits.len()).map(idx_char); + code!(w => + #[derive($copy Debug)] + pub struct $name<$lifetime $($traits_idx: $traits,)> { + $(pub $fields_name: $fields_ty,) + } + ); + } +} + +fn gen_row_structs(w: &mut impl Write, row: &PreparedItem, ctx: &GenCtx) { + let PreparedItem { + name, + fields, + is_copy, + is_named, + .. + } = row; + if *is_named { + // Generate row struct + let fields_name = fields.iter().map(|p| &p.ident.rs); + let fields_ty = fields.iter().map(|p| p.own_struct(ctx)); + let copy = if *is_copy { "Copy" } else { "" }; + let ser_str = if ctx.gen_derive { + "serde::Serialize," + } else { + "" + }; + code!(w => + #[derive($ser_str Debug, Clone, PartialEq,$copy)] + pub struct $name { + $(pub $fields_name : $fields_ty,) + } + ); + + if !is_copy { + let fields_name = fields.iter().map(|p| &p.ident.rs); + let fields_ty = fields.iter().map(|p| p.brw_ty(true, ctx)); + let from_own_assign = fields.iter().map(|f| f.owning_assign()); + code!(w => + pub struct ${name}Borrowed<'a> { + $(pub $fields_name : $fields_ty,) + } + impl<'a> From<${name}Borrowed<'a>> for $name { + fn from(${name}Borrowed { $($fields_name,) }: ${name}Borrowed<'a>) -> Self { + Self { + $($from_own_assign,) + } + } + } + ); + }; + } +} + +fn gen_row_query(w: &mut impl Write, row: &PreparedItem, ctx: &GenCtx) { + let PreparedItem { + name, + fields, + is_copy, + is_named, + .. + } = row; + // Generate query struct + let borrowed_str = if *is_copy { "" } else { "Borrowed" }; + let (client_mut, fn_async, fn_await, backend, collect, raw_type, raw_pre, raw_post) = + if ctx.is_async { + ( + "", + "async", + ".await", + "tokio_postgres", + "try_collect().await", + "futures::Stream", + "", + ".into_stream()", + ) + } else { + ( + "mut", + "", + "", + "postgres", + "collect()", + "Iterator", + ".iterator()", + "", + ) + }; + let client = ctx.client_name(); + + let row_struct = if *is_named { + format!("{}{borrowed_str}", row.path(ctx)) + } else { + fields[0].brw_ty(false, ctx) + }; + + code!(w => + pub struct ${name}Query<'a, C: GenericClient, T, const N: usize> { + client: &'a $client_mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut $client::Stmt, + extractor: fn(&$backend::Row) -> $row_struct, + mapper: fn($row_struct) -> T, + } + impl<'a, C, T:'a, const N: usize> ${name}Query<'a, C, T, N> where C: GenericClient { + pub fn map(self, mapper: fn($row_struct) -> R) -> ${name}Query<'a,C,R,N> { + ${name}Query { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + + pub $fn_async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)$fn_await?; + let row = self.client.query_one(stmt, &self.params)$fn_await?; + Ok((self.mapper)((self.extractor)(&row))) + } + + pub $fn_async fn all(self) -> Result, $backend::Error> { + self.iter()$fn_await?.$collect + } + + pub $fn_async fn opt(self) -> Result, $backend::Error> { + let stmt = self.stmt.prepare(self.client)$fn_await?; + Ok(self + .client + .query_opt(stmt, &self.params) + $fn_await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + + pub $fn_async fn iter( + self, + ) -> Result> + 'a, $backend::Error> { + let stmt = self.stmt.prepare(self.client)$fn_await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + $fn_await? + $raw_pre + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + $raw_post; + Ok(it) + } + }); +} + +fn gen_query_fn(w: &mut W, module: &PreparedModule, query: &PreparedQuery, ctx: &GenCtx) { + let PreparedQuery { + ident, + row, + sql, + param, + } = query; + + let (client_mut, fn_async, fn_await, backend) = if ctx.is_async { + ("", "async", ".await", "tokio_postgres") + } else { + ("mut", "", "", "postgres") + }; + let client = ctx.client_name(); + + let struct_name = ident.type_ident(); + let (param, param_field, order) = match param { + Some((idx, order)) => { + let it = module.params.get_index(*idx).unwrap().1; + (Some(it), it.fields.as_slice(), order.as_slice()) + } + None => (None, [].as_slice(), [].as_slice()), + }; + let traits = &mut Vec::new(); + let params_ty: Vec<_> = order + .iter() + .map(|idx| param_field[*idx].param_ergo_ty(traits, ctx)) + .collect(); + let params_name = order.iter().map(|idx| ¶m_field[*idx].ident.rs); + let traits_idx = (1..=traits.len()).map(idx_char); + let lazy_impl = |w: &mut W| { + if let Some((idx, index)) = row { + let item = module.rows.get_index(*idx).unwrap().1; + let PreparedItem { + name: row_name, + fields, + is_copy, + is_named, + .. + } = &item; + // Query fn + let nb_params = param_field.len(); + + // TODO find a way to clean this mess + #[allow(clippy::type_complexity)] + let (row_struct_name, extractor, mapper): (_, Box, _) = if *is_named { + let path = item.path(ctx); + ( + path.clone(), + Box::new(|w: _| { + let path = item.path(ctx); + let post = if *is_copy { "" } else { "Borrowed" }; + let fields_name = fields.iter().map(|p| &p.ident.rs); + let fields_idx = (0..fields.len()).map(|i| index[i]); + code!(w => $path$post { + $($fields_name: row.get($fields_idx),) + }) + }), + code!(<$path>::from(it)), + ) + } else { + let field = &fields[0]; + ( + field.own_struct(ctx), + Box::new(|w: _| code!(w => row.get(0))), + field.owning_call(Some("it")), + ) + }; + code!(w => + pub fn bind<'a, C: GenericClient,$($traits_idx: $traits,)>(&'a mut self, client: &'a $client_mut C, $($params_name: &'a $params_ty,) ) -> ${row_name}Query<'a,C, $row_struct_name, $nb_params> { + ${row_name}Query { + client, + params: [$($params_name,)], + stmt: &mut self.0, + extractor: |row| { $!extractor }, + mapper: |it| { $mapper }, + } + } + ); + } else { + // Execute fn + let params_wrap = order.iter().map(|idx| { + let p = ¶m_field[*idx]; + p.ty.sql_wrapped(&p.ident.rs) + }); + code!(w => + pub $fn_async fn bind<'a, C: GenericClient,$($traits_idx: $traits,)>(&'a mut self, client: &'a $client_mut C, $($params_name: &'a $params_ty,)) -> Result { + let stmt = self.0.prepare(client)$fn_await?; + client.execute(stmt, &[ $($params_wrap,) ])$fn_await + } + ); + } + }; + // Gen statement struct + { + let sql = sql.replace('"', "\\\""); // Rust string format escaping + let name = &ident.rs; + code!(w => + pub fn $name() -> ${struct_name}Stmt { + ${struct_name}Stmt($client::Stmt::new("$sql")) + } + pub struct ${struct_name}Stmt($client::Stmt); + impl ${struct_name}Stmt { + $!lazy_impl + } + ); + } + + // Param impl + if let Some(param) = param { + if param.is_named { + let param_path = ¶m.path(ctx); + let lifetime = if param.is_copy || !param.is_ref { + "" + } else { + "'a," + }; + if let Some((idx, _)) = row { + let prepared_row = &module.rows.get_index(*idx).unwrap().1; + let query_row_struct = if prepared_row.is_named { + prepared_row.path(ctx) + } else { + prepared_row.fields[0].own_struct(ctx) + }; + let name = &module.rows.get_index(*idx).unwrap().1.name; + let nb_params = param_field.len(); + code!(w => + impl <'a, C: GenericClient,$($traits_idx: $traits,)> $client::Params<'a, $param_path<$lifetime $($traits_idx,)>, ${name}Query<'a, C, $query_row_struct, $nb_params>, C> for ${struct_name}Stmt { + fn params(&'a mut self, client: &'a $client_mut C, params: &'a $param_path<$lifetime $($traits_idx,)>) -> ${name}Query<'a, C, $query_row_struct, $nb_params> { + self.bind(client, $(¶ms.$params_name,)) + } + } + ); + } else { + let (send_sync, pre_ty, post_ty_lf, pre, post) = if ctx.is_async { + ( + "+ Send + Sync", + "std::pin::Pin + Send + 'a>>", + "Box::pin(self", + ")", + ) + } else { + ("", "Result", "", "self", "") + }; + code!(w => + impl <'a, C: GenericClient $send_sync, $($traits_idx: $traits,)> $client::Params<'a, $param_path<$lifetime $($traits_idx,)>, $pre_ty$post_ty_lf, C> for ${struct_name}Stmt { + fn params(&'a mut self, client: &'a $client_mut C, params: &'a $param_path<$lifetime $($traits_idx,)>) -> $pre_ty$post_ty_lf { + $pre.bind(client, $(¶ms.$params_name,))$post + } + } + ); + } + } + } +} + +fn gen_query_module(module: &PreparedModule, settings: CodegenSettings) -> String { + let ctx = GenCtx::new(ModCtx::Queries, settings.gen_async, settings.derive_ser); + let params_string = module + .params + .values() + .map(|params| |w: &mut String| gen_params_struct(w, params, &ctx)); + let rows_struct_string = module + .rows + .values() + .map(|row| |w: &mut String| gen_row_structs(w, row, &ctx)); + + let sync_specific = |w: &mut String| { + let gen_specific = |hierarchy: ModCtx, is_async: bool| { + move |w: &mut String| { + let ctx = GenCtx::new(hierarchy, is_async, settings.derive_ser); + let import = if is_async { + "use futures::{self, StreamExt, TryStreamExt}; use crate::client::async_::GenericClient;" + } else { + "use postgres::{fallible_iterator::FallibleIterator,GenericClient};" + }; + let rows_query_string = module + .rows + .values() + .map(|row| |w: &mut String| gen_row_query(w, row, &ctx)); + let queries_string = module + .queries + .values() + .map(|query| |w: &mut String| gen_query_fn(w, module, query, &ctx)); + code!(w => + $import + $($!rows_query_string) + $($!queries_string) + ) + } + }; + + if settings.gen_async && settings.gen_sync { + let gen = gen_specific(ModCtx::CLientQueries, false); + code!(w => pub mod sync { $!gen}); + + let gen = gen_specific(ModCtx::CLientQueries, true); + code!(w => pub mod async_ { $!gen}); + } else if settings.gen_sync { + let gen = gen_specific(ModCtx::Queries, false); + code!(w => $!gen); + } else { + let gen = gen_specific(ModCtx::Queries, true); + code!(w => $!gen); + } + }; + + code!($WARNING + $($!params_string) + $($!rows_struct_string) + $!sync_specific + ) +} + +pub(crate) fn gen_queries(vfs: &mut Vfs, preparation: &Preparation, settings: CodegenSettings) { + for module in &preparation.modules { + let gen = gen_query_module(module, settings); + vfs.add(format!("src/queries/{}.rs", module.info.name), gen); + } + + let modules_name = preparation.modules.iter().map(|module| &module.info.name); + + let mut content = code!($WARNING + $(pub mod $modules_name;) + ); + if settings.gen_async && settings.gen_sync { + let sync = |w: &mut String| { + for module in &preparation.modules { + let name = &module.info.name; + code!(w => + pub mod ${name} { + pub use super::super::${name}::*; + pub use super::super::${name}::sync::*; + } + ); + } + }; + let async_ = |w: &mut String| { + for module in &preparation.modules { + let name = &module.info.name; + code!(w => + pub mod ${name} { + pub use super::super::${name}::*; + pub use super::super::${name}::async_::*; + } + ); + } + }; + let content = &mut content; + code!(content => + pub mod sync { + $!sync + } + pub mod async_ { + $!async_ + } + ) + } + + vfs.add("src/queries.rs", content); +} diff --git a/crates/cornucopia/src/codegen/types.rs b/crates/cornucopia/src/codegen/types.rs new file mode 100644 index 00000000..1e5d142b --- /dev/null +++ b/crates/cornucopia/src/codegen/types.rs @@ -0,0 +1,331 @@ +use std::fmt::Write; + +use codegen_template::code; +use indexmap::IndexMap; + +use crate::{ + codegen::{ModCtx, WARNING}, + prepare_queries::{Ident, PreparedContent, PreparedField, PreparedType}, + CodegenSettings, +}; + +use super::GenCtx; + +pub(crate) fn gen_type_modules( + prepared: &IndexMap>, + settings: &CodegenSettings, +) -> String { + let modules = prepared.iter().map(|(schema, types)| { + move |w: &mut String| { + if schema == "public" { + let ctx = &GenCtx::new(ModCtx::Types, settings.gen_async, settings.derive_ser); + let lazy = |w: &mut String| { + for ty in types { + gen_custom_type(w, schema, ty, ctx) + } + }; + code!(w => $!lazy); + } else { + let ctx = + &GenCtx::new(ModCtx::SchemaTypes, settings.gen_async, settings.derive_ser); + let lazy = |w: &mut String| { + for ty in types { + gen_custom_type(w, schema, ty, ctx) + } + }; + code!(w => pub mod $schema { $!lazy }); + } + } + }); + code!($WARNING + $($!modules) + ) +} + +/// Generates type definitions for custom user types. This includes domains, composites and enums. +/// If the type is not `Copy`, then a Borrowed version will be generated. +fn gen_custom_type(w: &mut String, schema: &str, prepared: &PreparedType, ctx: &GenCtx) { + let PreparedType { + struct_name, + content, + is_copy, + is_params, + name, + } = prepared; + let copy = if *is_copy { "Copy," } else { "" }; + let ser_str = if ctx.gen_derive { + "serde::Serialize," + } else { + "" + }; + match content { + PreparedContent::Enum(variants) => { + let variants_ident = variants.iter().map(|v| &v.rs); + code!(w => + #[derive($ser_str Debug, Clone, Copy, PartialEq, Eq)] + #[allow(non_camel_case_types)] + pub enum $struct_name { + $($variants_ident,) + } + ); + enum_sql(w, name, struct_name, variants); + } + PreparedContent::Composite(fields) => { + let fields_original_name = fields.iter().map(|p| &p.ident.db); + let fields_name = fields.iter().map(|p| &p.ident.rs); + { + let fields_ty = fields.iter().map(|p| p.own_struct(ctx)); + code!(w => + #[derive($ser_str Debug,postgres_types::FromSql,$copy Clone, PartialEq)] + #[postgres(name = "$name")] + pub struct $struct_name { + $( + #[postgres(name = "$fields_original_name")] + pub $fields_name: $fields_ty, + ) + } + ); + } + if *is_copy { + struct_tosql(w, struct_name, fields, name, false, *is_params, ctx); + } else { + let fields_owning = fields.iter().map(|p| p.owning_assign()); + let fields_brw = fields.iter().map(|p| p.brw_ty(true, ctx)); + code!(w => + #[derive(Debug)] + pub struct ${struct_name}Borrowed<'a> { + $(pub $fields_name: $fields_brw,) + } + impl<'a> From<${struct_name}Borrowed<'a>> for $struct_name { + fn from( + ${struct_name}Borrowed { + $($fields_name,) + }: ${struct_name}Borrowed<'a>, + ) -> Self { + Self { + $($fields_owning,) + } + } + } + ); + composite_fromsql(w, struct_name, fields, name, schema); + if !is_params { + let fields_ty = fields.iter().map(|p| p.param_ty(ctx)); + let derive = if *is_copy { ",Copy,Clone" } else { "" }; + code!(w => + #[derive(Debug $derive)] + pub struct ${struct_name}Params<'a> { + $(pub $fields_name: $fields_ty,) + } + ); + } + struct_tosql(w, struct_name, fields, name, true, *is_params, ctx); + } + } + } +} + +fn enum_sql(w: &mut String, name: &str, enum_name: &str, variants: &[Ident]) { + let enum_names = std::iter::repeat(enum_name); + let db_variants_ident = variants.iter().map(|v| &v.db); + let rs_variants_ident = variants.iter().map(|v| &v.rs); + + let nb_variants = variants.len(); + code!(w => + impl<'a> postgres_types::ToSql for $enum_name { + fn to_sql( + &self, + ty: &postgres_types::Type, + buf: &mut postgres_types::private::BytesMut, + ) -> Result,> { + let s = match *self { + $($enum_names::$rs_variants_ident => "$db_variants_ident",) + }; + buf.extend_from_slice(s.as_bytes()); + std::result::Result::Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "$name" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != $nb_variants { + return false; + } + variants.iter().all(|v| match &**v { + $("$db_variants_ident" => true,) + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } + } + impl<'a> postgres_types::FromSql<'a> for $enum_name { + fn from_sql( + ty: &postgres_types::Type, + buf: &'a [u8], + ) -> Result<$enum_name, Box,> { + match std::str::from_utf8(buf)? { + $("$db_variants_ident" => Ok($enum_names::$rs_variants_ident),) + s => Result::Err(Into::into(format!( + "invalid variant `{}`", + s + ))), + } + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "$name" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != $nb_variants { + return false; + } + variants.iter().all(|v| match &**v { + $("$db_variants_ident" => true,) + _ => false, + }) + } + _ => false, + } + } + } + ); +} + +fn struct_tosql( + w: &mut impl Write, + struct_name: &str, + fields: &[PreparedField], + name: &str, + is_borrow: bool, + is_params: bool, + ctx: &GenCtx, +) { + let (post, lifetime) = if is_borrow { + if is_params { + ("Borrowed", "<'a>") + } else { + ("Params", "<'a>") + } + } else { + ("", "") + }; + let db_fields_ident = fields.iter().map(|p| &p.ident.db); + let rs_fields_ident = fields.iter().map(|p| &p.ident.rs); + let write_ty = fields.iter().map(|p| p.ty.sql_wrapped(&p.ident.rs)); + let accept_ty = fields.iter().map(|p| p.ty.accept_to_sql(ctx)); + let nb_fields = fields.len(); + + code!(w => + impl<'a> postgres_types::ToSql for $struct_name$post $lifetime { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result,> { + let $struct_name$post { + $($rs_fields_ident,) + } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + $("$db_fields_ident" => postgres_types::ToSql::to_sql($write_ty,field.type_(), out),) + _ => unreachable!() + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "$name" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != $nb_fields { + return false; + } + fields.iter().all(|f| match f.name() { + $("$db_fields_ident" => <$accept_ty as postgres_types::ToSql>::accepts(f.type_()),) + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } + } + ); +} + +fn composite_fromsql( + w: &mut String, + struct_name: &str, + fields: &[PreparedField], + name: &str, + schema: &str, +) { + let field_names = fields.iter().map(|p| &p.ident.rs); + let read_idx = 0..fields.len(); + code!(w => + impl<'a> postgres_types::FromSql<'a> for ${struct_name}Borrowed<'a> { + fn from_sql(ty: &postgres_types::Type, out: &'a [u8]) -> + Result<${struct_name}Borrowed<'a>, Box> + { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err( + std::convert::Into::into(format!("invalid field count: {} vs {}", num_fields, fields.len()))); + } + $( + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let $field_names = postgres_types::private::read_value(fields[$read_idx].type_(), &mut out)?; + ) + Ok(${struct_name}Borrowed { $($field_names,) }) + } + + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "$name" && ty.schema() == "$schema" + } + } + ); +} diff --git a/crates/cornucopia/src/codegen/vfs.rs b/crates/cornucopia/src/codegen/vfs.rs new file mode 100644 index 00000000..2fa4bff4 --- /dev/null +++ b/crates/cornucopia/src/codegen/vfs.rs @@ -0,0 +1,46 @@ +use std::{ + collections::BTreeMap, + path::{Path, PathBuf}, +}; + +use crate::error::PersistError; + +/// In memory storage of file +/// Can only fail while persisting +pub struct Vfs { + fs: BTreeMap, +} + +impl Vfs { + pub fn empty() -> Self { + Self { + fs: BTreeMap::new(), + } + } + + /// Add a new file + pub fn add(&mut self, path: impl Into, content: impl Into) { + assert!(self.fs.insert(path.into(), content.into()).is_none()) + } + + /// Materialize on real file system, overwrite existing directory if any + pub fn persist(self, destination: impl AsRef) -> Result<(), PersistError> { + let destination = destination.as_ref(); + // First write in a temporary directory to prevent leaving the destination in a bad state + let tmp = tempfile::tempdir().map_err(PersistError::wrap("tempfile"))?; + for (path, content) in self.fs { + let path = tmp.path().join(path); + let parent = path + .parent() + .expect("Must at least has 'destination' as parent"); + std::fs::create_dir_all(parent).ok(); // Might already exist + std::fs::write(&path, content).map_err(PersistError::wrap(path))?; + } + // Swap destination and tmp as atomically as possible + // TODO is it possible to do this atomically for some platform ? + std::fs::remove_dir_all(destination).ok(); // Might not exist + std::fs::create_dir_all(destination).map_err(PersistError::wrap(destination))?; + std::fs::rename(tmp.into_path(), destination).map_err(PersistError::wrap(destination))?; + Ok(()) + } +} diff --git a/crates/cornucopia/src/error.rs b/crates/cornucopia/src/error.rs index 011b343c..1243df71 100644 --- a/crates/cornucopia/src/error.rs +++ b/crates/cornucopia/src/error.rs @@ -22,8 +22,8 @@ pub enum Error { PrepareQueries(#[from] crate::prepare_queries::error::Error), /// An error while reading PostgreSQL schema files. LoadSchema(#[from] crate::load_schema::error::Error), - /// An error while trying to write the generated code to its destination file. - WriteCodeGenFile(#[from] WriteOutputError), + /// An error while trying to write the generated crate to its destination. + PersistCrate(#[from] PersistError), } impl Error { @@ -39,8 +39,17 @@ impl Error { } #[derive(Debug, ThisError, Diagnostic)] -#[error("Could not write your queries to destination file `{file_path}`: ({err})")] -pub struct WriteOutputError { +#[error("Could not perform IO on file `{file_path}`: ({err})")] +pub struct PersistError { pub(crate) file_path: PathBuf, pub(crate) err: std::io::Error, } + +impl PersistError { + pub fn wrap(path: impl Into) -> impl FnOnce(std::io::Error) -> PersistError { + |err| PersistError { + file_path: path.into(), + err, + } + } +} diff --git a/crates/cornucopia/src/lib.rs b/crates/cornucopia/src/lib.rs index b879ee28..16809ed2 100644 --- a/crates/cornucopia/src/lib.rs +++ b/crates/cornucopia/src/lib.rs @@ -18,8 +18,6 @@ use std::path::Path; use postgres::Client; -use codegen::generate as generate_internal; -use error::WriteOutputError; use parser::parse_query_module; use prepare_queries::prepare; use read_queries::read_query_modules; @@ -39,15 +37,14 @@ pub struct CodegenSettings { } /// Generates Rust queries from PostgreSQL queries located at `queries_path`, -/// using a live database managed by you. If some `destination` is given, -/// the generated code will be written at that path. Code generation settings are +/// using a live database managed by you. Code generation settings are /// set using the `settings` parameter. -pub fn generate_live>( +pub fn gen_live>( client: &mut Client, queries_path: P, - destination: Option

, + destination: P, settings: CodegenSettings, -) -> Result { +) -> Result<(), Error> { // Read let modules = read_query_modules(queries_path.as_ref())? .into_iter() @@ -55,29 +52,30 @@ pub fn generate_live>( .collect::>()?; // Generate let prepared_modules = prepare(client, modules)?; - let generated_code = generate_internal(prepared_modules, settings); + let generated = codegen::gen( + extract_name(destination.as_ref()), + prepared_modules, + settings, + ); // Write - if let Some(d) = destination { - write_generated_code(d.as_ref(), &generated_code)?; - }; + generated.persist(destination)?; - Ok(generated_code) + Ok(()) } /// Generates Rust queries from PostgreSQL queries located at `queries_path`, using /// a container managed by cornucopia. The database schema is created using `schema_files`. -/// If some `destination` is given, the generated code will be written at that path. /// Code generation settings are set using the `settings` parameter. /// /// By default, the container manager is Docker, but Podman can be used by setting the /// `podman` parameter to `true`. -pub fn generate_managed>( +pub fn gen_managed>( queries_path: P, schema_files: &[P], - destination: Option

, + destination: P, podman: bool, settings: CodegenSettings, -) -> Result { +) -> Result<(), Error> { // Read let modules = read_query_modules(queries_path.as_ref())? .into_iter() @@ -87,21 +85,21 @@ pub fn generate_managed>( let mut client = conn::cornucopia_conn()?; load_schema(&mut client, schema_files)?; let prepared_modules = prepare(&mut client, modules)?; - let generated_code = generate_internal(prepared_modules, settings); + let generated = codegen::gen( + extract_name(destination.as_ref()), + prepared_modules, + settings, + ); container::cleanup(podman)?; + // Write + generated.persist(destination)?; - if let Some(destination) = destination { - write_generated_code(destination.as_ref(), &generated_code)?; - }; - - Ok(generated_code) + Ok(()) } -fn write_generated_code(destination: &Path, generated_code: &str) -> Result<(), Error> { - Ok( - std::fs::write(destination, generated_code).map_err(|err| WriteOutputError { - err, - file_path: destination.to_owned(), - })?, - ) +fn extract_name(destination: &Path) -> &str { + destination + .file_name() + .and_then(|n| n.to_str()) + .unwrap_or("cornucopia") } diff --git a/crates/cornucopia/src/load_schema.rs b/crates/cornucopia/src/load_schema.rs index f2616f90..2a92bad9 100644 --- a/crates/cornucopia/src/load_schema.rs +++ b/crates/cornucopia/src/load_schema.rs @@ -52,7 +52,7 @@ pub(crate) mod error { Postgres { msg: String, #[source_code] - src: NamedSource, + src: NamedSource, #[help] help: Option, #[label("error occurs near this location")] diff --git a/crates/cornucopia/src/parser.rs b/crates/cornucopia/src/parser.rs index cff887f8..a62c18a2 100644 --- a/crates/cornucopia/src/parser.rs +++ b/crates/cornucopia/src/parser.rs @@ -402,13 +402,14 @@ pub(crate) fn parse_query_module(info: ModuleInfo) -> Result { pub(crate) mod error { use miette::{Diagnostic, NamedSource, SourceSpan}; + use std::sync::Arc; use thiserror::Error as ThisError; #[derive(Debug, ThisError, Diagnostic)] #[error("Couldn't parse queries")] pub struct Error { #[source_code] - pub src: NamedSource, + pub src: NamedSource>, #[help] pub help: String, diff --git a/crates/cornucopia/src/prepare_queries.rs b/crates/cornucopia/src/prepare_queries.rs index 9edf6eee..48a425f0 100644 --- a/crates/cornucopia/src/prepare_queries.rs +++ b/crates/cornucopia/src/prepare_queries.rs @@ -6,7 +6,7 @@ use postgres::Client; use postgres_types::{Kind, Type}; use crate::{ - codegen::GenCtx, + codegen::{DependencyAnalysis, GenCtx, ModCtx}, parser::{Module, NullableIdent, Query, Span, TypeAnnotation}, read_queries::ModuleInfo, type_registrar::CornucopiaType, @@ -88,7 +88,7 @@ impl PreparedField { impl PreparedField { pub fn unwrapped_name(&self) -> String { - self.own_struct(&GenCtx::new(0, false, false)) + self.own_struct(&GenCtx::new(ModCtx::Types, false, false)) .replace(['<', '>', '_'], "") .to_upper_camel_case() } @@ -115,7 +115,13 @@ impl PreparedItem { } pub fn path(&self, ctx: &GenCtx) -> String { - ctx.path(ctx.depth - 2, &self.name) + match ctx.hierarchy { + ModCtx::Types | ModCtx::SchemaTypes => { + unreachable!() + } + ModCtx::Queries => self.name.to_string(), + ModCtx::CLientQueries => format!("super::{}", self.name), + } } } @@ -148,6 +154,7 @@ pub(crate) struct PreparedModule { pub(crate) struct Preparation { pub(crate) modules: Vec, pub(crate) types: IndexMap>, + pub(crate) dependency_analysis: DependencyAnalysis, } impl PreparedModule { @@ -228,10 +235,9 @@ impl PreparedModule { /// Prepares all modules pub(crate) fn prepare(client: &mut Client, modules: Vec) -> Result { let mut registrar = TypeRegistrar::default(); - let mut tmp = Preparation { - modules: Vec::new(), - types: IndexMap::new(), - }; + let mut prepared_types: IndexMap> = IndexMap::new(); + let mut prepared_modules = Vec::new(); + let declared: Vec<_> = modules .iter() .flat_map(|it| &it.types) @@ -239,14 +245,13 @@ pub(crate) fn prepare(client: &mut Client, modules: Vec) -> Result { entry.get_mut().push(ty); } @@ -256,7 +261,11 @@ pub(crate) fn prepare(client: &mut Client, modules: Vec) -> Result String { @@ -447,6 +456,8 @@ fn prepare_query( } pub(crate) mod error { + use std::sync::Arc; + use miette::{Diagnostic, NamedSource, SourceSpan}; use thiserror::Error as ThisError; @@ -463,7 +474,7 @@ pub(crate) mod error { #[help] help: Option, #[source_code] - src: NamedSource, + src: NamedSource>, #[label("error occurs near this location")] err_span: Option, }, diff --git a/crates/cornucopia/src/read_queries.rs b/crates/cornucopia/src/read_queries.rs index 7f9bda42..53987499 100644 --- a/crates/cornucopia/src/read_queries.rs +++ b/crates/cornucopia/src/read_queries.rs @@ -14,13 +14,13 @@ pub(crate) struct ModuleInfo { pub(crate) content: Arc, } -impl From for NamedSource { +impl From for NamedSource> { fn from(m: ModuleInfo) -> Self { Self::new(m.path.to_string_lossy(), m.content) } } -impl From<&ModuleInfo> for NamedSource { +impl From<&ModuleInfo> for NamedSource> { fn from(m: &ModuleInfo) -> Self { Self::new(m.path.to_string_lossy(), m.content.clone()) } diff --git a/crates/cornucopia/src/type_registrar.rs b/crates/cornucopia/src/type_registrar.rs index 1b7ca70f..aa15c2f5 100644 --- a/crates/cornucopia/src/type_registrar.rs +++ b/crates/cornucopia/src/type_registrar.rs @@ -5,7 +5,7 @@ use indexmap::{map::Entry, IndexMap}; use postgres_types::{Kind, Type}; use crate::{ - codegen::{idx_char, GenCtx}, + codegen::{idx_char, DependencyAnalysis, GenCtx}, parser::Span, read_queries::ModuleInfo, utils::SchemaKey, @@ -73,21 +73,14 @@ impl CornucopiaType { } /// Wrap type to escape domains in parameters - pub(crate) fn sql_wrapped(&self, name: &str, ctx: &GenCtx) -> String { - let client_name = ctx.client_name(); + pub(crate) fn sql_wrapped(&self, name: &str) -> String { match self { CornucopiaType::Domain { inner, .. } => { - format!( - "&{client_name}::private::Domain({})", - inner.sql_wrapped(name, ctx) - ) + format!("&crate::Domain({})", inner.sql_wrapped(name)) } CornucopiaType::Array { inner } => match inner.as_ref() { CornucopiaType::Domain { inner, .. } => { - format!( - "&{client_name}::private::DomainArray({})", - inner.sql_wrapped(name, ctx) - ) + format!("&crate::DomainArray({})", inner.sql_wrapped(name)) } _ => name.to_string(), }, @@ -97,16 +90,14 @@ impl CornucopiaType { /// Wrap type to escape domains when writing to sql pub(crate) fn accept_to_sql(&self, ctx: &GenCtx) -> String { - let client_name = ctx.client_name(); match self { - CornucopiaType::Domain { inner, .. } => format!( - "{client_name}::private::Domain::<{}>", - inner.accept_to_sql(ctx) - ), + CornucopiaType::Domain { inner, .. } => { + format!("crate::Domain::<{}>", inner.accept_to_sql(ctx)) + } CornucopiaType::Array { inner } => match inner.as_ref() { CornucopiaType::Domain { inner, .. } => { let ty = inner.accept_to_sql(ctx); - format!("{client_name}::private::DomainArray::<{ty}, &[{ty}]>") + format!("crate::DomainArray::<{ty}, &[{ty}]>") } _ => self.param_ty(false, ctx), }, @@ -170,7 +161,7 @@ impl CornucopiaType { CornucopiaType::Domain { inner, .. } => inner.own_ty(false, ctx), CornucopiaType::Custom { struct_name, pg_ty, .. - } => custom_ty_path(pg_ty.schema(), struct_name, ctx), + } => ctx.custom_ty_path(pg_ty.schema(), struct_name), } } @@ -181,19 +172,18 @@ impl CornucopiaType { traits: &mut Vec, ctx: &GenCtx, ) -> String { - let client_name = ctx.client_name(); match self { CornucopiaType::Simple { pg_ty, .. } => match *pg_ty { Type::BYTEA => { - traits.push(format!("{client_name}::BytesSql")); + traits.push("crate::BytesSql".to_string()); idx_char(traits.len()) } Type::TEXT | Type::VARCHAR => { - traits.push(format!("{client_name}::StringSql")); + traits.push("crate::StringSql".to_string()); idx_char(traits.len()) } Type::JSON | Type::JSONB => { - traits.push(format!("{client_name}::JsonSql")); + traits.push("crate::JsonSql".to_string()); idx_char(traits.len()) } _ => self.param_ty(is_inner_nullable, ctx), @@ -205,7 +195,7 @@ impl CornucopiaType { } else { inner }; - traits.push(format!("{client_name}::ArraySql")); + traits.push(format!("crate::ArraySql")); idx_char(traits.len()) } CornucopiaType::Domain { inner, .. } => { @@ -241,7 +231,7 @@ impl CornucopiaType { .. } => { if !is_copy && !is_params { - let path = custom_ty_path(pg_ty.schema(), struct_name, ctx); + let path = ctx.custom_ty_path(pg_ty.schema(), struct_name); format!("{path}Params<'a>") } else { self.brw_ty(is_inner_nullable, true, ctx) @@ -279,8 +269,7 @@ impl CornucopiaType { }; // Its more practical for users to use a slice let lifetime = if has_lifetime { lifetime } else { "'_" }; - let client_name = ctx.client_name(); - format!("{client_name}::ArrayIterator<{lifetime}, {inner}>") + format!("crate::ArrayIterator<{lifetime}, {inner}>") } CornucopiaType::Domain { inner, .. } => inner.brw_ty(false, has_lifetime, ctx), CornucopiaType::Custom { @@ -289,7 +278,7 @@ impl CornucopiaType { struct_name, .. } => { - let path = custom_ty_path(pg_ty.schema(), struct_name, ctx); + let path = ctx.custom_ty_path(pg_ty.schema(), struct_name); if *is_copy { path } else { @@ -300,20 +289,11 @@ impl CornucopiaType { } } -pub fn custom_ty_path(schema: &str, struct_name: &str, ctx: &GenCtx) -> String { - if ctx.depth == 0 { - format!("{schema}::{struct_name}") - } else if ctx.depth == 1 { - format!("super::{schema}::{struct_name}") - } else { - ctx.path(ctx.depth, format_args!("types::{schema}::{struct_name}")) - } -} - /// Data structure holding all types known to this particular run of Cornucopia. #[derive(Debug, Clone, Default)] pub(crate) struct TypeRegistrar { pub types: IndexMap<(String, String), Rc>, + pub dependency_analysis: DependencyAnalysis, } impl TypeRegistrar { @@ -324,6 +304,7 @@ impl TypeRegistrar { query_name: &Span, module_info: &ModuleInfo, ) -> Result<&Rc, Error> { + self.dependency_analysis.analyse(ty); fn custom(ty: &Type, is_copy: bool, is_params: bool) -> CornucopiaType { let rust_ty_name = ty.name().to_upper_camel_case(); CornucopiaType::Custom { @@ -449,6 +430,8 @@ impl std::ops::Index<&Type> for TypeRegistrar { } pub(crate) mod error { + use std::sync::Arc; + use miette::{Diagnostic, NamedSource, SourceSpan}; use thiserror::Error as ThisError; @@ -458,7 +441,7 @@ pub(crate) mod error { Db(#[from] postgres::Error), UnsupportedPostgresType { #[source_code] - src: NamedSource, + src: NamedSource>, #[label("this query contains an unsupported type (name: {col_name}, type: {col_ty})")] query: SourceSpan, col_name: String, diff --git a/crates/cornucopia/src/validation.rs b/crates/cornucopia/src/validation.rs index 9090e96a..3d09b090 100644 --- a/crates/cornucopia/src/validation.rs +++ b/crates/cornucopia/src/validation.rs @@ -355,7 +355,7 @@ pub(crate) fn validate_module( } pub mod error { - use std::fmt::Debug; + use std::{fmt::Debug, sync::Arc}; use miette::{Diagnostic, NamedSource, SourceSpan}; use thiserror::Error as ThisError; @@ -366,7 +366,7 @@ pub mod error { #[diagnostic(help("disambiguate column names in your SQL using an `AS` clause"))] DuplicateSqlColName { #[source_code] - src: NamedSource, + src: NamedSource>, name: String, #[label("query returns one or more columns with the same name")] pos: SourceSpan, @@ -375,7 +375,7 @@ pub mod error { #[diagnostic(help("remove one of the two declaration"))] DuplicateFieldNullity { #[source_code] - src: NamedSource, + src: NamedSource>, name: String, #[label("previous nullity declaration")] first: SourceSpan, @@ -386,7 +386,7 @@ pub mod error { #[diagnostic(help("use a different name for one of those"))] DuplicateType { #[source_code] - src: NamedSource, + src: NamedSource>, name: String, ty: &'static str, #[label("previous definition here")] @@ -398,7 +398,7 @@ pub mod error { #[diagnostic(help("declare an inline named type using `()`: {name}()"))] UnknownNamedType { #[source_code] - src: NamedSource, + src: NamedSource>, name: String, ty: &'static str, #[label("unknown named {ty}")] @@ -408,7 +408,7 @@ pub mod error { #[diagnostic(help("use one of those names: {known}"))] UnknownFieldName { #[source_code] - src: NamedSource, + src: NamedSource>, #[label("no field with this name was found")] pos: SourceSpan, known: String, @@ -417,7 +417,7 @@ pub mod error { #[diagnostic(help("use a different named type for each query"))] IncompatibleNamedType { #[source_code] - src: NamedSource, + src: NamedSource>, name: String, first_label: String, #[label("{first_label}")] @@ -430,7 +430,7 @@ pub mod error { #[diagnostic(help("remove row declaration"))] RowOnExecute { #[source_code] - src: NamedSource, + src: NamedSource>, name: String, #[label("row declared here")] row: SourceSpan, @@ -441,7 +441,7 @@ pub mod error { #[diagnostic(help("remove parameter declaration"))] ParamsOnSimpleQuery { #[source_code] - src: NamedSource, + src: NamedSource>, name: String, #[label("parameter declared here")] param: SourceSpan, @@ -452,7 +452,7 @@ pub mod error { #[diagnostic(help("use a different name for one of those"))] DuplicateName { #[source_code] - src: NamedSource, + src: NamedSource>, name: String, first_ty: &'static str, #[label("previous definition as {first_ty} here")] @@ -465,7 +465,7 @@ pub mod error { #[diagnostic(help("use a different name"))] TypeRustKeyword { #[source_code] - src: NamedSource, + src: NamedSource>, name: &'static str, #[label("reserved rust keyword")] pos: SourceSpan, @@ -474,7 +474,7 @@ pub mod error { #[diagnostic(help("use a different name"))] NameRustKeyword { #[source_code] - src: NamedSource, + src: NamedSource>, name: &'static str, ty: &'static str, #[label("from {ty} declared here")] diff --git a/examples/auto_build/Cargo.lock b/examples/auto_build/Cargo.lock new file mode 100644 index 00000000..018922eb --- /dev/null +++ b/examples/auto_build/Cargo.lock @@ -0,0 +1,1303 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +dependencies = [ + "memchr", +] + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "auto-build" +version = "0.1.0" +dependencies = [ + "cornucopia", + "cornucopia_async", + "deadpool-postgres", + "futures", + "postgres-types", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +dependencies = [ + "borsh-derive", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytecheck" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13fe11640a23eb24562225322cd3e452b93a3d4091d62fab69c70542fcd17d1f" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cornucopia" +version = "0.9.0" +dependencies = [ + "async-trait", + "deadpool-postgres", + "eui48", + "fallible-iterator", + "futures", + "postgres", + "postgres-protocol", + "postgres-types", + "rust_decimal", + "serde", + "serde_json", + "time", + "tokio", + "tokio-postgres", + "uuid", +] + +[[package]] +name = "cornucopia_async" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38063b8553edf452cccc674f07b3b5e3144a24712e46647bfc357040f25fdc12" +dependencies = [ + "async-trait", + "cornucopia_client_core", + "deadpool-postgres", + "tokio-postgres", +] + +[[package]] +name = "cornucopia_client_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a087271917ca54f32499539f3f44c8dc112ffea0f39f47d6cde075df8d2f18" +dependencies = [ + "fallible-iterator", + "postgres-protocol", + "postgres-types", +] + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deadpool" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "retain_mut", + "tokio", +] + +[[package]] +name = "deadpool-postgres" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a24a9d49deefe610b8b60c767a7412e9a931d79a89415cd2d2d71630ca8d7" +dependencies = [ + "deadpool", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1" +dependencies = [ + "tokio", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "eui48" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887418ac5e8d57c2e66e04bdc2fe15f9a5407be20b54a82c86bd0e368b709701" +dependencies = [ + "regex", + "rustc-serialize", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.45.0", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "postgres" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bed5017bc2ff49649c0075d0d7a9d676933c1292480c1d137776fb205b5cd18" +dependencies = [ + "bytes", + "fallible-iterator", + "futures-util", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "postgres-derive" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "070ffaa78859c779b19f9358ce035480479cf2619e968593ffbe72abcb6e0fcf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "postgres-protocol" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d" +dependencies = [ + "base64", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f028f05971fe20f512bcc679e2c10227e57809a3af86a7606304435bc8896cd6" +dependencies = [ + "bytes", + "eui48", + "fallible-iterator", + "postgres-derive", + "postgres-protocol", + "serde", + "serde_json", + "time", + "uuid", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +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.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + +[[package]] +name = "rend" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "retain_mut" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" + +[[package]] +name = "rkyv" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" +dependencies = [ + "bytecheck", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26bd36b60561ee1fb5ec2817f198b6fd09fa571c897a5e86d1487cfc2b096dfc" +dependencies = [ + "arrayvec", + "borsh", + "bytecheck", + "byteorder", + "bytes", + "num-traits", + "postgres", + "rand", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "serde" +version = "1.0.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d283f86695ae989d1e18440a943880967156325ba025f05049946bff47bcc2b" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +dependencies = [ + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.4.9", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "tokio-postgres" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures-channel", + "futures-util", + "log", + "parking_lot", + "percent-encoding", + "phf", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "socket2 0.5.2", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "uuid" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/examples/auto_build/Cargo.toml b/examples/auto_build/Cargo.toml index dc925e2c..51a997da 100644 --- a/examples/auto_build/Cargo.toml +++ b/examples/auto_build/Cargo.toml @@ -3,26 +3,13 @@ name = "auto-build" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -# Cornucopia async client -## If you're trying this example as a standalone crate, -## replace the path with the latest current version -cornucopia_async = { path = "../../crates/client_async" } - +# Cornucopia +codegen = { path = "auto_build_codegen", package = "auto_build_codegen" } # Async -tokio = { version = "1.24.2", features = ["full"] } -futures = "0.3.25" - +tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread"] } +futures = "0.3.28" # Postgres interaction -tokio-postgres = "0.7.7" -postgres-types = "0.2.4" -## Connection pooling -deadpool-postgres = "0.11.0" - -[build-dependencies] -# Cornucopia library to automatically -## If you're trying this example as a standalone crate, -## replace the path with the latest current version -cornucopia = { path = "../../crates/cornucopia" } +tokio-postgres = "0.7.8" +# Connection pooling +deadpool-postgres = "0.14.0" diff --git a/examples/auto_build/_build.rs b/examples/auto_build/_build.rs index 700b9bf9..94fbc461 100644 --- a/examples/auto_build/_build.rs +++ b/examples/auto_build/_build.rs @@ -7,7 +7,7 @@ use cornucopia::{CodegenSettings, Error}; fn main() -> Result<(), Error> { let queries_path = "queries"; let schema_file = "schema.sql"; - let destination = "src/cornucopia.rs"; + let destination = "auto_build_codegen"; let settings = CodegenSettings { is_async: true, derive_ser: false, @@ -15,10 +15,10 @@ fn main() -> Result<(), Error> { println!("cargo:rerun-if-changed={queries_path}"); println!("cargo:rerun-if-changed={schema_file}"); - cornucopia::generate_managed( + cornucopia::gen_managed( queries_path, &[schema_file], - Some(destination), + destination, false, settings, )?; diff --git a/examples/auto_build/auto_build_codegen/Cargo.toml b/examples/auto_build/auto_build_codegen/Cargo.toml new file mode 100644 index 00000000..02c00a50 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/Cargo.toml @@ -0,0 +1,29 @@ +# This file was generated with `cornucopia`. Do not modify +[package] +name = "auto_build_codegen" +version = "0.9.0" +edition = "2021" + +[features] +default = ["deadpool"] +deadpool = ["dep:deadpool-postgres"] + +[dependencies] +## Core dependencies +# Postgres types +postgres-types = { version = "0.2.6", features = ["derive"] } +# Postgres interaction +postgres-protocol = "0.6.6" +# Iterator utils required for working with `postgres_protocol::types::ArrayValues` +fallible-iterator = "0.2.0" + +## Async client dependencies +# Postgres async client +tokio-postgres = { version = "0.7.10", features = [] } +# Async utils +async-trait = "0.1.78" +futures = "0.3.30" + +## Async features dependencies +# Async connection pooling +deadpool-postgres = { version = "0.14.0", optional = true } diff --git a/examples/auto_build/auto_build_codegen/src/array_iterator.rs b/examples/auto_build/auto_build_codegen/src/array_iterator.rs new file mode 100644 index 00000000..429ac0d6 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/array_iterator.rs @@ -0,0 +1,59 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::utils::escape_domain; +use fallible_iterator::FallibleIterator; +use postgres_protocol::types::{array_from_sql, ArrayValues}; +use postgres_types::{FromSql, Kind, Type}; +use std::fmt::Debug; +use std::marker::PhantomData; +/// Iterator over the items in a PostgreSQL array. You only need this if you are +/// working with custom zero-cost type mapping of rows containing PostgreSQL arrays. +pub struct ArrayIterator<'a, T: FromSql<'a>> { + values: ArrayValues<'a>, + ty: Type, + _type: PhantomData, +} +impl<'a, T: FromSql<'a>> Debug for ArrayIterator<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ArrayIterator") + .field("values", &"[T]") + .field("ty", &self.ty) + .field("_type", &self._type) + .finish() + } +} +impl<'a, T: FromSql<'a>> Iterator for ArrayIterator<'a, T> { + type Item = T; + fn next(&mut self) -> Option { + self.values + .next() + .unwrap() + .map(|raw| T::from_sql_nullable(&self.ty, raw).unwrap()) + } +} +impl<'a, T: FromSql<'a>> FromSql<'a> for ArrayIterator<'a, T> { + fn from_sql( + ty: &Type, + raw: &'a [u8], + ) -> Result, Box> { + let member_type = match *escape_domain(ty).kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + let array = array_from_sql(raw)?; + if array.dimensions().count()? > 1 { + return Err("array contains too many dimensions".into()); + } + Ok(ArrayIterator { + ty: member_type.clone(), + values: array.values(), + _type: PhantomData, + }) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref inner) => T::accepts(escape_domain(inner)), + _ => false, + } + } +} diff --git a/examples/auto_build/auto_build_codegen/src/client.rs b/examples/auto_build/auto_build_codegen/src/client.rs new file mode 100644 index 00000000..7dd182ab --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/client.rs @@ -0,0 +1,2 @@ +pub(crate) mod async_; +pub use async_::*; diff --git a/examples/auto_build/auto_build_codegen/src/client/async_.rs b/examples/auto_build/auto_build_codegen/src/client/async_.rs new file mode 100644 index 00000000..a40fc681 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/client/async_.rs @@ -0,0 +1,37 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub use generic_client::GenericClient; +use tokio_postgres::{Error, Statement}; +#[cfg(feature = "deadpool")] +mod deadpool; +mod generic_client; +/// This trait allows you to bind parameters to a query using a single +/// struct, rather than passing each bind parameter as a function parameter. +pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a C, params: &'a P) -> O; +} +/// Cached statement +#[doc(hidden)] +pub struct Stmt { + query: &'static str, + cached: Option, +} +impl Stmt { + #[must_use] + pub fn new(query: &'static str) -> Self { + Self { + query, + cached: None, + } + } + pub async fn prepare<'a, C: GenericClient>( + &'a mut self, + client: &C, + ) -> Result<&'a Statement, Error> { + if self.cached.is_none() { + let stmt = client.prepare(self.query).await?; + self.cached = Some(stmt); + } + Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) + } +} diff --git a/examples/auto_build/auto_build_codegen/src/client/async_/deadpool.rs b/examples/auto_build/auto_build_codegen/src/client/async_/deadpool.rs new file mode 100644 index 00000000..641a31c1 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/client/async_/deadpool.rs @@ -0,0 +1,121 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::generic_client::GenericClient; +use async_trait::async_trait; +use deadpool_postgres::{ + Client as DeadpoolClient, ClientWrapper, Transaction as DeadpoolTransaction, +}; +use tokio_postgres::{ + types::BorrowToSql, Client as PgClient, Error, RowStream, Statement, ToStatement, + Transaction as PgTransaction, +}; +#[async_trait] +impl GenericClient for DeadpoolClient { + async fn prepare(&self, query: &str) -> Result { + ClientWrapper::prepare_cached(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + PgClient::query_raw(self, statement, params).await + } +} +#[async_trait] +impl GenericClient for DeadpoolTransaction<'_> { + async fn prepare(&self, query: &str) -> Result { + DeadpoolTransaction::prepare_cached(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + PgTransaction::query_raw(self, statement, params).await + } +} diff --git a/examples/auto_build/auto_build_codegen/src/client/async_/generic_client.rs b/examples/auto_build/auto_build_codegen/src/client/async_/generic_client.rs new file mode 100644 index 00000000..b1b6314a --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/client/async_/generic_client.rs @@ -0,0 +1,159 @@ +// This file was generated with `cornucopia`. Do not modify. + +use async_trait::async_trait; +use tokio_postgres::{ + types::BorrowToSql, Client, Error, RowStream, Statement, ToStatement, Transaction, +}; +/// Abstraction over multiple types of asynchronous clients. +/// This allows you to use tokio_postgres clients and transactions interchangeably. +/// +/// In addition, when the `deadpool` feature is enabled (default), this trait also +/// abstracts over deadpool clients and transactions +#[async_trait] +pub trait GenericClient: Send + Sync { + async fn prepare(&self, query: &str) -> Result; + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator; +} +#[async_trait] +impl GenericClient for Transaction<'_> { + async fn prepare(&self, query: &str) -> Result { + Transaction::prepare(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + Transaction::query_raw(self, statement, params).await + } +} +#[async_trait] +impl GenericClient for Client { + async fn prepare(&self, query: &str) -> Result { + Client::prepare(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + Client::query_raw(self, statement, params).await + } +} diff --git a/examples/auto_build/auto_build_codegen/src/domain.rs b/examples/auto_build/auto_build_codegen/src/domain.rs new file mode 100644 index 00000000..d0510159 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/domain.rs @@ -0,0 +1,92 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::{type_traits::ArraySql, utils::escape_domain}; +use postgres_protocol::types::{array_to_sql, ArrayDimension}; +use postgres_types::{private::BytesMut, IsNull, Kind, ToSql, Type}; +use std::{ + error::Error, + fmt::{Debug, Formatter}, +}; +pub struct Domain(pub T); +impl Debug for Domain { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("DomainWrapper").field(&self.0).finish() + } +} +impl ToSql for Domain { + fn to_sql(&self, ty: &Type, out: &mut BytesMut) -> Result> + where + Self: Sized, + { + postgres_types::ToSql::to_sql(&self.0, escape_domain(ty), out) + } + fn accepts(ty: &Type) -> bool + where + Self: Sized, + { + return T::accepts(escape_domain(ty)); + } + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +pub struct DomainArray<'a, T: ToSql + Sync, A: ArraySql>(pub &'a A); +impl<'a, T: ToSql + Sync, A: ArraySql> Debug for DomainArray<'a, T, A> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayDomain").field(&self.0).finish() + } +} +impl<'a, T: ToSql + Sync + 'a, A: ArraySql> ToSql for DomainArray<'a, T, A> { + fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { + self.0.escape_domain_to_sql(ty, w) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(escape_domain(member)), + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +pub fn escape_domain_to_sql( + ty: &Type, + w: &mut BytesMut, + iter: impl ExactSizeIterator, +) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match Domain(e).to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) +} +fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } +} diff --git a/examples/auto_build/auto_build_codegen/src/lib.rs b/examples/auto_build/auto_build_codegen/src/lib.rs new file mode 100644 index 00000000..996a9387 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/lib.rs @@ -0,0 +1,21 @@ +// This file was generated with `cornucopia`. Do not modify. + +mod array_iterator; +pub mod client; +mod domain; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod queries; +mod type_traits; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod types; +mod utils; +pub use array_iterator::ArrayIterator; +pub use domain::{Domain, DomainArray}; +pub use type_traits::{ArraySql, BytesSql, IterSql, StringSql}; +pub(crate) use utils::slice_iter; diff --git a/examples/auto_build/auto_build_codegen/src/queries.rs b/examples/auto_build/auto_build_codegen/src/queries.rs new file mode 100644 index 00000000..af7d99d7 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/queries.rs @@ -0,0 +1,3 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub mod module_1; diff --git a/examples/auto_build/auto_build_codegen/src/queries/module_1.rs b/examples/auto_build/auto_build_codegen/src/queries/module_1.rs new file mode 100644 index 00000000..15965b59 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/queries/module_1.rs @@ -0,0 +1,79 @@ +// This file was generated with `cornucopia`. Do not modify. + +use crate::client::async_::GenericClient; +use futures::{self, StreamExt, TryStreamExt}; +pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> &str, + mapper: fn(&str) -> T, +} +impl<'a, C, T: 'a, const N: usize> StringQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map(self, mapper: fn(&str) -> R) -> StringQuery<'a, C, R, N> { + StringQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } +} +pub fn example_query() -> ExampleQueryStmt { + ExampleQueryStmt(crate::client::async_::Stmt::new( + "SELECT + * +FROM + example_table", + )) +} +pub struct ExampleQueryStmt(crate::client::async_::Stmt); +impl ExampleQueryStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> StringQuery<'a, C, String, 0> { + StringQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } +} diff --git a/examples/auto_build/auto_build_codegen/src/type_traits.rs b/examples/auto_build/auto_build_codegen/src/type_traits.rs new file mode 100644 index 00000000..68727072 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/type_traits.rs @@ -0,0 +1,121 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::domain::escape_domain_to_sql; +use postgres_protocol::types::{self, ArrayDimension}; +use postgres_types::{private::BytesMut, to_sql_checked, IsNull, Kind, ToSql, Type}; +use std::borrow::Cow; +pub trait StringSql: std::fmt::Debug + ToSql + Sync {} +impl StringSql for &T {} +impl StringSql for String {} +impl StringSql for &str {} +impl StringSql for Cow<'_, str> {} +impl StringSql for Box {} +pub trait BytesSql: std::fmt::Debug + ToSql + Send + Sync {} +impl BytesSql for &T {} +impl BytesSql for Vec {} +impl BytesSql for &[u8] {} +pub trait ArraySql: std::fmt::Debug + ToSql + Send + Sync { + type Item; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result>; +} +impl> ArraySql for &A { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + A::escape_domain_to_sql(self, ty, w) + } +} +impl ArraySql for Vec { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } +} +impl ArraySql for &[T] { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } +} +impl< + T: std::fmt::Debug + ToSql + Send + Sync, + I: Iterator + ExactSizeIterator, + F: Fn() -> I + Send + Sync, + > ArraySql for IterSql +{ + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, (self.0)()) + } +} +pub struct IterSql + ExactSizeIterator, F: Fn() -> I + Sync>(pub F); +impl + ExactSizeIterator, F: Fn() -> I + Sync> std::fmt::Debug + for IterSql +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayFn").finish() + } +} +impl + ExactSizeIterator, F: Fn() -> I + Sync> ToSql + for IterSql +{ + fn to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => member, + _ => panic!("expected array type"), + }; + let iter = (self.0)(); + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + types::array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match e.to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(member), + _ => false, + } + } + to_sql_checked!(); +} +fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } +} diff --git a/examples/auto_build/auto_build_codegen/src/types.rs b/examples/auto_build/auto_build_codegen/src/types.rs new file mode 100644 index 00000000..f5372d93 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/types.rs @@ -0,0 +1 @@ +// This file was generated with `cornucopia`. Do not modify. diff --git a/examples/auto_build/auto_build_codegen/src/utils.rs b/examples/auto_build/auto_build_codegen/src/utils.rs new file mode 100644 index 00000000..fca59fa2 --- /dev/null +++ b/examples/auto_build/auto_build_codegen/src/utils.rs @@ -0,0 +1,14 @@ +// This file was generated with `cornucopia`. Do not modify. + +use postgres_types::{Kind, ToSql, Type}; +pub fn escape_domain(ty: &Type) -> &Type { + match ty.kind() { + Kind::Domain(ty) => ty, + _ => ty, + } +} +pub fn slice_iter<'a>( + s: &'a [&'a (dyn ToSql + Sync)], +) -> impl ExactSizeIterator + 'a { + s.iter().map(|s| *s as _) +} diff --git a/examples/auto_build/src/cornucopia.rs b/examples/auto_build/src/cornucopia.rs deleted file mode 100644 index 7645821c..00000000 --- a/examples/auto_build/src/cornucopia.rs +++ /dev/null @@ -1,93 +0,0 @@ -// This file was generated with `cornucopia`. Do not modify. - -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod types {} -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod queries { - pub mod module_1 { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> &str, - mapper: fn(&str) -> T, - } - impl<'a, C, T: 'a, const N: usize> StringQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(&str) -> R) -> StringQuery<'a, C, R, N> { - StringQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn example_query() -> ExampleQueryStmt { - ExampleQueryStmt(cornucopia_async::private::Stmt::new( - "SELECT - * -FROM - example_table", - )) - } - pub struct ExampleQueryStmt(cornucopia_async::private::Stmt); - impl ExampleQueryStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> StringQuery<'a, C, String, 0> { - StringQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - } -} diff --git a/examples/auto_build/src/main.rs b/examples/auto_build/src/main.rs index ae6e8ff4..8287437c 100644 --- a/examples/auto_build/src/main.rs +++ b/examples/auto_build/src/main.rs @@ -1,14 +1,9 @@ use deadpool_postgres::{Config, Runtime}; use tokio_postgres::NoTls; -// Take a look at the generated `cornucopia.rs` file if you want to +// Take a look at the generated `cornucopia` crate if you want to // see what it looks like under the hood. -use cornucopia::queries::module_1::example_query; - -// Since we generated the cornucopia file inside our project, you can simply -// import the modules as you usually would, but you could also use something -// like `include_str` if you wanted to. -mod cornucopia; +use codegen::queries::module_1::example_query; // Add more schema files and queries, rebuild the crate, // and observe how your cornucopia modules are regenerated! diff --git a/examples/basic_async/Cargo.lock b/examples/basic_async/Cargo.lock new file mode 100644 index 00000000..23b13343 --- /dev/null +++ b/examples/basic_async/Cargo.lock @@ -0,0 +1,1303 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +dependencies = [ + "memchr", +] + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "basic-async" +version = "0.1.0" +dependencies = [ + "cornucopia", + "cornucopia_async", + "deadpool-postgres", + "futures", + "postgres-types", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +dependencies = [ + "borsh-derive", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytecheck" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13fe11640a23eb24562225322cd3e452b93a3d4091d62fab69c70542fcd17d1f" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cornucopia" +version = "0.9.0" +dependencies = [ + "async-trait", + "deadpool-postgres", + "eui48", + "fallible-iterator", + "futures", + "postgres", + "postgres-protocol", + "postgres-types", + "rust_decimal", + "serde", + "serde_json", + "time", + "tokio", + "tokio-postgres", + "uuid", +] + +[[package]] +name = "cornucopia_async" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38063b8553edf452cccc674f07b3b5e3144a24712e46647bfc357040f25fdc12" +dependencies = [ + "async-trait", + "cornucopia_client_core", + "deadpool-postgres", + "tokio-postgres", +] + +[[package]] +name = "cornucopia_client_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a087271917ca54f32499539f3f44c8dc112ffea0f39f47d6cde075df8d2f18" +dependencies = [ + "fallible-iterator", + "postgres-protocol", + "postgres-types", +] + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deadpool" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "retain_mut", + "tokio", +] + +[[package]] +name = "deadpool-postgres" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a24a9d49deefe610b8b60c767a7412e9a931d79a89415cd2d2d71630ca8d7" +dependencies = [ + "deadpool", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1" +dependencies = [ + "tokio", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "eui48" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887418ac5e8d57c2e66e04bdc2fe15f9a5407be20b54a82c86bd0e368b709701" +dependencies = [ + "regex", + "rustc-serialize", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.45.0", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "postgres" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bed5017bc2ff49649c0075d0d7a9d676933c1292480c1d137776fb205b5cd18" +dependencies = [ + "bytes", + "fallible-iterator", + "futures-util", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "postgres-derive" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "070ffaa78859c779b19f9358ce035480479cf2619e968593ffbe72abcb6e0fcf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "postgres-protocol" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d" +dependencies = [ + "base64", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f028f05971fe20f512bcc679e2c10227e57809a3af86a7606304435bc8896cd6" +dependencies = [ + "bytes", + "eui48", + "fallible-iterator", + "postgres-derive", + "postgres-protocol", + "serde", + "serde_json", + "time", + "uuid", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +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.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + +[[package]] +name = "rend" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "retain_mut" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" + +[[package]] +name = "rkyv" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" +dependencies = [ + "bytecheck", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26bd36b60561ee1fb5ec2817f198b6fd09fa571c897a5e86d1487cfc2b096dfc" +dependencies = [ + "arrayvec", + "borsh", + "bytecheck", + "byteorder", + "bytes", + "num-traits", + "postgres", + "rand", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "serde" +version = "1.0.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d283f86695ae989d1e18440a943880967156325ba025f05049946bff47bcc2b" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +dependencies = [ + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.4.9", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "tokio-postgres" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures-channel", + "futures-util", + "log", + "parking_lot", + "percent-encoding", + "phf", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "socket2 0.5.2", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "uuid" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/examples/basic_async/Cargo.toml b/examples/basic_async/Cargo.toml index ed6463d9..9564589e 100644 --- a/examples/basic_async/Cargo.toml +++ b/examples/basic_async/Cargo.toml @@ -4,17 +4,12 @@ name = "basic-async" version = "0.1.0" [dependencies] -# Cornucopia async client -## If you're trying this example as a standalone crate, -## replace the path with the latest current version -cornucopia_async = { path = "../../crates/client_async" } - +# Cornucopia +codegen = { path = "basic_async_codegen", package = "basic_async_codegen" } # Async -tokio = { version = "1.24.2", features = ["full"] } -futures = "0.3.25" - +tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread"] } +futures = "0.3.28" # Postgres interaction tokio-postgres = "0.7.7" -postgres-types = { version = "0.2.4", features = ["derive"] } ## Connection pooling -deadpool-postgres = "0.11.0" +deadpool-postgres = "0.14.0" diff --git a/examples/basic_async/basic_async_codegen/Cargo.toml b/examples/basic_async/basic_async_codegen/Cargo.toml new file mode 100644 index 00000000..417bedab --- /dev/null +++ b/examples/basic_async/basic_async_codegen/Cargo.toml @@ -0,0 +1,29 @@ +# This file was generated with `cornucopia`. Do not modify +[package] +name = "basic_async_codegen" +version = "0.9.0" +edition = "2021" + +[features] +default = ["deadpool"] +deadpool = ["dep:deadpool-postgres"] + +[dependencies] +## Core dependencies +# Postgres types +postgres-types = { version = "0.2.6", features = ["derive"] } +# Postgres interaction +postgres-protocol = "0.6.6" +# Iterator utils required for working with `postgres_protocol::types::ArrayValues` +fallible-iterator = "0.2.0" + +## Async client dependencies +# Postgres async client +tokio-postgres = { version = "0.7.10", features = [] } +# Async utils +async-trait = "0.1.78" +futures = "0.3.30" + +## Async features dependencies +# Async connection pooling +deadpool-postgres = { version = "0.14.0", optional = true } diff --git a/examples/basic_async/basic_async_codegen/src/array_iterator.rs b/examples/basic_async/basic_async_codegen/src/array_iterator.rs new file mode 100644 index 00000000..429ac0d6 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/array_iterator.rs @@ -0,0 +1,59 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::utils::escape_domain; +use fallible_iterator::FallibleIterator; +use postgres_protocol::types::{array_from_sql, ArrayValues}; +use postgres_types::{FromSql, Kind, Type}; +use std::fmt::Debug; +use std::marker::PhantomData; +/// Iterator over the items in a PostgreSQL array. You only need this if you are +/// working with custom zero-cost type mapping of rows containing PostgreSQL arrays. +pub struct ArrayIterator<'a, T: FromSql<'a>> { + values: ArrayValues<'a>, + ty: Type, + _type: PhantomData, +} +impl<'a, T: FromSql<'a>> Debug for ArrayIterator<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ArrayIterator") + .field("values", &"[T]") + .field("ty", &self.ty) + .field("_type", &self._type) + .finish() + } +} +impl<'a, T: FromSql<'a>> Iterator for ArrayIterator<'a, T> { + type Item = T; + fn next(&mut self) -> Option { + self.values + .next() + .unwrap() + .map(|raw| T::from_sql_nullable(&self.ty, raw).unwrap()) + } +} +impl<'a, T: FromSql<'a>> FromSql<'a> for ArrayIterator<'a, T> { + fn from_sql( + ty: &Type, + raw: &'a [u8], + ) -> Result, Box> { + let member_type = match *escape_domain(ty).kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + let array = array_from_sql(raw)?; + if array.dimensions().count()? > 1 { + return Err("array contains too many dimensions".into()); + } + Ok(ArrayIterator { + ty: member_type.clone(), + values: array.values(), + _type: PhantomData, + }) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref inner) => T::accepts(escape_domain(inner)), + _ => false, + } + } +} diff --git a/examples/basic_async/basic_async_codegen/src/client.rs b/examples/basic_async/basic_async_codegen/src/client.rs new file mode 100644 index 00000000..7dd182ab --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/client.rs @@ -0,0 +1,2 @@ +pub(crate) mod async_; +pub use async_::*; diff --git a/examples/basic_async/basic_async_codegen/src/client/async_.rs b/examples/basic_async/basic_async_codegen/src/client/async_.rs new file mode 100644 index 00000000..a40fc681 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/client/async_.rs @@ -0,0 +1,37 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub use generic_client::GenericClient; +use tokio_postgres::{Error, Statement}; +#[cfg(feature = "deadpool")] +mod deadpool; +mod generic_client; +/// This trait allows you to bind parameters to a query using a single +/// struct, rather than passing each bind parameter as a function parameter. +pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a C, params: &'a P) -> O; +} +/// Cached statement +#[doc(hidden)] +pub struct Stmt { + query: &'static str, + cached: Option, +} +impl Stmt { + #[must_use] + pub fn new(query: &'static str) -> Self { + Self { + query, + cached: None, + } + } + pub async fn prepare<'a, C: GenericClient>( + &'a mut self, + client: &C, + ) -> Result<&'a Statement, Error> { + if self.cached.is_none() { + let stmt = client.prepare(self.query).await?; + self.cached = Some(stmt); + } + Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) + } +} diff --git a/examples/basic_async/basic_async_codegen/src/client/async_/deadpool.rs b/examples/basic_async/basic_async_codegen/src/client/async_/deadpool.rs new file mode 100644 index 00000000..641a31c1 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/client/async_/deadpool.rs @@ -0,0 +1,121 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::generic_client::GenericClient; +use async_trait::async_trait; +use deadpool_postgres::{ + Client as DeadpoolClient, ClientWrapper, Transaction as DeadpoolTransaction, +}; +use tokio_postgres::{ + types::BorrowToSql, Client as PgClient, Error, RowStream, Statement, ToStatement, + Transaction as PgTransaction, +}; +#[async_trait] +impl GenericClient for DeadpoolClient { + async fn prepare(&self, query: &str) -> Result { + ClientWrapper::prepare_cached(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + PgClient::query_raw(self, statement, params).await + } +} +#[async_trait] +impl GenericClient for DeadpoolTransaction<'_> { + async fn prepare(&self, query: &str) -> Result { + DeadpoolTransaction::prepare_cached(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + PgTransaction::query_raw(self, statement, params).await + } +} diff --git a/examples/basic_async/basic_async_codegen/src/client/async_/generic_client.rs b/examples/basic_async/basic_async_codegen/src/client/async_/generic_client.rs new file mode 100644 index 00000000..b1b6314a --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/client/async_/generic_client.rs @@ -0,0 +1,159 @@ +// This file was generated with `cornucopia`. Do not modify. + +use async_trait::async_trait; +use tokio_postgres::{ + types::BorrowToSql, Client, Error, RowStream, Statement, ToStatement, Transaction, +}; +/// Abstraction over multiple types of asynchronous clients. +/// This allows you to use tokio_postgres clients and transactions interchangeably. +/// +/// In addition, when the `deadpool` feature is enabled (default), this trait also +/// abstracts over deadpool clients and transactions +#[async_trait] +pub trait GenericClient: Send + Sync { + async fn prepare(&self, query: &str) -> Result; + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator; +} +#[async_trait] +impl GenericClient for Transaction<'_> { + async fn prepare(&self, query: &str) -> Result { + Transaction::prepare(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + Transaction::query_raw(self, statement, params).await + } +} +#[async_trait] +impl GenericClient for Client { + async fn prepare(&self, query: &str) -> Result { + Client::prepare(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + Client::query_raw(self, statement, params).await + } +} diff --git a/examples/basic_async/basic_async_codegen/src/domain.rs b/examples/basic_async/basic_async_codegen/src/domain.rs new file mode 100644 index 00000000..d0510159 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/domain.rs @@ -0,0 +1,92 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::{type_traits::ArraySql, utils::escape_domain}; +use postgres_protocol::types::{array_to_sql, ArrayDimension}; +use postgres_types::{private::BytesMut, IsNull, Kind, ToSql, Type}; +use std::{ + error::Error, + fmt::{Debug, Formatter}, +}; +pub struct Domain(pub T); +impl Debug for Domain { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("DomainWrapper").field(&self.0).finish() + } +} +impl ToSql for Domain { + fn to_sql(&self, ty: &Type, out: &mut BytesMut) -> Result> + where + Self: Sized, + { + postgres_types::ToSql::to_sql(&self.0, escape_domain(ty), out) + } + fn accepts(ty: &Type) -> bool + where + Self: Sized, + { + return T::accepts(escape_domain(ty)); + } + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +pub struct DomainArray<'a, T: ToSql + Sync, A: ArraySql>(pub &'a A); +impl<'a, T: ToSql + Sync, A: ArraySql> Debug for DomainArray<'a, T, A> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayDomain").field(&self.0).finish() + } +} +impl<'a, T: ToSql + Sync + 'a, A: ArraySql> ToSql for DomainArray<'a, T, A> { + fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { + self.0.escape_domain_to_sql(ty, w) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(escape_domain(member)), + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +pub fn escape_domain_to_sql( + ty: &Type, + w: &mut BytesMut, + iter: impl ExactSizeIterator, +) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match Domain(e).to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) +} +fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } +} diff --git a/examples/basic_async/basic_async_codegen/src/lib.rs b/examples/basic_async/basic_async_codegen/src/lib.rs new file mode 100644 index 00000000..996a9387 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/lib.rs @@ -0,0 +1,21 @@ +// This file was generated with `cornucopia`. Do not modify. + +mod array_iterator; +pub mod client; +mod domain; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod queries; +mod type_traits; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod types; +mod utils; +pub use array_iterator::ArrayIterator; +pub use domain::{Domain, DomainArray}; +pub use type_traits::{ArraySql, BytesSql, IterSql, StringSql}; +pub(crate) use utils::slice_iter; diff --git a/examples/basic_async/basic_async_codegen/src/queries.rs b/examples/basic_async/basic_async_codegen/src/queries.rs new file mode 100644 index 00000000..ae189bec --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/queries.rs @@ -0,0 +1,4 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub mod module_1; +pub mod module_2; diff --git a/examples/basic_async/basic_async_codegen/src/queries/module_1.rs b/examples/basic_async/basic_async_codegen/src/queries/module_1.rs new file mode 100644 index 00000000..aec38a10 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/queries/module_1.rs @@ -0,0 +1,21 @@ +// This file was generated with `cornucopia`. Do not modify. + +use crate::client::async_::GenericClient; +use futures::{self, StreamExt, TryStreamExt}; +pub fn insert_book() -> InsertBookStmt { + InsertBookStmt(crate::client::async_::Stmt::new( + "INSERT INTO Book (title) + VALUES ($1)", + )) +} +pub struct InsertBookStmt(crate::client::async_::Stmt); +impl InsertBookStmt { + pub async fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + title: &'a T1, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[title]).await + } +} diff --git a/examples/basic_async/basic_async_codegen/src/queries/module_2.rs b/examples/basic_async/basic_async_codegen/src/queries/module_2.rs new file mode 100644 index 00000000..880b9aa9 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/queries/module_2.rs @@ -0,0 +1,530 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct AuthorNameStartingWithParams { + pub start_str: T1, +} +#[derive(Debug, Clone, PartialEq)] +pub struct Authors { + pub id: i32, + pub name: String, + pub country: String, +} +pub struct AuthorsBorrowed<'a> { + pub id: i32, + pub name: &'a str, + pub country: &'a str, +} +impl<'a> From> for Authors { + fn from(AuthorsBorrowed { id, name, country }: AuthorsBorrowed<'a>) -> Self { + Self { + id, + name: name.into(), + country: country.into(), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub struct AuthorNameStartingWith { + pub authorid: i32, + pub name: String, + pub bookid: i32, + pub title: String, +} +pub struct AuthorNameStartingWithBorrowed<'a> { + pub authorid: i32, + pub name: &'a str, + pub bookid: i32, + pub title: &'a str, +} +impl<'a> From> for AuthorNameStartingWith { + fn from( + AuthorNameStartingWithBorrowed { + authorid, + name, + bookid, + title, + }: AuthorNameStartingWithBorrowed<'a>, + ) -> Self { + Self { + authorid, + name: name.into(), + bookid, + title: title.into(), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub struct SelectTranslations { + pub title: String, + pub translations: Vec, +} +pub struct SelectTranslationsBorrowed<'a> { + pub title: &'a str, + pub translations: crate::ArrayIterator<'a, &'a str>, +} +impl<'a> From> for SelectTranslations { + fn from( + SelectTranslationsBorrowed { + title, + translations, + }: SelectTranslationsBorrowed<'a>, + ) -> Self { + Self { + title: title.into(), + translations: translations.map(|v| v.into()).collect(), + } + } +} +use crate::client::async_::GenericClient; +use futures::{self, StreamExt, TryStreamExt}; +pub struct AuthorsQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> AuthorsBorrowed, + mapper: fn(AuthorsBorrowed) -> T, +} +impl<'a, C, T: 'a, const N: usize> AuthorsQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map(self, mapper: fn(AuthorsBorrowed) -> R) -> AuthorsQuery<'a, C, R, N> { + AuthorsQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } +} +pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> &str, + mapper: fn(&str) -> T, +} +impl<'a, C, T: 'a, const N: usize> StringQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map(self, mapper: fn(&str) -> R) -> StringQuery<'a, C, R, N> { + StringQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } +} +pub struct AuthorNameStartingWithQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> AuthorNameStartingWithBorrowed, + mapper: fn(AuthorNameStartingWithBorrowed) -> T, +} +impl<'a, C, T: 'a, const N: usize> AuthorNameStartingWithQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map( + self, + mapper: fn(AuthorNameStartingWithBorrowed) -> R, + ) -> AuthorNameStartingWithQuery<'a, C, R, N> { + AuthorNameStartingWithQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } +} +pub struct VoiceactorQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> crate::types::VoiceactorBorrowed, + mapper: fn(crate::types::VoiceactorBorrowed) -> T, +} +impl<'a, C, T: 'a, const N: usize> VoiceactorQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map( + self, + mapper: fn(crate::types::VoiceactorBorrowed) -> R, + ) -> VoiceactorQuery<'a, C, R, N> { + VoiceactorQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } +} +pub struct SelectTranslationsQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> SelectTranslationsBorrowed, + mapper: fn(SelectTranslationsBorrowed) -> T, +} +impl<'a, C, T: 'a, const N: usize> SelectTranslationsQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map( + self, + mapper: fn(SelectTranslationsBorrowed) -> R, + ) -> SelectTranslationsQuery<'a, C, R, N> { + SelectTranslationsQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } +} +pub fn authors() -> AuthorsStmt { + AuthorsStmt(crate::client::async_::Stmt::new( + "SELECT + * +FROM + Author", + )) +} +pub struct AuthorsStmt(crate::client::async_::Stmt); +impl AuthorsStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> AuthorsQuery<'a, C, Authors, 0> { + AuthorsQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| AuthorsBorrowed { + id: row.get(0), + name: row.get(1), + country: row.get(2), + }, + mapper: |it| ::from(it), + } + } +} +pub fn books() -> BooksStmt { + BooksStmt(crate::client::async_::Stmt::new( + "SELECT + Title +FROM + Book", + )) +} +pub struct BooksStmt(crate::client::async_::Stmt); +impl BooksStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> StringQuery<'a, C, String, 0> { + StringQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } +} +pub fn author_name_by_id() -> AuthorNameByIdStmt { + AuthorNameByIdStmt(crate::client::async_::Stmt::new( + "SELECT + Author.Name +FROM + Author +WHERE + Author.Id = $1", + )) +} +pub struct AuthorNameByIdStmt(crate::client::async_::Stmt); +impl AuthorNameByIdStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + id: &'a i32, + ) -> StringQuery<'a, C, String, 1> { + StringQuery { + client, + params: [id], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } +} +pub fn author_name_starting_with() -> AuthorNameStartingWithStmt { + AuthorNameStartingWithStmt(crate::client::async_::Stmt::new( + "SELECT + BookAuthor.AuthorId, + Author.Name, + BookAuthor.BookId, + Book.Title +FROM + BookAuthor + INNER JOIN Author ON Author.id = BookAuthor.AuthorId + INNER JOIN Book ON Book.Id = BookAuthor.BookId +WHERE + Author.Name LIKE CONCAT($1::text, '%')", + )) +} +pub struct AuthorNameStartingWithStmt(crate::client::async_::Stmt); +impl AuthorNameStartingWithStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + start_str: &'a T1, + ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { + AuthorNameStartingWithQuery { + client, + params: [start_str], + stmt: &mut self.0, + extractor: |row| AuthorNameStartingWithBorrowed { + authorid: row.get(0), + name: row.get(1), + bookid: row.get(2), + title: row.get(3), + }, + mapper: |it| ::from(it), + } + } +} +impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::async_::Params< + 'a, + AuthorNameStartingWithParams, + AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1>, + C, + > for AuthorNameStartingWithStmt +{ + fn params( + &'a mut self, + client: &'a C, + params: &'a AuthorNameStartingWithParams, + ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { + self.bind(client, ¶ms.start_str) + } +} +pub fn select_voice_actor_with_character() -> SelectVoiceActorWithCharacterStmt { + SelectVoiceActorWithCharacterStmt(crate::client::async_::Stmt::new( + "SELECT + voice_actor +FROM + SpongeBobVoiceActor +WHERE + character = $1", + )) +} +pub struct SelectVoiceActorWithCharacterStmt(crate::client::async_::Stmt); +impl SelectVoiceActorWithCharacterStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + spongebob_character: &'a crate::types::SpongeBobCharacter, + ) -> VoiceactorQuery<'a, C, crate::types::Voiceactor, 1> { + VoiceactorQuery { + client, + params: [spongebob_character], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } +} +pub fn select_translations() -> SelectTranslationsStmt { + SelectTranslationsStmt(crate::client::async_::Stmt::new( + "SELECT + Title, + Translations +FROM + Book", + )) +} +pub struct SelectTranslationsStmt(crate::client::async_::Stmt); +impl SelectTranslationsStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> SelectTranslationsQuery<'a, C, SelectTranslations, 0> { + SelectTranslationsQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| SelectTranslationsBorrowed { + title: row.get(0), + translations: row.get(1), + }, + mapper: |it| ::from(it), + } + } +} diff --git a/examples/basic_async/basic_async_codegen/src/type_traits.rs b/examples/basic_async/basic_async_codegen/src/type_traits.rs new file mode 100644 index 00000000..68727072 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/type_traits.rs @@ -0,0 +1,121 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::domain::escape_domain_to_sql; +use postgres_protocol::types::{self, ArrayDimension}; +use postgres_types::{private::BytesMut, to_sql_checked, IsNull, Kind, ToSql, Type}; +use std::borrow::Cow; +pub trait StringSql: std::fmt::Debug + ToSql + Sync {} +impl StringSql for &T {} +impl StringSql for String {} +impl StringSql for &str {} +impl StringSql for Cow<'_, str> {} +impl StringSql for Box {} +pub trait BytesSql: std::fmt::Debug + ToSql + Send + Sync {} +impl BytesSql for &T {} +impl BytesSql for Vec {} +impl BytesSql for &[u8] {} +pub trait ArraySql: std::fmt::Debug + ToSql + Send + Sync { + type Item; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result>; +} +impl> ArraySql for &A { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + A::escape_domain_to_sql(self, ty, w) + } +} +impl ArraySql for Vec { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } +} +impl ArraySql for &[T] { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } +} +impl< + T: std::fmt::Debug + ToSql + Send + Sync, + I: Iterator + ExactSizeIterator, + F: Fn() -> I + Send + Sync, + > ArraySql for IterSql +{ + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, (self.0)()) + } +} +pub struct IterSql + ExactSizeIterator, F: Fn() -> I + Sync>(pub F); +impl + ExactSizeIterator, F: Fn() -> I + Sync> std::fmt::Debug + for IterSql +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayFn").finish() + } +} +impl + ExactSizeIterator, F: Fn() -> I + Sync> ToSql + for IterSql +{ + fn to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => member, + _ => panic!("expected array type"), + }; + let iter = (self.0)(); + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + types::array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match e.to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(member), + _ => false, + } + } + to_sql_checked!(); +} +fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } +} diff --git a/examples/basic_async/basic_async_codegen/src/types.rs b/examples/basic_async/basic_async_codegen/src/types.rs new file mode 100644 index 00000000..a7c944f1 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/types.rs @@ -0,0 +1,192 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[allow(non_camel_case_types)] +pub enum SpongeBobCharacter { + Bob, + Patrick, + Squidward, +} +impl<'a> postgres_types::ToSql for SpongeBobCharacter { + fn to_sql( + &self, + ty: &postgres_types::Type, + buf: &mut postgres_types::private::BytesMut, + ) -> Result> { + let s = match *self { + SpongeBobCharacter::Bob => "Bob", + SpongeBobCharacter::Patrick => "Patrick", + SpongeBobCharacter::Squidward => "Squidward", + }; + buf.extend_from_slice(s.as_bytes()); + std::result::Result::Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "sponge_bob_character" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 3 { + return false; + } + variants.iter().all(|v| match &**v { + "Bob" => true, + "Patrick" => true, + "Squidward" => true, + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +impl<'a> postgres_types::FromSql<'a> for SpongeBobCharacter { + fn from_sql( + ty: &postgres_types::Type, + buf: &'a [u8], + ) -> Result> { + match std::str::from_utf8(buf)? { + "Bob" => Ok(SpongeBobCharacter::Bob), + "Patrick" => Ok(SpongeBobCharacter::Patrick), + "Squidward" => Ok(SpongeBobCharacter::Squidward), + s => Result::Err(Into::into(format!("invalid variant `{}`", s))), + } + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "sponge_bob_character" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 3 { + return false; + } + variants.iter().all(|v| match &**v { + "Bob" => true, + "Patrick" => true, + "Squidward" => true, + _ => false, + }) + } + _ => false, + } + } +} +#[derive(Debug, postgres_types::FromSql, Clone, PartialEq)] +#[postgres(name = "voiceactor")] +pub struct Voiceactor { + #[postgres(name = "name")] + pub name: String, + #[postgres(name = "age")] + pub age: i32, +} +#[derive(Debug)] +pub struct VoiceactorBorrowed<'a> { + pub name: &'a str, + pub age: i32, +} +impl<'a> From> for Voiceactor { + fn from(VoiceactorBorrowed { name, age }: VoiceactorBorrowed<'a>) -> Self { + Self { + name: name.into(), + age, + } + } +} +impl<'a> postgres_types::FromSql<'a> for VoiceactorBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let name = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let age = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + Ok(VoiceactorBorrowed { name, age }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "voiceactor" && ty.schema() == "public" + } +} +impl<'a> postgres_types::ToSql for VoiceactorBorrowed<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let VoiceactorBorrowed { name, age } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "name" => postgres_types::ToSql::to_sql(name, field.type_(), out), + "age" => postgres_types::ToSql::to_sql(age, field.type_(), out), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "voiceactor" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 2 { + return false; + } + fields.iter().all(|f| match f.name() { + "name" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), + "age" => ::accepts(f.type_()), + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} diff --git a/examples/basic_async/basic_async_codegen/src/utils.rs b/examples/basic_async/basic_async_codegen/src/utils.rs new file mode 100644 index 00000000..fca59fa2 --- /dev/null +++ b/examples/basic_async/basic_async_codegen/src/utils.rs @@ -0,0 +1,14 @@ +// This file was generated with `cornucopia`. Do not modify. + +use postgres_types::{Kind, ToSql, Type}; +pub fn escape_domain(ty: &Type) -> &Type { + match ty.kind() { + Kind::Domain(ty) => ty, + _ => ty, + } +} +pub fn slice_iter<'a>( + s: &'a [&'a (dyn ToSql + Sync)], +) -> impl ExactSizeIterator + 'a { + s.iter().map(|s| *s as _) +} diff --git a/examples/basic_async/src/cornucopia.rs b/examples/basic_async/src/cornucopia.rs deleted file mode 100644 index 36941dc5..00000000 --- a/examples/basic_async/src/cornucopia.rs +++ /dev/null @@ -1,765 +0,0 @@ -// This file was generated with `cornucopia`. Do not modify. - -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod types { - pub mod public { - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[allow(non_camel_case_types)] - pub enum SpongeBobCharacter { - Bob, - Patrick, - Squidward, - } - impl<'a> postgres_types::ToSql for SpongeBobCharacter { - fn to_sql( - &self, - ty: &postgres_types::Type, - buf: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let s = match *self { - SpongeBobCharacter::Bob => "Bob", - SpongeBobCharacter::Patrick => "Patrick", - SpongeBobCharacter::Squidward => "Squidward", - }; - buf.extend_from_slice(s.as_bytes()); - std::result::Result::Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "sponge_bob_character" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 3 { - return false; - } - variants.iter().all(|v| match &**v { - "Bob" => true, - "Patrick" => true, - "Squidward" => true, - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - impl<'a> postgres_types::FromSql<'a> for SpongeBobCharacter { - fn from_sql( - ty: &postgres_types::Type, - buf: &'a [u8], - ) -> Result> { - match std::str::from_utf8(buf)? { - "Bob" => Ok(SpongeBobCharacter::Bob), - "Patrick" => Ok(SpongeBobCharacter::Patrick), - "Squidward" => Ok(SpongeBobCharacter::Squidward), - s => Result::Err(Into::into(format!("invalid variant `{}`", s))), - } - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "sponge_bob_character" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 3 { - return false; - } - variants.iter().all(|v| match &**v { - "Bob" => true, - "Patrick" => true, - "Squidward" => true, - _ => false, - }) - } - _ => false, - } - } - } - #[derive(Debug, postgres_types :: FromSql, Clone, PartialEq)] - #[postgres(name = "voiceactor")] - pub struct Voiceactor { - #[postgres(name = "name")] - pub name: String, - #[postgres(name = "age")] - pub age: i32, - } - #[derive(Debug)] - pub struct VoiceactorBorrowed<'a> { - pub name: &'a str, - pub age: i32, - } - impl<'a> From> for Voiceactor { - fn from(VoiceactorBorrowed { name, age }: VoiceactorBorrowed<'a>) -> Self { - Self { - name: name.into(), - age, - } - } - } - impl<'a> postgres_types::FromSql<'a> for VoiceactorBorrowed<'a> { - fn from_sql( - ty: &postgres_types::Type, - out: &'a [u8], - ) -> Result, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err(std::convert::Into::into(format!( - "invalid field count: {} vs {}", - num_fields, - fields.len() - ))); - } - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let name = postgres_types::private::read_value(fields[0].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let age = postgres_types::private::read_value(fields[1].type_(), &mut out)?; - Ok(VoiceactorBorrowed { name, age }) - } - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "voiceactor" && ty.schema() == "public" - } - } - impl<'a> postgres_types::ToSql for VoiceactorBorrowed<'a> { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let VoiceactorBorrowed { name, age } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "name" => postgres_types::ToSql::to_sql(name, field.type_(), out), - "age" => postgres_types::ToSql::to_sql(age, field.type_(), out), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "voiceactor" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 2 { - return false; - } - fields.iter().all(|f| match f.name() { - "name" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), - "age" => ::accepts(f.type_()), - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - } -} -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod queries { - pub mod module_1 { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub fn insert_book() -> InsertBookStmt { - InsertBookStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO Book (title) - VALUES ($1)", - )) - } - pub struct InsertBookStmt(cornucopia_async::private::Stmt); - impl InsertBookStmt { - pub async fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - title: &'a T1, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[title]).await - } - } - } - pub mod module_2 { - #[derive(Debug)] - pub struct AuthorNameStartingWithParams { - pub start_str: T1, - } - #[derive(Debug, Clone, PartialEq)] - pub struct Authors { - pub id: i32, - pub name: String, - pub country: String, - } - pub struct AuthorsBorrowed<'a> { - pub id: i32, - pub name: &'a str, - pub country: &'a str, - } - impl<'a> From> for Authors { - fn from(AuthorsBorrowed { id, name, country }: AuthorsBorrowed<'a>) -> Self { - Self { - id, - name: name.into(), - country: country.into(), - } - } - } - #[derive(Debug, Clone, PartialEq)] - pub struct AuthorNameStartingWith { - pub authorid: i32, - pub name: String, - pub bookid: i32, - pub title: String, - } - pub struct AuthorNameStartingWithBorrowed<'a> { - pub authorid: i32, - pub name: &'a str, - pub bookid: i32, - pub title: &'a str, - } - impl<'a> From> for AuthorNameStartingWith { - fn from( - AuthorNameStartingWithBorrowed { - authorid, - name, - bookid, - title, - }: AuthorNameStartingWithBorrowed<'a>, - ) -> Self { - Self { - authorid, - name: name.into(), - bookid, - title: title.into(), - } - } - } - #[derive(Debug, Clone, PartialEq)] - pub struct SelectTranslations { - pub title: String, - pub translations: Vec, - } - pub struct SelectTranslationsBorrowed<'a> { - pub title: &'a str, - pub translations: cornucopia_async::ArrayIterator<'a, &'a str>, - } - impl<'a> From> for SelectTranslations { - fn from( - SelectTranslationsBorrowed { - title, - translations, - }: SelectTranslationsBorrowed<'a>, - ) -> Self { - Self { - title: title.into(), - translations: translations.map(|v| v.into()).collect(), - } - } - } - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct AuthorsQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> AuthorsBorrowed, - mapper: fn(AuthorsBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> AuthorsQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(AuthorsBorrowed) -> R) -> AuthorsQuery<'a, C, R, N> { - AuthorsQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> &str, - mapper: fn(&str) -> T, - } - impl<'a, C, T: 'a, const N: usize> StringQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(&str) -> R) -> StringQuery<'a, C, R, N> { - StringQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct AuthorNameStartingWithQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> AuthorNameStartingWithBorrowed, - mapper: fn(AuthorNameStartingWithBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> AuthorNameStartingWithQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(AuthorNameStartingWithBorrowed) -> R, - ) -> AuthorNameStartingWithQuery<'a, C, R, N> { - AuthorNameStartingWithQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct PublicVoiceactorQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::super::types::public::VoiceactorBorrowed, - mapper: fn(super::super::types::public::VoiceactorBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicVoiceactorQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::types::public::VoiceactorBorrowed) -> R, - ) -> PublicVoiceactorQuery<'a, C, R, N> { - PublicVoiceactorQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct SelectTranslationsQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> SelectTranslationsBorrowed, - mapper: fn(SelectTranslationsBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectTranslationsQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(SelectTranslationsBorrowed) -> R, - ) -> SelectTranslationsQuery<'a, C, R, N> { - SelectTranslationsQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn authors() -> AuthorsStmt { - AuthorsStmt(cornucopia_async::private::Stmt::new( - "SELECT - * -FROM - Author", - )) - } - pub struct AuthorsStmt(cornucopia_async::private::Stmt); - impl AuthorsStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> AuthorsQuery<'a, C, Authors, 0> { - AuthorsQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| AuthorsBorrowed { - id: row.get(0), - name: row.get(1), - country: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - pub fn books() -> BooksStmt { - BooksStmt(cornucopia_async::private::Stmt::new( - "SELECT - Title -FROM - Book", - )) - } - pub struct BooksStmt(cornucopia_async::private::Stmt); - impl BooksStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> StringQuery<'a, C, String, 0> { - StringQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn author_name_by_id() -> AuthorNameByIdStmt { - AuthorNameByIdStmt(cornucopia_async::private::Stmt::new( - "SELECT - Author.Name -FROM - Author -WHERE - Author.Id = $1", - )) - } - pub struct AuthorNameByIdStmt(cornucopia_async::private::Stmt); - impl AuthorNameByIdStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - id: &'a i32, - ) -> StringQuery<'a, C, String, 1> { - StringQuery { - client, - params: [id], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn author_name_starting_with() -> AuthorNameStartingWithStmt { - AuthorNameStartingWithStmt(cornucopia_async::private::Stmt::new( - "SELECT - BookAuthor.AuthorId, - Author.Name, - BookAuthor.BookId, - Book.Title -FROM - BookAuthor - INNER JOIN Author ON Author.id = BookAuthor.AuthorId - INNER JOIN Book ON Book.Id = BookAuthor.BookId -WHERE - Author.Name LIKE CONCAT($1::text, '%')", - )) - } - pub struct AuthorNameStartingWithStmt(cornucopia_async::private::Stmt); - impl AuthorNameStartingWithStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - start_str: &'a T1, - ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { - AuthorNameStartingWithQuery { - client, - params: [start_str], - stmt: &mut self.0, - extractor: |row| AuthorNameStartingWithBorrowed { - authorid: row.get(0), - name: row.get(1), - bookid: row.get(2), - title: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_async::StringSql> - cornucopia_async::Params< - 'a, - AuthorNameStartingWithParams, - AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1>, - C, - > for AuthorNameStartingWithStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a AuthorNameStartingWithParams, - ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { - self.bind(client, ¶ms.start_str) - } - } - pub fn select_voice_actor_with_character() -> SelectVoiceActorWithCharacterStmt { - SelectVoiceActorWithCharacterStmt(cornucopia_async::private::Stmt::new( - "SELECT - voice_actor -FROM - SpongeBobVoiceActor -WHERE - character = $1", - )) - } - pub struct SelectVoiceActorWithCharacterStmt(cornucopia_async::private::Stmt); - impl SelectVoiceActorWithCharacterStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - spongebob_character: &'a super::super::types::public::SpongeBobCharacter, - ) -> PublicVoiceactorQuery<'a, C, super::super::types::public::Voiceactor, 1> - { - PublicVoiceactorQuery { - client, - params: [spongebob_character], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn select_translations() -> SelectTranslationsStmt { - SelectTranslationsStmt(cornucopia_async::private::Stmt::new( - "SELECT - Title, - Translations -FROM - Book", - )) - } - pub struct SelectTranslationsStmt(cornucopia_async::private::Stmt); - impl SelectTranslationsStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> SelectTranslationsQuery<'a, C, SelectTranslations, 0> { - SelectTranslationsQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| SelectTranslationsBorrowed { - title: row.get(0), - translations: row.get(1), - }, - mapper: |it| ::from(it), - } - } - } - } -} diff --git a/examples/basic_async/src/main.rs b/examples/basic_async/src/main.rs index cd535ed8..b5bd6d1d 100644 --- a/examples/basic_async/src/main.rs +++ b/examples/basic_async/src/main.rs @@ -1,7 +1,7 @@ -// Take a look at the generated `cornucopia.rs` file if you want to +// Take a look at the generated `cornucopia` crate if you want to // see what it looks like under the hood. -mod cornucopia; -use crate::cornucopia::{ +use codegen::{ + client::Params, queries::{ module_1::insert_book, module_2::{ @@ -9,9 +9,8 @@ use crate::cornucopia::{ select_voice_actor_with_character, AuthorNameStartingWithParams, }, }, - types::public::SpongeBobCharacter, + types::SpongeBobCharacter, }; -use cornucopia_async::Params; #[tokio::main] pub async fn main() { diff --git a/examples/basic_sync/Cargo.lock b/examples/basic_sync/Cargo.lock new file mode 100644 index 00000000..7421b35b --- /dev/null +++ b/examples/basic_sync/Cargo.lock @@ -0,0 +1,1298 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +dependencies = [ + "memchr", +] + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "basic_sync" +version = "0.1.0" +dependencies = [ + "cornucopia", + "cornucopia_sync", + "postgres", + "postgres-types", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +dependencies = [ + "borsh-derive", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytecheck" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13fe11640a23eb24562225322cd3e452b93a3d4091d62fab69c70542fcd17d1f" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cornucopia" +version = "0.9.0" +dependencies = [ + "async-trait", + "deadpool-postgres", + "eui48", + "fallible-iterator", + "futures", + "postgres", + "postgres-protocol", + "postgres-types", + "rust_decimal", + "serde", + "serde_json", + "time", + "tokio", + "tokio-postgres", + "uuid", +] + +[[package]] +name = "cornucopia_client_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a087271917ca54f32499539f3f44c8dc112ffea0f39f47d6cde075df8d2f18" +dependencies = [ + "fallible-iterator", + "postgres-protocol", + "postgres-types", +] + +[[package]] +name = "cornucopia_sync" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da1c7fcaf2f8fcdd02341a1d6f8ee63d17bfc1629265a9b3115974519efbcb0e" +dependencies = [ + "cornucopia_client_core", + "postgres", +] + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deadpool" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "retain_mut", + "tokio", +] + +[[package]] +name = "deadpool-postgres" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a24a9d49deefe610b8b60c767a7412e9a931d79a89415cd2d2d71630ca8d7" +dependencies = [ + "deadpool", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1" +dependencies = [ + "tokio", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "eui48" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887418ac5e8d57c2e66e04bdc2fe15f9a5407be20b54a82c86bd0e368b709701" +dependencies = [ + "regex", + "rustc-serialize", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.45.0", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "postgres" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bed5017bc2ff49649c0075d0d7a9d676933c1292480c1d137776fb205b5cd18" +dependencies = [ + "bytes", + "fallible-iterator", + "futures-util", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "postgres-derive" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "070ffaa78859c779b19f9358ce035480479cf2619e968593ffbe72abcb6e0fcf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "postgres-protocol" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d" +dependencies = [ + "base64", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f028f05971fe20f512bcc679e2c10227e57809a3af86a7606304435bc8896cd6" +dependencies = [ + "bytes", + "eui48", + "fallible-iterator", + "postgres-derive", + "postgres-protocol", + "serde", + "serde_json", + "time", + "uuid", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +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.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + +[[package]] +name = "rend" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "retain_mut" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" + +[[package]] +name = "rkyv" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" +dependencies = [ + "bytecheck", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26bd36b60561ee1fb5ec2817f198b6fd09fa571c897a5e86d1487cfc2b096dfc" +dependencies = [ + "arrayvec", + "borsh", + "bytecheck", + "byteorder", + "bytes", + "num-traits", + "postgres", + "rand", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "serde" +version = "1.0.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d283f86695ae989d1e18440a943880967156325ba025f05049946bff47bcc2b" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +dependencies = [ + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.4.9", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "tokio-postgres" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures-channel", + "futures-util", + "log", + "parking_lot", + "percent-encoding", + "phf", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "socket2 0.5.2", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "uuid" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/examples/basic_sync/Cargo.toml b/examples/basic_sync/Cargo.toml index e6ab73c7..79337b5e 100644 --- a/examples/basic_sync/Cargo.toml +++ b/examples/basic_sync/Cargo.toml @@ -6,11 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +# Cornucopia +codegen = { path = "basic_sync_codegen", package = "basic_sync_codegen" } # Postgres interaction postgres = "0.19.4" -postgres-types = { version = "0.2.4", features = ["derive"] } -# Cornucopia async client -## If you're trying this example as a standalone crate, -## replace the path with the latest current version -cornucopia_sync = { path = "../../crates/client_sync" } diff --git a/examples/basic_sync/basic_sync_codegen/Cargo.toml b/examples/basic_sync/basic_sync_codegen/Cargo.toml new file mode 100644 index 00000000..344fe039 --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/Cargo.toml @@ -0,0 +1,18 @@ +# This file was generated with `cornucopia`. Do not modify +[package] +name = "basic_sync_codegen" +version = "0.9.0" +edition = "2021" + +[dependencies] +## Core dependencies +# Postgres types +postgres-types = { version = "0.2.6", features = ["derive"] } +# Postgres interaction +postgres-protocol = "0.6.6" +# Iterator utils required for working with `postgres_protocol::types::ArrayValues` +fallible-iterator = "0.2.0" + +## Sync client dependencies +# Postgres sync client +postgres = { version = "0.19.7", features = [] } diff --git a/examples/basic_sync/basic_sync_codegen/src/array_iterator.rs b/examples/basic_sync/basic_sync_codegen/src/array_iterator.rs new file mode 100644 index 00000000..429ac0d6 --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/array_iterator.rs @@ -0,0 +1,59 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::utils::escape_domain; +use fallible_iterator::FallibleIterator; +use postgres_protocol::types::{array_from_sql, ArrayValues}; +use postgres_types::{FromSql, Kind, Type}; +use std::fmt::Debug; +use std::marker::PhantomData; +/// Iterator over the items in a PostgreSQL array. You only need this if you are +/// working with custom zero-cost type mapping of rows containing PostgreSQL arrays. +pub struct ArrayIterator<'a, T: FromSql<'a>> { + values: ArrayValues<'a>, + ty: Type, + _type: PhantomData, +} +impl<'a, T: FromSql<'a>> Debug for ArrayIterator<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ArrayIterator") + .field("values", &"[T]") + .field("ty", &self.ty) + .field("_type", &self._type) + .finish() + } +} +impl<'a, T: FromSql<'a>> Iterator for ArrayIterator<'a, T> { + type Item = T; + fn next(&mut self) -> Option { + self.values + .next() + .unwrap() + .map(|raw| T::from_sql_nullable(&self.ty, raw).unwrap()) + } +} +impl<'a, T: FromSql<'a>> FromSql<'a> for ArrayIterator<'a, T> { + fn from_sql( + ty: &Type, + raw: &'a [u8], + ) -> Result, Box> { + let member_type = match *escape_domain(ty).kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + let array = array_from_sql(raw)?; + if array.dimensions().count()? > 1 { + return Err("array contains too many dimensions".into()); + } + Ok(ArrayIterator { + ty: member_type.clone(), + values: array.values(), + _type: PhantomData, + }) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref inner) => T::accepts(escape_domain(inner)), + _ => false, + } + } +} diff --git a/examples/basic_sync/basic_sync_codegen/src/client.rs b/examples/basic_sync/basic_sync_codegen/src/client.rs new file mode 100644 index 00000000..ad952c1f --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/client.rs @@ -0,0 +1,2 @@ +pub(crate) mod sync; +pub use sync::*; diff --git a/examples/basic_sync/basic_sync_codegen/src/client/sync.rs b/examples/basic_sync/basic_sync_codegen/src/client/sync.rs new file mode 100644 index 00000000..64188901 --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/client/sync.rs @@ -0,0 +1,33 @@ +// This file was generated with `cornucopia`. Do not modify. + +use postgres::Statement; +/// This trait allows you to bind parameters to a query using a single +/// struct, rather than passing each bind parameter as a function parameter. +pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a mut C, params: &'a P) -> O; +} +/// Cached statement +#[doc(hidden)] +pub(crate) struct Stmt { + query: &'static str, + cached: Option, +} +impl Stmt { + #[must_use] + pub fn new(query: &'static str) -> Self { + Self { + query, + cached: None, + } + } + pub fn prepare<'a, C: postgres::GenericClient>( + &'a mut self, + client: &mut C, + ) -> Result<&'a Statement, postgres::Error> { + if self.cached.is_none() { + let stmt = client.prepare(self.query)?; + self.cached = Some(stmt); + } + Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) + } +} diff --git a/examples/basic_sync/basic_sync_codegen/src/domain.rs b/examples/basic_sync/basic_sync_codegen/src/domain.rs new file mode 100644 index 00000000..d0510159 --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/domain.rs @@ -0,0 +1,92 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::{type_traits::ArraySql, utils::escape_domain}; +use postgres_protocol::types::{array_to_sql, ArrayDimension}; +use postgres_types::{private::BytesMut, IsNull, Kind, ToSql, Type}; +use std::{ + error::Error, + fmt::{Debug, Formatter}, +}; +pub struct Domain(pub T); +impl Debug for Domain { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("DomainWrapper").field(&self.0).finish() + } +} +impl ToSql for Domain { + fn to_sql(&self, ty: &Type, out: &mut BytesMut) -> Result> + where + Self: Sized, + { + postgres_types::ToSql::to_sql(&self.0, escape_domain(ty), out) + } + fn accepts(ty: &Type) -> bool + where + Self: Sized, + { + return T::accepts(escape_domain(ty)); + } + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +pub struct DomainArray<'a, T: ToSql + Sync, A: ArraySql>(pub &'a A); +impl<'a, T: ToSql + Sync, A: ArraySql> Debug for DomainArray<'a, T, A> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayDomain").field(&self.0).finish() + } +} +impl<'a, T: ToSql + Sync + 'a, A: ArraySql> ToSql for DomainArray<'a, T, A> { + fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { + self.0.escape_domain_to_sql(ty, w) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(escape_domain(member)), + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +pub fn escape_domain_to_sql( + ty: &Type, + w: &mut BytesMut, + iter: impl ExactSizeIterator, +) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match Domain(e).to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) +} +fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } +} diff --git a/examples/basic_sync/basic_sync_codegen/src/lib.rs b/examples/basic_sync/basic_sync_codegen/src/lib.rs new file mode 100644 index 00000000..996a9387 --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/lib.rs @@ -0,0 +1,21 @@ +// This file was generated with `cornucopia`. Do not modify. + +mod array_iterator; +pub mod client; +mod domain; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod queries; +mod type_traits; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod types; +mod utils; +pub use array_iterator::ArrayIterator; +pub use domain::{Domain, DomainArray}; +pub use type_traits::{ArraySql, BytesSql, IterSql, StringSql}; +pub(crate) use utils::slice_iter; diff --git a/examples/basic_sync/basic_sync_codegen/src/queries.rs b/examples/basic_sync/basic_sync_codegen/src/queries.rs new file mode 100644 index 00000000..ae189bec --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/queries.rs @@ -0,0 +1,4 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub mod module_1; +pub mod module_2; diff --git a/examples/basic_sync/basic_sync_codegen/src/queries/module_1.rs b/examples/basic_sync/basic_sync_codegen/src/queries/module_1.rs new file mode 100644 index 00000000..76e97c5e --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/queries/module_1.rs @@ -0,0 +1,20 @@ +// This file was generated with `cornucopia`. Do not modify. + +use postgres::{fallible_iterator::FallibleIterator, GenericClient}; +pub fn insert_book() -> InsertBookStmt { + InsertBookStmt(crate::client::sync::Stmt::new( + "INSERT INTO Book (title) + VALUES ($1)", + )) +} +pub struct InsertBookStmt(crate::client::sync::Stmt); +impl InsertBookStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + title: &'a T1, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[title]) + } +} diff --git a/examples/basic_sync/basic_sync_codegen/src/queries/module_2.rs b/examples/basic_sync/basic_sync_codegen/src/queries/module_2.rs new file mode 100644 index 00000000..64ecde2b --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/queries/module_2.rs @@ -0,0 +1,504 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct AuthorNameStartingWithParams { + pub start_str: T1, +} +#[derive(Debug, Clone, PartialEq)] +pub struct Authors { + pub id: i32, + pub name: String, + pub country: String, +} +pub struct AuthorsBorrowed<'a> { + pub id: i32, + pub name: &'a str, + pub country: &'a str, +} +impl<'a> From> for Authors { + fn from(AuthorsBorrowed { id, name, country }: AuthorsBorrowed<'a>) -> Self { + Self { + id, + name: name.into(), + country: country.into(), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub struct AuthorNameStartingWith { + pub authorid: i32, + pub name: String, + pub bookid: i32, + pub title: String, +} +pub struct AuthorNameStartingWithBorrowed<'a> { + pub authorid: i32, + pub name: &'a str, + pub bookid: i32, + pub title: &'a str, +} +impl<'a> From> for AuthorNameStartingWith { + fn from( + AuthorNameStartingWithBorrowed { + authorid, + name, + bookid, + title, + }: AuthorNameStartingWithBorrowed<'a>, + ) -> Self { + Self { + authorid, + name: name.into(), + bookid, + title: title.into(), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub struct SelectTranslations { + pub title: String, + pub translations: Vec, +} +pub struct SelectTranslationsBorrowed<'a> { + pub title: &'a str, + pub translations: crate::ArrayIterator<'a, &'a str>, +} +impl<'a> From> for SelectTranslations { + fn from( + SelectTranslationsBorrowed { + title, + translations, + }: SelectTranslationsBorrowed<'a>, + ) -> Self { + Self { + title: title.into(), + translations: translations.map(|v| v.into()).collect(), + } + } +} +use postgres::{fallible_iterator::FallibleIterator, GenericClient}; +pub struct AuthorsQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> AuthorsBorrowed, + mapper: fn(AuthorsBorrowed) -> T, +} +impl<'a, C, T: 'a, const N: usize> AuthorsQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map(self, mapper: fn(AuthorsBorrowed) -> R) -> AuthorsQuery<'a, C, R, N> { + AuthorsQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } +} +pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> &str, + mapper: fn(&str) -> T, +} +impl<'a, C, T: 'a, const N: usize> StringQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map(self, mapper: fn(&str) -> R) -> StringQuery<'a, C, R, N> { + StringQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } +} +pub struct AuthorNameStartingWithQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> AuthorNameStartingWithBorrowed, + mapper: fn(AuthorNameStartingWithBorrowed) -> T, +} +impl<'a, C, T: 'a, const N: usize> AuthorNameStartingWithQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map( + self, + mapper: fn(AuthorNameStartingWithBorrowed) -> R, + ) -> AuthorNameStartingWithQuery<'a, C, R, N> { + AuthorNameStartingWithQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } +} +pub struct VoiceactorQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> crate::types::VoiceactorBorrowed, + mapper: fn(crate::types::VoiceactorBorrowed) -> T, +} +impl<'a, C, T: 'a, const N: usize> VoiceactorQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map( + self, + mapper: fn(crate::types::VoiceactorBorrowed) -> R, + ) -> VoiceactorQuery<'a, C, R, N> { + VoiceactorQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } +} +pub struct SelectTranslationsQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> SelectTranslationsBorrowed, + mapper: fn(SelectTranslationsBorrowed) -> T, +} +impl<'a, C, T: 'a, const N: usize> SelectTranslationsQuery<'a, C, T, N> +where + C: GenericClient, +{ + pub fn map( + self, + mapper: fn(SelectTranslationsBorrowed) -> R, + ) -> SelectTranslationsQuery<'a, C, R, N> { + SelectTranslationsQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } +} +pub fn authors() -> AuthorsStmt { + AuthorsStmt(crate::client::sync::Stmt::new( + "SELECT + * +FROM + Author", + )) +} +pub struct AuthorsStmt(crate::client::sync::Stmt); +impl AuthorsStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> AuthorsQuery<'a, C, Authors, 0> { + AuthorsQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| AuthorsBorrowed { + id: row.get(0), + name: row.get(1), + country: row.get(2), + }, + mapper: |it| ::from(it), + } + } +} +pub fn books() -> BooksStmt { + BooksStmt(crate::client::sync::Stmt::new( + "SELECT + Title +FROM + Book", + )) +} +pub struct BooksStmt(crate::client::sync::Stmt); +impl BooksStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> StringQuery<'a, C, String, 0> { + StringQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } +} +pub fn author_name_by_id() -> AuthorNameByIdStmt { + AuthorNameByIdStmt(crate::client::sync::Stmt::new( + "SELECT + Author.Name +FROM + Author +WHERE + Author.Id = $1", + )) +} +pub struct AuthorNameByIdStmt(crate::client::sync::Stmt); +impl AuthorNameByIdStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + id: &'a i32, + ) -> StringQuery<'a, C, String, 1> { + StringQuery { + client, + params: [id], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } +} +pub fn author_name_starting_with() -> AuthorNameStartingWithStmt { + AuthorNameStartingWithStmt(crate::client::sync::Stmt::new( + "SELECT + BookAuthor.AuthorId, + Author.Name, + BookAuthor.BookId, + Book.Title +FROM + BookAuthor + INNER JOIN Author ON Author.id = BookAuthor.AuthorId + INNER JOIN Book ON Book.Id = BookAuthor.BookId +WHERE + Author.Name LIKE CONCAT($1::text, '%')", + )) +} +pub struct AuthorNameStartingWithStmt(crate::client::sync::Stmt); +impl AuthorNameStartingWithStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + start_str: &'a T1, + ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { + AuthorNameStartingWithQuery { + client, + params: [start_str], + stmt: &mut self.0, + extractor: |row| AuthorNameStartingWithBorrowed { + authorid: row.get(0), + name: row.get(1), + bookid: row.get(2), + title: row.get(3), + }, + mapper: |it| ::from(it), + } + } +} +impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::sync::Params< + 'a, + AuthorNameStartingWithParams, + AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1>, + C, + > for AuthorNameStartingWithStmt +{ + fn params( + &'a mut self, + client: &'a mut C, + params: &'a AuthorNameStartingWithParams, + ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { + self.bind(client, ¶ms.start_str) + } +} +pub fn select_voice_actor_with_character() -> SelectVoiceActorWithCharacterStmt { + SelectVoiceActorWithCharacterStmt(crate::client::sync::Stmt::new( + "SELECT + voice_actor +FROM + SpongeBobVoiceActor +WHERE + character = $1", + )) +} +pub struct SelectVoiceActorWithCharacterStmt(crate::client::sync::Stmt); +impl SelectVoiceActorWithCharacterStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + spongebob_character: &'a crate::types::SpongeBobCharacter, + ) -> VoiceactorQuery<'a, C, crate::types::Voiceactor, 1> { + VoiceactorQuery { + client, + params: [spongebob_character], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } +} +pub fn select_translations() -> SelectTranslationsStmt { + SelectTranslationsStmt(crate::client::sync::Stmt::new( + "SELECT + Title, + Translations +FROM + Book", + )) +} +pub struct SelectTranslationsStmt(crate::client::sync::Stmt); +impl SelectTranslationsStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> SelectTranslationsQuery<'a, C, SelectTranslations, 0> { + SelectTranslationsQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| SelectTranslationsBorrowed { + title: row.get(0), + translations: row.get(1), + }, + mapper: |it| ::from(it), + } + } +} diff --git a/examples/basic_sync/basic_sync_codegen/src/type_traits.rs b/examples/basic_sync/basic_sync_codegen/src/type_traits.rs new file mode 100644 index 00000000..68727072 --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/type_traits.rs @@ -0,0 +1,121 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::domain::escape_domain_to_sql; +use postgres_protocol::types::{self, ArrayDimension}; +use postgres_types::{private::BytesMut, to_sql_checked, IsNull, Kind, ToSql, Type}; +use std::borrow::Cow; +pub trait StringSql: std::fmt::Debug + ToSql + Sync {} +impl StringSql for &T {} +impl StringSql for String {} +impl StringSql for &str {} +impl StringSql for Cow<'_, str> {} +impl StringSql for Box {} +pub trait BytesSql: std::fmt::Debug + ToSql + Send + Sync {} +impl BytesSql for &T {} +impl BytesSql for Vec {} +impl BytesSql for &[u8] {} +pub trait ArraySql: std::fmt::Debug + ToSql + Send + Sync { + type Item; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result>; +} +impl> ArraySql for &A { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + A::escape_domain_to_sql(self, ty, w) + } +} +impl ArraySql for Vec { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } +} +impl ArraySql for &[T] { + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, self.iter()) + } +} +impl< + T: std::fmt::Debug + ToSql + Send + Sync, + I: Iterator + ExactSizeIterator, + F: Fn() -> I + Send + Sync, + > ArraySql for IterSql +{ + type Item = T; + fn escape_domain_to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + escape_domain_to_sql(ty, w, (self.0)()) + } +} +pub struct IterSql + ExactSizeIterator, F: Fn() -> I + Sync>(pub F); +impl + ExactSizeIterator, F: Fn() -> I + Sync> std::fmt::Debug + for IterSql +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayFn").finish() + } +} +impl + ExactSizeIterator, F: Fn() -> I + Sync> ToSql + for IterSql +{ + fn to_sql( + &self, + ty: &Type, + w: &mut BytesMut, + ) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => member, + _ => panic!("expected array type"), + }; + let iter = (self.0)(); + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + types::array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match e.to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(member), + _ => false, + } + } + to_sql_checked!(); +} +fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } +} diff --git a/examples/basic_sync/basic_sync_codegen/src/types.rs b/examples/basic_sync/basic_sync_codegen/src/types.rs new file mode 100644 index 00000000..a7c944f1 --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/types.rs @@ -0,0 +1,192 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[allow(non_camel_case_types)] +pub enum SpongeBobCharacter { + Bob, + Patrick, + Squidward, +} +impl<'a> postgres_types::ToSql for SpongeBobCharacter { + fn to_sql( + &self, + ty: &postgres_types::Type, + buf: &mut postgres_types::private::BytesMut, + ) -> Result> { + let s = match *self { + SpongeBobCharacter::Bob => "Bob", + SpongeBobCharacter::Patrick => "Patrick", + SpongeBobCharacter::Squidward => "Squidward", + }; + buf.extend_from_slice(s.as_bytes()); + std::result::Result::Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "sponge_bob_character" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 3 { + return false; + } + variants.iter().all(|v| match &**v { + "Bob" => true, + "Patrick" => true, + "Squidward" => true, + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +impl<'a> postgres_types::FromSql<'a> for SpongeBobCharacter { + fn from_sql( + ty: &postgres_types::Type, + buf: &'a [u8], + ) -> Result> { + match std::str::from_utf8(buf)? { + "Bob" => Ok(SpongeBobCharacter::Bob), + "Patrick" => Ok(SpongeBobCharacter::Patrick), + "Squidward" => Ok(SpongeBobCharacter::Squidward), + s => Result::Err(Into::into(format!("invalid variant `{}`", s))), + } + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "sponge_bob_character" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 3 { + return false; + } + variants.iter().all(|v| match &**v { + "Bob" => true, + "Patrick" => true, + "Squidward" => true, + _ => false, + }) + } + _ => false, + } + } +} +#[derive(Debug, postgres_types::FromSql, Clone, PartialEq)] +#[postgres(name = "voiceactor")] +pub struct Voiceactor { + #[postgres(name = "name")] + pub name: String, + #[postgres(name = "age")] + pub age: i32, +} +#[derive(Debug)] +pub struct VoiceactorBorrowed<'a> { + pub name: &'a str, + pub age: i32, +} +impl<'a> From> for Voiceactor { + fn from(VoiceactorBorrowed { name, age }: VoiceactorBorrowed<'a>) -> Self { + Self { + name: name.into(), + age, + } + } +} +impl<'a> postgres_types::FromSql<'a> for VoiceactorBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let name = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let age = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + Ok(VoiceactorBorrowed { name, age }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "voiceactor" && ty.schema() == "public" + } +} +impl<'a> postgres_types::ToSql for VoiceactorBorrowed<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let VoiceactorBorrowed { name, age } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "name" => postgres_types::ToSql::to_sql(name, field.type_(), out), + "age" => postgres_types::ToSql::to_sql(age, field.type_(), out), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "voiceactor" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 2 { + return false; + } + fields.iter().all(|f| match f.name() { + "name" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), + "age" => ::accepts(f.type_()), + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} diff --git a/examples/basic_sync/basic_sync_codegen/src/utils.rs b/examples/basic_sync/basic_sync_codegen/src/utils.rs new file mode 100644 index 00000000..fca59fa2 --- /dev/null +++ b/examples/basic_sync/basic_sync_codegen/src/utils.rs @@ -0,0 +1,14 @@ +// This file was generated with `cornucopia`. Do not modify. + +use postgres_types::{Kind, ToSql, Type}; +pub fn escape_domain(ty: &Type) -> &Type { + match ty.kind() { + Kind::Domain(ty) => ty, + _ => ty, + } +} +pub fn slice_iter<'a>( + s: &'a [&'a (dyn ToSql + Sync)], +) -> impl ExactSizeIterator + 'a { + s.iter().map(|s| *s as _) +} diff --git a/examples/basic_sync/src/cornucopia.rs b/examples/basic_sync/src/cornucopia.rs deleted file mode 100644 index 55e9cea0..00000000 --- a/examples/basic_sync/src/cornucopia.rs +++ /dev/null @@ -1,741 +0,0 @@ -// This file was generated with `cornucopia`. Do not modify. - -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod types { - pub mod public { - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[allow(non_camel_case_types)] - pub enum SpongeBobCharacter { - Bob, - Patrick, - Squidward, - } - impl<'a> postgres_types::ToSql for SpongeBobCharacter { - fn to_sql( - &self, - ty: &postgres_types::Type, - buf: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let s = match *self { - SpongeBobCharacter::Bob => "Bob", - SpongeBobCharacter::Patrick => "Patrick", - SpongeBobCharacter::Squidward => "Squidward", - }; - buf.extend_from_slice(s.as_bytes()); - std::result::Result::Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "sponge_bob_character" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 3 { - return false; - } - variants.iter().all(|v| match &**v { - "Bob" => true, - "Patrick" => true, - "Squidward" => true, - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - impl<'a> postgres_types::FromSql<'a> for SpongeBobCharacter { - fn from_sql( - ty: &postgres_types::Type, - buf: &'a [u8], - ) -> Result> { - match std::str::from_utf8(buf)? { - "Bob" => Ok(SpongeBobCharacter::Bob), - "Patrick" => Ok(SpongeBobCharacter::Patrick), - "Squidward" => Ok(SpongeBobCharacter::Squidward), - s => Result::Err(Into::into(format!("invalid variant `{}`", s))), - } - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "sponge_bob_character" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 3 { - return false; - } - variants.iter().all(|v| match &**v { - "Bob" => true, - "Patrick" => true, - "Squidward" => true, - _ => false, - }) - } - _ => false, - } - } - } - #[derive(Debug, postgres_types :: FromSql, Clone, PartialEq)] - #[postgres(name = "voiceactor")] - pub struct Voiceactor { - #[postgres(name = "name")] - pub name: String, - #[postgres(name = "age")] - pub age: i32, - } - #[derive(Debug)] - pub struct VoiceactorBorrowed<'a> { - pub name: &'a str, - pub age: i32, - } - impl<'a> From> for Voiceactor { - fn from(VoiceactorBorrowed { name, age }: VoiceactorBorrowed<'a>) -> Self { - Self { - name: name.into(), - age, - } - } - } - impl<'a> postgres_types::FromSql<'a> for VoiceactorBorrowed<'a> { - fn from_sql( - ty: &postgres_types::Type, - out: &'a [u8], - ) -> Result, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err(std::convert::Into::into(format!( - "invalid field count: {} vs {}", - num_fields, - fields.len() - ))); - } - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let name = postgres_types::private::read_value(fields[0].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let age = postgres_types::private::read_value(fields[1].type_(), &mut out)?; - Ok(VoiceactorBorrowed { name, age }) - } - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "voiceactor" && ty.schema() == "public" - } - } - impl<'a> postgres_types::ToSql for VoiceactorBorrowed<'a> { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let VoiceactorBorrowed { name, age } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "name" => postgres_types::ToSql::to_sql(name, field.type_(), out), - "age" => postgres_types::ToSql::to_sql(age, field.type_(), out), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "voiceactor" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 2 { - return false; - } - fields.iter().all(|f| match f.name() { - "name" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), - "age" => ::accepts(f.type_()), - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - } -} -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod queries { - pub mod module_1 { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub fn insert_book() -> InsertBookStmt { - InsertBookStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO Book (title) - VALUES ($1)", - )) - } - pub struct InsertBookStmt(cornucopia_sync::private::Stmt); - impl InsertBookStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - title: &'a T1, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[title]) - } - } - } - pub mod module_2 { - #[derive(Debug)] - pub struct AuthorNameStartingWithParams { - pub start_str: T1, - } - #[derive(Debug, Clone, PartialEq)] - pub struct Authors { - pub id: i32, - pub name: String, - pub country: String, - } - pub struct AuthorsBorrowed<'a> { - pub id: i32, - pub name: &'a str, - pub country: &'a str, - } - impl<'a> From> for Authors { - fn from(AuthorsBorrowed { id, name, country }: AuthorsBorrowed<'a>) -> Self { - Self { - id, - name: name.into(), - country: country.into(), - } - } - } - #[derive(Debug, Clone, PartialEq)] - pub struct AuthorNameStartingWith { - pub authorid: i32, - pub name: String, - pub bookid: i32, - pub title: String, - } - pub struct AuthorNameStartingWithBorrowed<'a> { - pub authorid: i32, - pub name: &'a str, - pub bookid: i32, - pub title: &'a str, - } - impl<'a> From> for AuthorNameStartingWith { - fn from( - AuthorNameStartingWithBorrowed { - authorid, - name, - bookid, - title, - }: AuthorNameStartingWithBorrowed<'a>, - ) -> Self { - Self { - authorid, - name: name.into(), - bookid, - title: title.into(), - } - } - } - #[derive(Debug, Clone, PartialEq)] - pub struct SelectTranslations { - pub title: String, - pub translations: Vec, - } - pub struct SelectTranslationsBorrowed<'a> { - pub title: &'a str, - pub translations: cornucopia_sync::ArrayIterator<'a, &'a str>, - } - impl<'a> From> for SelectTranslations { - fn from( - SelectTranslationsBorrowed { - title, - translations, - }: SelectTranslationsBorrowed<'a>, - ) -> Self { - Self { - title: title.into(), - translations: translations.map(|v| v.into()).collect(), - } - } - } - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct AuthorsQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> AuthorsBorrowed, - mapper: fn(AuthorsBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> AuthorsQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(AuthorsBorrowed) -> R) -> AuthorsQuery<'a, C, R, N> { - AuthorsQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> &str, - mapper: fn(&str) -> T, - } - impl<'a, C, T: 'a, const N: usize> StringQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(&str) -> R) -> StringQuery<'a, C, R, N> { - StringQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct AuthorNameStartingWithQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> AuthorNameStartingWithBorrowed, - mapper: fn(AuthorNameStartingWithBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> AuthorNameStartingWithQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(AuthorNameStartingWithBorrowed) -> R, - ) -> AuthorNameStartingWithQuery<'a, C, R, N> { - AuthorNameStartingWithQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct PublicVoiceactorQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::super::types::public::VoiceactorBorrowed, - mapper: fn(super::super::types::public::VoiceactorBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicVoiceactorQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::types::public::VoiceactorBorrowed) -> R, - ) -> PublicVoiceactorQuery<'a, C, R, N> { - PublicVoiceactorQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct SelectTranslationsQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> SelectTranslationsBorrowed, - mapper: fn(SelectTranslationsBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectTranslationsQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(SelectTranslationsBorrowed) -> R, - ) -> SelectTranslationsQuery<'a, C, R, N> { - SelectTranslationsQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn authors() -> AuthorsStmt { - AuthorsStmt(cornucopia_sync::private::Stmt::new( - "SELECT - * -FROM - Author", - )) - } - pub struct AuthorsStmt(cornucopia_sync::private::Stmt); - impl AuthorsStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> AuthorsQuery<'a, C, Authors, 0> { - AuthorsQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| AuthorsBorrowed { - id: row.get(0), - name: row.get(1), - country: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - pub fn books() -> BooksStmt { - BooksStmt(cornucopia_sync::private::Stmt::new( - "SELECT - Title -FROM - Book", - )) - } - pub struct BooksStmt(cornucopia_sync::private::Stmt); - impl BooksStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> StringQuery<'a, C, String, 0> { - StringQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn author_name_by_id() -> AuthorNameByIdStmt { - AuthorNameByIdStmt(cornucopia_sync::private::Stmt::new( - "SELECT - Author.Name -FROM - Author -WHERE - Author.Id = $1", - )) - } - pub struct AuthorNameByIdStmt(cornucopia_sync::private::Stmt); - impl AuthorNameByIdStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - id: &'a i32, - ) -> StringQuery<'a, C, String, 1> { - StringQuery { - client, - params: [id], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn author_name_starting_with() -> AuthorNameStartingWithStmt { - AuthorNameStartingWithStmt(cornucopia_sync::private::Stmt::new( - "SELECT - BookAuthor.AuthorId, - Author.Name, - BookAuthor.BookId, - Book.Title -FROM - BookAuthor - INNER JOIN Author ON Author.id = BookAuthor.AuthorId - INNER JOIN Book ON Book.Id = BookAuthor.BookId -WHERE - Author.Name LIKE CONCAT($1::text, '%')", - )) - } - pub struct AuthorNameStartingWithStmt(cornucopia_sync::private::Stmt); - impl AuthorNameStartingWithStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - start_str: &'a T1, - ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { - AuthorNameStartingWithQuery { - client, - params: [start_str], - stmt: &mut self.0, - extractor: |row| AuthorNameStartingWithBorrowed { - authorid: row.get(0), - name: row.get(1), - bookid: row.get(2), - title: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_sync::StringSql> - cornucopia_sync::Params< - 'a, - AuthorNameStartingWithParams, - AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1>, - C, - > for AuthorNameStartingWithStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a AuthorNameStartingWithParams, - ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { - self.bind(client, ¶ms.start_str) - } - } - pub fn select_voice_actor_with_character() -> SelectVoiceActorWithCharacterStmt { - SelectVoiceActorWithCharacterStmt(cornucopia_sync::private::Stmt::new( - "SELECT - voice_actor -FROM - SpongeBobVoiceActor -WHERE - character = $1", - )) - } - pub struct SelectVoiceActorWithCharacterStmt(cornucopia_sync::private::Stmt); - impl SelectVoiceActorWithCharacterStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - spongebob_character: &'a super::super::types::public::SpongeBobCharacter, - ) -> PublicVoiceactorQuery<'a, C, super::super::types::public::Voiceactor, 1> - { - PublicVoiceactorQuery { - client, - params: [spongebob_character], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn select_translations() -> SelectTranslationsStmt { - SelectTranslationsStmt(cornucopia_sync::private::Stmt::new( - "SELECT - Title, - Translations -FROM - Book", - )) - } - pub struct SelectTranslationsStmt(cornucopia_sync::private::Stmt); - impl SelectTranslationsStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> SelectTranslationsQuery<'a, C, SelectTranslations, 0> { - SelectTranslationsQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| SelectTranslationsBorrowed { - title: row.get(0), - translations: row.get(1), - }, - mapper: |it| ::from(it), - } - } - } - } -} diff --git a/examples/basic_sync/src/main.rs b/examples/basic_sync/src/main.rs index b8dc4176..5c8ee1ef 100644 --- a/examples/basic_sync/src/main.rs +++ b/examples/basic_sync/src/main.rs @@ -1,8 +1,7 @@ // Take a look at the generated `cornucopia.rs` file if you want to // see what it looks like under the hood. -mod cornucopia; - -use crate::cornucopia::{ +use codegen::{ + client::Params, queries::{ module_1::insert_book, module_2::{ @@ -10,9 +9,8 @@ use crate::cornucopia::{ select_voice_actor_with_character, AuthorNameStartingWithParams, }, }, - types::public::SpongeBobCharacter, + types::SpongeBobCharacter, }; -use cornucopia_sync::Params; pub fn main() { // You can learn which database connection types are compatible with Cornucopia in the book diff --git a/test_codegen/Cargo.toml b/test_codegen/Cargo.toml index 5a77d12f..74192804 100644 --- a/test_codegen/Cargo.toml +++ b/test_codegen/Cargo.toml @@ -3,41 +3,19 @@ name = "test_codegen" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -# Path dependencies -cornucopia_sync = { path = "../crates/client_sync", features = [ - "with-serde_json-1", -] } -cornucopia_async = { path = "../crates/client_async", features = [ - "with-serde_json-1", -] } - +# Cornucopia +codegen = { path = "codegen" } # async futures = "0.3.25" - # rust-postgres interaction -postgres = { version = "0.19.4", features = [ - "with-serde_json-1", - "with-time-0_3", - "with-uuid-1", - "with-eui48-1", -] } -tokio-postgres = { version = "0.7.7", features = [ - "with-serde_json-1", - "with-time-0_3", - "with-uuid-1", - "with-eui48-1", -] } -postgres-types = { version = "0.2.4", features = ["derive"] } - +postgres = "0.19.5" +tokio-postgres = "0.7.8" # serde -serde = { version = "1.0.152", features = ["derive"] } - +serde = { version = "1.0.163", features = ["derive"] } # extra types -serde_json = { version = "1.0.91", features = ["raw_value"] } -time = { version = "0.3.17", features = ["parsing", "serde"] } -uuid = { version = "1.2.2", features = ["serde"] } +serde_json = { version = "1.0.96", features = ["raw_value"] } +time = { version = "0.3.21", features = ["parsing", "serde"] } +uuid = { version = "1.3.2", features = ["serde"] } eui48 = { version = "1.1.0", features = ["serde"] } -rust_decimal = { version = "1.28.0", features = ["db-postgres"] } +rust_decimal = { version = "1.29.1", features = ["db-postgres"] } diff --git a/test_codegen/codegen/Cargo.toml b/test_codegen/codegen/Cargo.toml new file mode 100644 index 00000000..47dcfee8 --- /dev/null +++ b/test_codegen/codegen/Cargo.toml @@ -0,0 +1,46 @@ +# This file was generated with `cornucopia`. Do not modify +[package] +name = "codegen" +version = "0.9.0" +edition = "2021" + +[features] +default = ["deadpool"] +deadpool = ["dep:deadpool-postgres"] + +[dependencies] +## Core dependencies +# Postgres types +postgres-types = { version = "0.2.6", features = ["derive"] } +# Postgres interaction +postgres-protocol = "0.6.6" +# Iterator utils required for working with `postgres_protocol::types::ArrayValues` +fallible-iterator = "0.2.0" + +## Types dependencies +# JSON or JSONB +serde_json = { version = "1.0.113", features = ["raw_value"] } +serde = { version = "1.0.197", features = ["derive"] } +# TIME, DATE, TIMESTAMP or TIMESTAMPZ +time = "0.3.34" +# UUID +uuid = "1.8.0" +# MAC ADDRESS +eui48 = "1.1.0" +# DECIMAL +rust_decimal = { version = "1.29.1", features = ["db-postgres"] } + +## Sync client dependencies +# Postgres sync client +postgres = { version = "0.19.7", features = ["with-serde_json-1","with-time-0_3","with-uuid-1","with-eui48-1",] } + +## Async client dependencies +# Postgres async client +tokio-postgres = { version = "0.7.10", features = ["with-serde_json-1","with-time-0_3","with-uuid-1","with-eui48-1",] } +# Async utils +async-trait = "0.1.78" +futures = "0.3.30" + +## Async features dependencies +# Async connection pooling +deadpool-postgres = { version = "0.14.0", optional = true } diff --git a/test_codegen/codegen/src/array_iterator.rs b/test_codegen/codegen/src/array_iterator.rs new file mode 100644 index 00000000..429ac0d6 --- /dev/null +++ b/test_codegen/codegen/src/array_iterator.rs @@ -0,0 +1,59 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::utils::escape_domain; +use fallible_iterator::FallibleIterator; +use postgres_protocol::types::{array_from_sql, ArrayValues}; +use postgres_types::{FromSql, Kind, Type}; +use std::fmt::Debug; +use std::marker::PhantomData; +/// Iterator over the items in a PostgreSQL array. You only need this if you are +/// working with custom zero-cost type mapping of rows containing PostgreSQL arrays. +pub struct ArrayIterator<'a, T: FromSql<'a>> { + values: ArrayValues<'a>, + ty: Type, + _type: PhantomData, +} +impl<'a, T: FromSql<'a>> Debug for ArrayIterator<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ArrayIterator") + .field("values", &"[T]") + .field("ty", &self.ty) + .field("_type", &self._type) + .finish() + } +} +impl<'a, T: FromSql<'a>> Iterator for ArrayIterator<'a, T> { + type Item = T; + fn next(&mut self) -> Option { + self.values + .next() + .unwrap() + .map(|raw| T::from_sql_nullable(&self.ty, raw).unwrap()) + } +} +impl<'a, T: FromSql<'a>> FromSql<'a> for ArrayIterator<'a, T> { + fn from_sql( + ty: &Type, + raw: &'a [u8], + ) -> Result, Box> { + let member_type = match *escape_domain(ty).kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + let array = array_from_sql(raw)?; + if array.dimensions().count()? > 1 { + return Err("array contains too many dimensions".into()); + } + Ok(ArrayIterator { + ty: member_type.clone(), + values: array.values(), + _type: PhantomData, + }) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref inner) => T::accepts(escape_domain(inner)), + _ => false, + } + } +} diff --git a/test_codegen/codegen/src/client.rs b/test_codegen/codegen/src/client.rs new file mode 100644 index 00000000..c0a0df64 --- /dev/null +++ b/test_codegen/codegen/src/client.rs @@ -0,0 +1,2 @@ +pub mod async_; +pub mod sync; diff --git a/test_codegen/codegen/src/client/async_.rs b/test_codegen/codegen/src/client/async_.rs new file mode 100644 index 00000000..a40fc681 --- /dev/null +++ b/test_codegen/codegen/src/client/async_.rs @@ -0,0 +1,37 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub use generic_client::GenericClient; +use tokio_postgres::{Error, Statement}; +#[cfg(feature = "deadpool")] +mod deadpool; +mod generic_client; +/// This trait allows you to bind parameters to a query using a single +/// struct, rather than passing each bind parameter as a function parameter. +pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a C, params: &'a P) -> O; +} +/// Cached statement +#[doc(hidden)] +pub struct Stmt { + query: &'static str, + cached: Option, +} +impl Stmt { + #[must_use] + pub fn new(query: &'static str) -> Self { + Self { + query, + cached: None, + } + } + pub async fn prepare<'a, C: GenericClient>( + &'a mut self, + client: &C, + ) -> Result<&'a Statement, Error> { + if self.cached.is_none() { + let stmt = client.prepare(self.query).await?; + self.cached = Some(stmt); + } + Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) + } +} diff --git a/test_codegen/codegen/src/client/async_/deadpool.rs b/test_codegen/codegen/src/client/async_/deadpool.rs new file mode 100644 index 00000000..641a31c1 --- /dev/null +++ b/test_codegen/codegen/src/client/async_/deadpool.rs @@ -0,0 +1,121 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::generic_client::GenericClient; +use async_trait::async_trait; +use deadpool_postgres::{ + Client as DeadpoolClient, ClientWrapper, Transaction as DeadpoolTransaction, +}; +use tokio_postgres::{ + types::BorrowToSql, Client as PgClient, Error, RowStream, Statement, ToStatement, + Transaction as PgTransaction, +}; +#[async_trait] +impl GenericClient for DeadpoolClient { + async fn prepare(&self, query: &str) -> Result { + ClientWrapper::prepare_cached(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgClient::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + PgClient::query_raw(self, statement, params).await + } +} +#[async_trait] +impl GenericClient for DeadpoolTransaction<'_> { + async fn prepare(&self, query: &str) -> Result { + DeadpoolTransaction::prepare_cached(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + PgTransaction::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + PgTransaction::query_raw(self, statement, params).await + } +} diff --git a/test_codegen/codegen/src/client/async_/generic_client.rs b/test_codegen/codegen/src/client/async_/generic_client.rs new file mode 100644 index 00000000..b1b6314a --- /dev/null +++ b/test_codegen/codegen/src/client/async_/generic_client.rs @@ -0,0 +1,159 @@ +// This file was generated with `cornucopia`. Do not modify. + +use async_trait::async_trait; +use tokio_postgres::{ + types::BorrowToSql, Client, Error, RowStream, Statement, ToStatement, Transaction, +}; +/// Abstraction over multiple types of asynchronous clients. +/// This allows you to use tokio_postgres clients and transactions interchangeably. +/// +/// In addition, when the `deadpool` feature is enabled (default), this trait also +/// abstracts over deadpool clients and transactions +#[async_trait] +pub trait GenericClient: Send + Sync { + async fn prepare(&self, query: &str) -> Result; + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator; +} +#[async_trait] +impl GenericClient for Transaction<'_> { + async fn prepare(&self, query: &str) -> Result { + Transaction::prepare(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Transaction::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + Transaction::query_raw(self, statement, params).await + } +} +#[async_trait] +impl GenericClient for Client { + async fn prepare(&self, query: &str) -> Result { + Client::prepare(self, query).await + } + async fn execute( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::execute(self, query, params).await + } + async fn query_one( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query_one(self, statement, params).await + } + async fn query_opt( + &self, + statement: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query_opt(self, statement, params).await + } + async fn query( + &self, + query: &T, + params: &[&(dyn tokio_postgres::types::ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + { + Client::query(self, query, params).await + } + async fn query_raw(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, + { + Client::query_raw(self, statement, params).await + } +} diff --git a/test_codegen/codegen/src/client/sync.rs b/test_codegen/codegen/src/client/sync.rs new file mode 100644 index 00000000..64188901 --- /dev/null +++ b/test_codegen/codegen/src/client/sync.rs @@ -0,0 +1,33 @@ +// This file was generated with `cornucopia`. Do not modify. + +use postgres::Statement; +/// This trait allows you to bind parameters to a query using a single +/// struct, rather than passing each bind parameter as a function parameter. +pub trait Params<'a, P, O, C> { + fn params(&'a mut self, client: &'a mut C, params: &'a P) -> O; +} +/// Cached statement +#[doc(hidden)] +pub(crate) struct Stmt { + query: &'static str, + cached: Option, +} +impl Stmt { + #[must_use] + pub fn new(query: &'static str) -> Self { + Self { + query, + cached: None, + } + } + pub fn prepare<'a, C: postgres::GenericClient>( + &'a mut self, + client: &mut C, + ) -> Result<&'a Statement, postgres::Error> { + if self.cached.is_none() { + let stmt = client.prepare(self.query)?; + self.cached = Some(stmt); + } + Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) + } +} diff --git a/test_codegen/codegen/src/domain.rs b/test_codegen/codegen/src/domain.rs new file mode 100644 index 00000000..d0510159 --- /dev/null +++ b/test_codegen/codegen/src/domain.rs @@ -0,0 +1,92 @@ +// This file was generated with `cornucopia`. Do not modify. + +use super::{type_traits::ArraySql, utils::escape_domain}; +use postgres_protocol::types::{array_to_sql, ArrayDimension}; +use postgres_types::{private::BytesMut, IsNull, Kind, ToSql, Type}; +use std::{ + error::Error, + fmt::{Debug, Formatter}, +}; +pub struct Domain(pub T); +impl Debug for Domain { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("DomainWrapper").field(&self.0).finish() + } +} +impl ToSql for Domain { + fn to_sql(&self, ty: &Type, out: &mut BytesMut) -> Result> + where + Self: Sized, + { + postgres_types::ToSql::to_sql(&self.0, escape_domain(ty), out) + } + fn accepts(ty: &Type) -> bool + where + Self: Sized, + { + return T::accepts(escape_domain(ty)); + } + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +pub struct DomainArray<'a, T: ToSql + Sync, A: ArraySql>(pub &'a A); +impl<'a, T: ToSql + Sync, A: ArraySql> Debug for DomainArray<'a, T, A> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("ArrayDomain").field(&self.0).finish() + } +} +impl<'a, T: ToSql + Sync + 'a, A: ArraySql> ToSql for DomainArray<'a, T, A> { + fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { + self.0.escape_domain_to_sql(ty, w) + } + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref member) => T::accepts(escape_domain(member)), + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &Type, + out: &mut BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +pub fn escape_domain_to_sql( + ty: &Type, + w: &mut BytesMut, + iter: impl ExactSizeIterator, +) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => escape_domain(member), + _ => panic!("expected array type got {ty}"), + }; + let dimension = ArrayDimension { + len: downcast(iter.len())?, + lower_bound: 1, + }; + array_to_sql( + Some(dimension), + member_type.oid(), + iter, + |e, w| match Domain(e).to_sql(member_type, w)? { + IsNull::No => Ok(postgres_protocol::IsNull::No), + IsNull::Yes => Ok(postgres_protocol::IsNull::Yes), + }, + w, + )?; + Ok(IsNull::No) +} +fn downcast(len: usize) -> Result> { + if len > i32::MAX as usize { + Err("value too large to transmit".into()) + } else { + Ok(len as i32) + } +} diff --git a/test_codegen/codegen/src/lib.rs b/test_codegen/codegen/src/lib.rs new file mode 100644 index 00000000..7fd4ebab --- /dev/null +++ b/test_codegen/codegen/src/lib.rs @@ -0,0 +1,22 @@ +// This file was generated with `cornucopia`. Do not modify. + +mod array_iterator; +pub mod client; +mod domain; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod queries; +mod type_traits; +#[allow(clippy::all, clippy::pedantic)] +#[allow(unused_variables)] +#[allow(unused_imports)] +#[allow(dead_code)] +pub mod types; +mod utils; +pub use array_iterator::ArrayIterator; +pub use domain::{Domain, DomainArray}; +pub use type_traits::JsonSql; +pub use type_traits::{ArraySql, BytesSql, IterSql, StringSql}; +pub(crate) use utils::slice_iter; diff --git a/test_codegen/codegen/src/queries.rs b/test_codegen/codegen/src/queries.rs new file mode 100644 index 00000000..2ceecb9d --- /dev/null +++ b/test_codegen/codegen/src/queries.rs @@ -0,0 +1,69 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub mod copy; +pub mod domain; +pub mod named; +pub mod nullity; +pub mod params; +pub mod stress; +pub mod syntax; +pub mod sync { + pub mod copy { + pub use super::super::copy::sync::*; + pub use super::super::copy::*; + } + pub mod domain { + pub use super::super::domain::sync::*; + pub use super::super::domain::*; + } + pub mod named { + pub use super::super::named::sync::*; + pub use super::super::named::*; + } + pub mod nullity { + pub use super::super::nullity::sync::*; + pub use super::super::nullity::*; + } + pub mod params { + pub use super::super::params::sync::*; + pub use super::super::params::*; + } + pub mod stress { + pub use super::super::stress::sync::*; + pub use super::super::stress::*; + } + pub mod syntax { + pub use super::super::syntax::sync::*; + pub use super::super::syntax::*; + } +} +pub mod async_ { + pub mod copy { + pub use super::super::copy::async_::*; + pub use super::super::copy::*; + } + pub mod domain { + pub use super::super::domain::async_::*; + pub use super::super::domain::*; + } + pub mod named { + pub use super::super::named::async_::*; + pub use super::super::named::*; + } + pub mod nullity { + pub use super::super::nullity::async_::*; + pub use super::super::nullity::*; + } + pub mod params { + pub use super::super::params::async_::*; + pub use super::super::params::*; + } + pub mod stress { + pub use super::super::stress::async_::*; + pub use super::super::stress::*; + } + pub mod syntax { + pub use super::super::syntax::async_::*; + pub use super::super::syntax::*; + } +} diff --git a/test_codegen/codegen/src/queries/copy.rs b/test_codegen/codegen/src/queries/copy.rs new file mode 100644 index 00000000..6874b106 --- /dev/null +++ b/test_codegen/codegen/src/queries/copy.rs @@ -0,0 +1,357 @@ +// This file was generated with `cornucopia`. Do not modify. + +pub mod sync { + use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + pub struct CloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> crate::types::CloneCompositeBorrowed, + mapper: fn(crate::types::CloneCompositeBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> CloneCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::CloneCompositeBorrowed) -> R, + ) -> CloneCompositeQuery<'a, C, R, N> { + CloneCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct CopyCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> crate::types::CopyComposite, + mapper: fn(crate::types::CopyComposite) -> T, + } + impl<'a, C, T: 'a, const N: usize> CopyCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::CopyComposite) -> R, + ) -> CopyCompositeQuery<'a, C, R, N> { + CopyCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub fn insert_clone() -> InsertCloneStmt { + InsertCloneStmt(crate::client::sync::Stmt::new( + "INSERT INTO clone (composite) VALUES ($1)", + )) + } + pub struct InsertCloneStmt(crate::client::sync::Stmt); + impl InsertCloneStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + composite: &'a crate::types::CloneCompositeBorrowed<'a>, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[composite]) + } + } + pub fn select_clone() -> SelectCloneStmt { + SelectCloneStmt(crate::client::sync::Stmt::new("SELECT * FROM clone")) + } + pub struct SelectCloneStmt(crate::client::sync::Stmt); + impl SelectCloneStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> CloneCompositeQuery<'a, C, crate::types::CloneComposite, 0> { + CloneCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn insert_copy() -> InsertCopyStmt { + InsertCopyStmt(crate::client::sync::Stmt::new( + "INSERT INTO copy (composite) VALUES ($1)", + )) + } + pub struct InsertCopyStmt(crate::client::sync::Stmt); + impl InsertCopyStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + composite: &'a crate::types::CopyComposite, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[composite]) + } + } + pub fn select_copy() -> SelectCopyStmt { + SelectCopyStmt(crate::client::sync::Stmt::new("SELECT * FROM copy")) + } + pub struct SelectCopyStmt(crate::client::sync::Stmt); + impl SelectCopyStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> CopyCompositeQuery<'a, C, crate::types::CopyComposite, 0> { + CopyCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it, + } + } + } +} +pub mod async_ { + use crate::client::async_::GenericClient; + use futures::{self, StreamExt, TryStreamExt}; + pub struct CloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> crate::types::CloneCompositeBorrowed, + mapper: fn(crate::types::CloneCompositeBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> CloneCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::CloneCompositeBorrowed) -> R, + ) -> CloneCompositeQuery<'a, C, R, N> { + CloneCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct CopyCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> crate::types::CopyComposite, + mapper: fn(crate::types::CopyComposite) -> T, + } + impl<'a, C, T: 'a, const N: usize> CopyCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::CopyComposite) -> R, + ) -> CopyCompositeQuery<'a, C, R, N> { + CopyCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub fn insert_clone() -> InsertCloneStmt { + InsertCloneStmt(crate::client::async_::Stmt::new( + "INSERT INTO clone (composite) VALUES ($1)", + )) + } + pub struct InsertCloneStmt(crate::client::async_::Stmt); + impl InsertCloneStmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + composite: &'a crate::types::CloneCompositeBorrowed<'a>, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[composite]).await + } + } + pub fn select_clone() -> SelectCloneStmt { + SelectCloneStmt(crate::client::async_::Stmt::new("SELECT * FROM clone")) + } + pub struct SelectCloneStmt(crate::client::async_::Stmt); + impl SelectCloneStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> CloneCompositeQuery<'a, C, crate::types::CloneComposite, 0> { + CloneCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn insert_copy() -> InsertCopyStmt { + InsertCopyStmt(crate::client::async_::Stmt::new( + "INSERT INTO copy (composite) VALUES ($1)", + )) + } + pub struct InsertCopyStmt(crate::client::async_::Stmt); + impl InsertCopyStmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + composite: &'a crate::types::CopyComposite, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[composite]).await + } + } + pub fn select_copy() -> SelectCopyStmt { + SelectCopyStmt(crate::client::async_::Stmt::new("SELECT * FROM copy")) + } + pub struct SelectCopyStmt(crate::client::async_::Stmt); + impl SelectCopyStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> CopyCompositeQuery<'a, C, crate::types::CopyComposite, 0> { + CopyCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it, + } + } + } +} diff --git a/test_codegen/codegen/src/queries/domain.rs b/test_codegen/codegen/src/queries/domain.rs new file mode 100644 index 00000000..c0d1415f --- /dev/null +++ b/test_codegen/codegen/src/queries/domain.rs @@ -0,0 +1,537 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct InsertNightmareDomainParams< + 'a, + T1: crate::StringSql, + T2: crate::JsonSql, + T3: crate::JsonSql, + T4: crate::ArraySql, +> { + pub txt: T1, + pub json: T2, + pub nb: i32, + pub arr: T4, + pub composite: Option>, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct SelectNightmareDomain { + pub txt: String, + pub json: serde_json::Value, + pub nb: i32, + pub arr: Vec, +} +pub struct SelectNightmareDomainBorrowed<'a> { + pub txt: &'a str, + pub json: postgres_types::Json<&'a serde_json::value::RawValue>, + pub nb: i32, + pub arr: crate::ArrayIterator<'a, postgres_types::Json<&'a serde_json::value::RawValue>>, +} +impl<'a> From> for SelectNightmareDomain { + fn from( + SelectNightmareDomainBorrowed { txt, json, nb, arr }: SelectNightmareDomainBorrowed<'a>, + ) -> Self { + Self { + txt: txt.into(), + json: serde_json::from_str(json.0.get()).unwrap(), + nb, + arr: arr + .map(|v| serde_json::from_str(v.0.get()).unwrap()) + .collect(), + } + } +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct SelectNightmareDomainNull { + pub txt: Option, + pub json: Option, + pub nb: Option, + pub arr: Option>>, + pub composite: Option, +} +pub struct SelectNightmareDomainNullBorrowed<'a> { + pub txt: Option<&'a str>, + pub json: Option>, + pub nb: Option, + pub arr: Option< + crate::ArrayIterator<'a, Option>>, + >, + pub composite: Option>, +} +impl<'a> From> for SelectNightmareDomainNull { + fn from( + SelectNightmareDomainNullBorrowed { + txt, + json, + nb, + arr, + composite, + }: SelectNightmareDomainNullBorrowed<'a>, + ) -> Self { + Self { + txt: txt.map(|v| v.into()), + json: json.map(|v| serde_json::from_str(v.0.get()).unwrap()), + nb, + arr: arr.map(|v| { + v.map(|v| v.map(|v| serde_json::from_str(v.0.get()).unwrap())) + .collect() + }), + composite: composite.map(|v| v.into()), + } + } +} +pub mod sync { + use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + pub struct SelectNightmareDomainQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::SelectNightmareDomainBorrowed, + mapper: fn(super::SelectNightmareDomainBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SelectNightmareDomainQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::SelectNightmareDomainBorrowed) -> R, + ) -> SelectNightmareDomainQuery<'a, C, R, N> { + SelectNightmareDomainQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct SelectNightmareDomainNullQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::SelectNightmareDomainNullBorrowed, + mapper: fn(super::SelectNightmareDomainNullBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SelectNightmareDomainNullQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::SelectNightmareDomainNullBorrowed) -> R, + ) -> SelectNightmareDomainNullQuery<'a, C, R, N> { + SelectNightmareDomainNullQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub fn select_nightmare_domain() -> SelectNightmareDomainStmt { + SelectNightmareDomainStmt(crate::client::sync::Stmt::new( + "SELECT txt, json, nb, arr FROM nightmare_domain", + )) + } + pub struct SelectNightmareDomainStmt(crate::client::sync::Stmt); + impl SelectNightmareDomainStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> SelectNightmareDomainQuery<'a, C, super::SelectNightmareDomain, 0> { + SelectNightmareDomainQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::SelectNightmareDomainBorrowed { + txt: row.get(0), + json: row.get(1), + nb: row.get(2), + arr: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn insert_nightmare_domain() -> InsertNightmareDomainStmt { + InsertNightmareDomainStmt(crate::client::sync::Stmt::new("INSERT INTO nightmare_domain (txt, json, nb, arr, composite) VALUES ($1, $2, $3, $4, $5)")) + } + pub struct InsertNightmareDomainStmt(crate::client::sync::Stmt); + impl InsertNightmareDomainStmt { + pub fn bind< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::JsonSql, + T3: crate::JsonSql, + T4: crate::ArraySql, + >( + &'a mut self, + client: &'a mut C, + txt: &'a T1, + json: &'a T2, + nb: &'a i32, + arr: &'a T4, + composite: &'a Option>, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute( + stmt, + &[ + &crate::Domain(txt), + &crate::Domain(json), + &crate::Domain(nb), + &crate::Domain(&crate::DomainArray(arr)), + composite, + ], + ) + } + } + impl< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::JsonSql, + T3: crate::JsonSql, + T4: crate::ArraySql, + > + crate::client::sync::Params< + 'a, + super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, + Result, + C, + > for InsertNightmareDomainStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, + ) -> Result { + self.bind( + client, + ¶ms.txt, + ¶ms.json, + ¶ms.nb, + ¶ms.arr, + ¶ms.composite, + ) + } + } + pub fn select_nightmare_domain_null() -> SelectNightmareDomainNullStmt { + SelectNightmareDomainNullStmt(crate::client::sync::Stmt::new( + "SELECT * FROM nightmare_domain", + )) + } + pub struct SelectNightmareDomainNullStmt(crate::client::sync::Stmt); + impl SelectNightmareDomainNullStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> SelectNightmareDomainNullQuery<'a, C, super::SelectNightmareDomainNull, 0> { + SelectNightmareDomainNullQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::SelectNightmareDomainNullBorrowed { + txt: row.get(0), + json: row.get(1), + nb: row.get(2), + arr: row.get(3), + composite: row.get(4), + }, + mapper: |it| ::from(it), + } + } + } +} +pub mod async_ { + use crate::client::async_::GenericClient; + use futures::{self, StreamExt, TryStreamExt}; + pub struct SelectNightmareDomainQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::SelectNightmareDomainBorrowed, + mapper: fn(super::SelectNightmareDomainBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SelectNightmareDomainQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::SelectNightmareDomainBorrowed) -> R, + ) -> SelectNightmareDomainQuery<'a, C, R, N> { + SelectNightmareDomainQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct SelectNightmareDomainNullQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::SelectNightmareDomainNullBorrowed, + mapper: fn(super::SelectNightmareDomainNullBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SelectNightmareDomainNullQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::SelectNightmareDomainNullBorrowed) -> R, + ) -> SelectNightmareDomainNullQuery<'a, C, R, N> { + SelectNightmareDomainNullQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub fn select_nightmare_domain() -> SelectNightmareDomainStmt { + SelectNightmareDomainStmt(crate::client::async_::Stmt::new( + "SELECT txt, json, nb, arr FROM nightmare_domain", + )) + } + pub struct SelectNightmareDomainStmt(crate::client::async_::Stmt); + impl SelectNightmareDomainStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> SelectNightmareDomainQuery<'a, C, super::SelectNightmareDomain, 0> { + SelectNightmareDomainQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::SelectNightmareDomainBorrowed { + txt: row.get(0), + json: row.get(1), + nb: row.get(2), + arr: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn insert_nightmare_domain() -> InsertNightmareDomainStmt { + InsertNightmareDomainStmt(crate::client::async_::Stmt::new("INSERT INTO nightmare_domain (txt, json, nb, arr, composite) VALUES ($1, $2, $3, $4, $5)")) + } + pub struct InsertNightmareDomainStmt(crate::client::async_::Stmt); + impl InsertNightmareDomainStmt { + pub async fn bind< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::JsonSql, + T3: crate::JsonSql, + T4: crate::ArraySql, + >( + &'a mut self, + client: &'a C, + txt: &'a T1, + json: &'a T2, + nb: &'a i32, + arr: &'a T4, + composite: &'a Option>, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client + .execute( + stmt, + &[ + &crate::Domain(txt), + &crate::Domain(json), + &crate::Domain(nb), + &crate::Domain(&crate::DomainArray(arr)), + composite, + ], + ) + .await + } + } + impl< + 'a, + C: GenericClient + Send + Sync, + T1: crate::StringSql, + T2: crate::JsonSql, + T3: crate::JsonSql, + T4: crate::ArraySql, + > + crate::client::async_::Params< + 'a, + super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for InsertNightmareDomainStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind( + client, + ¶ms.txt, + ¶ms.json, + ¶ms.nb, + ¶ms.arr, + ¶ms.composite, + )) + } + } + pub fn select_nightmare_domain_null() -> SelectNightmareDomainNullStmt { + SelectNightmareDomainNullStmt(crate::client::async_::Stmt::new( + "SELECT * FROM nightmare_domain", + )) + } + pub struct SelectNightmareDomainNullStmt(crate::client::async_::Stmt); + impl SelectNightmareDomainNullStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> SelectNightmareDomainNullQuery<'a, C, super::SelectNightmareDomainNull, 0> { + SelectNightmareDomainNullQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::SelectNightmareDomainNullBorrowed { + txt: row.get(0), + json: row.get(1), + nb: row.get(2), + arr: row.get(3), + composite: row.get(4), + }, + mapper: |it| ::from(it), + } + } + } +} diff --git a/test_codegen/codegen/src/queries/named.rs b/test_codegen/codegen/src/queries/named.rs new file mode 100644 index 00000000..f556ab43 --- /dev/null +++ b/test_codegen/codegen/src/queries/named.rs @@ -0,0 +1,731 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct NamedParams { + pub name: T1, + pub price: Option, +} +#[derive(Debug)] +pub struct NamedComplexParams<'a> { + pub named: crate::types::NamedCompositeBorrowed<'a>, + pub named_with_dot: Option, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq, Copy)] +pub struct Id { + pub id: i32, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct Named { + pub id: i32, + pub name: String, + pub price: Option, + pub show: bool, +} +pub struct NamedBorrowed<'a> { + pub id: i32, + pub name: &'a str, + pub price: Option, + pub show: bool, +} +impl<'a> From> for Named { + fn from( + NamedBorrowed { + id, + name, + price, + show, + }: NamedBorrowed<'a>, + ) -> Self { + Self { + id, + name: name.into(), + price, + show, + } + } +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct NamedComplex { + pub named: crate::types::NamedComposite, + pub named_with_dot: Option, +} +pub struct NamedComplexBorrowed<'a> { + pub named: crate::types::NamedCompositeBorrowed<'a>, + pub named_with_dot: Option, +} +impl<'a> From> for NamedComplex { + fn from( + NamedComplexBorrowed { + named, + named_with_dot, + }: NamedComplexBorrowed<'a>, + ) -> Self { + Self { + named: named.into(), + named_with_dot, + } + } +} +pub mod sync { + use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + pub struct IdQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::Id, + mapper: fn(super::Id) -> T, + } + impl<'a, C, T: 'a, const N: usize> IdQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::Id) -> R) -> IdQuery<'a, C, R, N> { + IdQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct NamedQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::NamedBorrowed, + mapper: fn(super::NamedBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> NamedQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::NamedBorrowed) -> R) -> NamedQuery<'a, C, R, N> { + NamedQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct NamedComplexQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::NamedComplexBorrowed, + mapper: fn(super::NamedComplexBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> NamedComplexQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::NamedComplexBorrowed) -> R, + ) -> NamedComplexQuery<'a, C, R, N> { + NamedComplexQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub fn new_named_visible() -> NewNamedVisibleStmt { + NewNamedVisibleStmt(crate::client::sync::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, true) RETURNING id ", + )) + } + pub struct NewNamedVisibleStmt(crate::client::sync::Stmt); + impl NewNamedVisibleStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + name: &'a T1, + price: &'a Option, + ) -> IdQuery<'a, C, super::Id, 2> { + IdQuery { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| super::Id { id: row.get(0) }, + mapper: |it| ::from(it), + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::sync::Params<'a, super::NamedParams, IdQuery<'a, C, super::Id, 2>, C> + for NewNamedVisibleStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::NamedParams, + ) -> IdQuery<'a, C, super::Id, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn new_named_hidden() -> NewNamedHiddenStmt { + NewNamedHiddenStmt(crate::client::sync::Stmt::new( + "INSERT INTO named (price, name, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct NewNamedHiddenStmt(crate::client::sync::Stmt); + impl NewNamedHiddenStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + price: &'a Option, + name: &'a T1, + ) -> IdQuery<'a, C, super::Id, 2> { + IdQuery { + client, + params: [price, name], + stmt: &mut self.0, + extractor: |row| super::Id { id: row.get(0) }, + mapper: |it| ::from(it), + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::sync::Params<'a, super::NamedParams, IdQuery<'a, C, super::Id, 2>, C> + for NewNamedHiddenStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::NamedParams, + ) -> IdQuery<'a, C, super::Id, 2> { + self.bind(client, ¶ms.price, ¶ms.name) + } + } + pub fn named() -> NamedStmt { + NamedStmt(crate::client::sync::Stmt::new("SELECT * FROM named")) + } + pub struct NamedStmt(crate::client::sync::Stmt); + impl NamedStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> NamedQuery<'a, C, super::Named, 0> { + NamedQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::NamedBorrowed { + id: row.get(0), + name: row.get(1), + price: row.get(2), + show: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn named_by_id() -> NamedByIdStmt { + NamedByIdStmt(crate::client::sync::Stmt::new( + "SELECT * FROM named WHERE id = $1", + )) + } + pub struct NamedByIdStmt(crate::client::sync::Stmt); + impl NamedByIdStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + id: &'a i32, + ) -> NamedQuery<'a, C, super::Named, 1> { + NamedQuery { + client, + params: [id], + stmt: &mut self.0, + extractor: |row| super::NamedBorrowed { + id: row.get(0), + name: row.get(1), + price: row.get(2), + show: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn new_named_complex() -> NewNamedComplexStmt { + NewNamedComplexStmt(crate::client::sync::Stmt::new( + "INSERT INTO named_complex (named, \"named.with_dot\") VALUES ($1, $2)", + )) + } + pub struct NewNamedComplexStmt(crate::client::sync::Stmt); + impl NewNamedComplexStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + named: &'a crate::types::NamedCompositeBorrowed<'a>, + named_with_dot: &'a Option, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[named, named_with_dot]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params< + 'a, + super::NamedComplexParams<'a>, + Result, + C, + > for NewNamedComplexStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::NamedComplexParams<'a>, + ) -> Result { + self.bind(client, ¶ms.named, ¶ms.named_with_dot) + } + } + pub fn named_complex() -> NamedComplexStmt { + NamedComplexStmt(crate::client::sync::Stmt::new( + "SELECT * FROM named_complex", + )) + } + pub struct NamedComplexStmt(crate::client::sync::Stmt); + impl NamedComplexStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> NamedComplexQuery<'a, C, super::NamedComplex, 0> { + NamedComplexQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::NamedComplexBorrowed { + named: row.get(0), + named_with_dot: row.get(1), + }, + mapper: |it| ::from(it), + } + } + } +} +pub mod async_ { + use crate::client::async_::GenericClient; + use futures::{self, StreamExt, TryStreamExt}; + pub struct IdQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::Id, + mapper: fn(super::Id) -> T, + } + impl<'a, C, T: 'a, const N: usize> IdQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::Id) -> R) -> IdQuery<'a, C, R, N> { + IdQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct NamedQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::NamedBorrowed, + mapper: fn(super::NamedBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> NamedQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::NamedBorrowed) -> R) -> NamedQuery<'a, C, R, N> { + NamedQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct NamedComplexQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::NamedComplexBorrowed, + mapper: fn(super::NamedComplexBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> NamedComplexQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::NamedComplexBorrowed) -> R, + ) -> NamedComplexQuery<'a, C, R, N> { + NamedComplexQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub fn new_named_visible() -> NewNamedVisibleStmt { + NewNamedVisibleStmt(crate::client::async_::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, true) RETURNING id ", + )) + } + pub struct NewNamedVisibleStmt(crate::client::async_::Stmt); + impl NewNamedVisibleStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + name: &'a T1, + price: &'a Option, + ) -> IdQuery<'a, C, super::Id, 2> { + IdQuery { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| super::Id { id: row.get(0) }, + mapper: |it| ::from(it), + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::async_::Params<'a, super::NamedParams, IdQuery<'a, C, super::Id, 2>, C> + for NewNamedVisibleStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::NamedParams, + ) -> IdQuery<'a, C, super::Id, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn new_named_hidden() -> NewNamedHiddenStmt { + NewNamedHiddenStmt(crate::client::async_::Stmt::new( + "INSERT INTO named (price, name, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct NewNamedHiddenStmt(crate::client::async_::Stmt); + impl NewNamedHiddenStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + price: &'a Option, + name: &'a T1, + ) -> IdQuery<'a, C, super::Id, 2> { + IdQuery { + client, + params: [price, name], + stmt: &mut self.0, + extractor: |row| super::Id { id: row.get(0) }, + mapper: |it| ::from(it), + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::async_::Params<'a, super::NamedParams, IdQuery<'a, C, super::Id, 2>, C> + for NewNamedHiddenStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::NamedParams, + ) -> IdQuery<'a, C, super::Id, 2> { + self.bind(client, ¶ms.price, ¶ms.name) + } + } + pub fn named() -> NamedStmt { + NamedStmt(crate::client::async_::Stmt::new("SELECT * FROM named")) + } + pub struct NamedStmt(crate::client::async_::Stmt); + impl NamedStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> NamedQuery<'a, C, super::Named, 0> { + NamedQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::NamedBorrowed { + id: row.get(0), + name: row.get(1), + price: row.get(2), + show: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn named_by_id() -> NamedByIdStmt { + NamedByIdStmt(crate::client::async_::Stmt::new( + "SELECT * FROM named WHERE id = $1", + )) + } + pub struct NamedByIdStmt(crate::client::async_::Stmt); + impl NamedByIdStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + id: &'a i32, + ) -> NamedQuery<'a, C, super::Named, 1> { + NamedQuery { + client, + params: [id], + stmt: &mut self.0, + extractor: |row| super::NamedBorrowed { + id: row.get(0), + name: row.get(1), + price: row.get(2), + show: row.get(3), + }, + mapper: |it| ::from(it), + } + } + } + pub fn new_named_complex() -> NewNamedComplexStmt { + NewNamedComplexStmt(crate::client::async_::Stmt::new( + "INSERT INTO named_complex (named, \"named.with_dot\") VALUES ($1, $2)", + )) + } + pub struct NewNamedComplexStmt(crate::client::async_::Stmt); + impl NewNamedComplexStmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + named: &'a crate::types::NamedCompositeBorrowed<'a>, + named_with_dot: &'a Option, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[named, named_with_dot]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::NamedComplexParams<'a>, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for NewNamedComplexStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::NamedComplexParams<'a>, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.named, ¶ms.named_with_dot)) + } + } + pub fn named_complex() -> NamedComplexStmt { + NamedComplexStmt(crate::client::async_::Stmt::new( + "SELECT * FROM named_complex", + )) + } + pub struct NamedComplexStmt(crate::client::async_::Stmt); + impl NamedComplexStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> NamedComplexQuery<'a, C, super::NamedComplex, 0> { + NamedComplexQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::NamedComplexBorrowed { + named: row.get(0), + named_with_dot: row.get(1), + }, + mapper: |it| ::from(it), + } + } + } +} diff --git a/test_codegen/codegen/src/queries/nullity.rs b/test_codegen/codegen/src/queries/nullity.rs new file mode 100644 index 00000000..18120f2d --- /dev/null +++ b/test_codegen/codegen/src/queries/nullity.rs @@ -0,0 +1,286 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct NullityParams< + 'a, + T1: crate::StringSql, + T2: crate::ArraySql>, + T3: crate::StringSql, +> { + pub texts: T2, + pub name: T3, + pub composite: Option>, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct Nullity { + pub texts: Vec>, + pub name: String, + pub composite: Option, +} +pub struct NullityBorrowed<'a> { + pub texts: crate::ArrayIterator<'a, Option<&'a str>>, + pub name: &'a str, + pub composite: Option>, +} +impl<'a> From> for Nullity { + fn from( + NullityBorrowed { + texts, + name, + composite, + }: NullityBorrowed<'a>, + ) -> Self { + Self { + texts: texts.map(|v| v.map(|v| v.into())).collect(), + name: name.into(), + composite: composite.map(|v| v.into()), + } + } +} +pub mod sync { + use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + pub struct NullityQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::NullityBorrowed, + mapper: fn(super::NullityBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> NullityQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::NullityBorrowed) -> R) -> NullityQuery<'a, C, R, N> { + NullityQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub fn new_nullity() -> NewNullityStmt { + NewNullityStmt(crate::client::sync::Stmt::new( + "INSERT INTO nullity(texts, name, composite) VALUES ($1, $2, $3)", + )) + } + pub struct NewNullityStmt(crate::client::sync::Stmt); + impl NewNullityStmt { + pub fn bind< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::ArraySql>, + T3: crate::StringSql, + >( + &'a mut self, + client: &'a mut C, + texts: &'a T2, + name: &'a T3, + composite: &'a Option>, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[texts, name, composite]) + } + } + impl< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::ArraySql>, + T3: crate::StringSql, + > + crate::client::sync::Params< + 'a, + super::NullityParams<'a, T1, T2, T3>, + Result, + C, + > for NewNullityStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::NullityParams<'a, T1, T2, T3>, + ) -> Result { + self.bind(client, ¶ms.texts, ¶ms.name, ¶ms.composite) + } + } + pub fn nullity() -> NullityStmt { + NullityStmt(crate::client::sync::Stmt::new("SELECT * FROM nullity")) + } + pub struct NullityStmt(crate::client::sync::Stmt); + impl NullityStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> NullityQuery<'a, C, super::Nullity, 0> { + NullityQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::NullityBorrowed { + texts: row.get(0), + name: row.get(1), + composite: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } +} +pub mod async_ { + use crate::client::async_::GenericClient; + use futures::{self, StreamExt, TryStreamExt}; + pub struct NullityQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::NullityBorrowed, + mapper: fn(super::NullityBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> NullityQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::NullityBorrowed) -> R) -> NullityQuery<'a, C, R, N> { + NullityQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub fn new_nullity() -> NewNullityStmt { + NewNullityStmt(crate::client::async_::Stmt::new( + "INSERT INTO nullity(texts, name, composite) VALUES ($1, $2, $3)", + )) + } + pub struct NewNullityStmt(crate::client::async_::Stmt); + impl NewNullityStmt { + pub async fn bind< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::ArraySql>, + T3: crate::StringSql, + >( + &'a mut self, + client: &'a C, + texts: &'a T2, + name: &'a T3, + composite: &'a Option>, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[texts, name, composite]).await + } + } + impl< + 'a, + C: GenericClient + Send + Sync, + T1: crate::StringSql, + T2: crate::ArraySql>, + T3: crate::StringSql, + > + crate::client::async_::Params< + 'a, + super::NullityParams<'a, T1, T2, T3>, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for NewNullityStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::NullityParams<'a, T1, T2, T3>, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.texts, ¶ms.name, ¶ms.composite)) + } + } + pub fn nullity() -> NullityStmt { + NullityStmt(crate::client::async_::Stmt::new("SELECT * FROM nullity")) + } + pub struct NullityStmt(crate::client::async_::Stmt); + impl NullityStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> NullityQuery<'a, C, super::Nullity, 0> { + NullityQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::NullityBorrowed { + texts: row.get(0), + name: row.get(1), + composite: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } +} diff --git a/test_codegen/codegen/src/queries/params.rs b/test_codegen/codegen/src/queries/params.rs new file mode 100644 index 00000000..a2c13bc8 --- /dev/null +++ b/test_codegen/codegen/src/queries/params.rs @@ -0,0 +1,523 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct InsertBookParams { + pub author: Option, + pub name: T2, +} +#[derive(Clone, Copy, Debug)] +pub struct ParamsOrderParams { + pub c: i32, + pub a: i32, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct SelectBook { + pub name: String, + pub author: Option, +} +pub struct SelectBookBorrowed<'a> { + pub name: &'a str, + pub author: Option<&'a str>, +} +impl<'a> From> for SelectBook { + fn from(SelectBookBorrowed { name, author }: SelectBookBorrowed<'a>) -> Self { + Self { + name: name.into(), + author: author.map(|v| v.into()), + } + } +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct FindBooks { + pub name: String, + pub author: Option, +} +pub struct FindBooksBorrowed<'a> { + pub name: &'a str, + pub author: Option<&'a str>, +} +impl<'a> From> for FindBooks { + fn from(FindBooksBorrowed { name, author }: FindBooksBorrowed<'a>) -> Self { + Self { + name: name.into(), + author: author.map(|v| v.into()), + } + } +} +pub mod sync { + use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + pub struct SelectBookQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::SelectBookBorrowed, + mapper: fn(super::SelectBookBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SelectBookQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::SelectBookBorrowed) -> R, + ) -> SelectBookQuery<'a, C, R, N> { + SelectBookQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct FindBooksQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::FindBooksBorrowed, + mapper: fn(super::FindBooksBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> FindBooksQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::FindBooksBorrowed) -> R, + ) -> FindBooksQuery<'a, C, R, N> { + FindBooksQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub fn insert_book() -> InsertBookStmt { + InsertBookStmt(crate::client::sync::Stmt::new( + "INSERT INTO book (author, name) VALUES ($1, $2)", + )) + } + pub struct InsertBookStmt(crate::client::sync::Stmt); + impl InsertBookStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql>( + &'a mut self, + client: &'a mut C, + author: &'a Option, + name: &'a T2, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[author, name]) + } + } + impl<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql> + crate::client::sync::Params< + 'a, + super::InsertBookParams, + Result, + C, + > for InsertBookStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::InsertBookParams, + ) -> Result { + self.bind(client, ¶ms.author, ¶ms.name) + } + } + pub fn select_book() -> SelectBookStmt { + SelectBookStmt(crate::client::sync::Stmt::new("SELECT * FROM book")) + } + pub struct SelectBookStmt(crate::client::sync::Stmt); + impl SelectBookStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> SelectBookQuery<'a, C, super::SelectBook, 0> { + SelectBookQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::SelectBookBorrowed { + name: row.get(0), + author: row.get(1), + }, + mapper: |it| ::from(it), + } + } + } + pub fn find_books() -> FindBooksStmt { + FindBooksStmt(crate::client::sync::Stmt::new( + "SELECT * FROM book WHERE name = ANY ($1)", + )) + } + pub struct FindBooksStmt(crate::client::sync::Stmt); + impl FindBooksStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql, T2: crate::ArraySql>( + &'a mut self, + client: &'a mut C, + title: &'a T2, + ) -> FindBooksQuery<'a, C, super::FindBooks, 1> { + FindBooksQuery { + client, + params: [title], + stmt: &mut self.0, + extractor: |row| super::FindBooksBorrowed { + name: row.get(0), + author: row.get(1), + }, + mapper: |it| ::from(it), + } + } + } + pub fn params_use_twice() -> ParamsUseTwiceStmt { + ParamsUseTwiceStmt(crate::client::sync::Stmt::new( + "UPDATE book SET name = $1 WHERE length(name) > 42 AND length($1) < 42", + )) + } + pub struct ParamsUseTwiceStmt(crate::client::sync::Stmt); + impl ParamsUseTwiceStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + name: &'a T1, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[name]) + } + } + pub fn params_order() -> ParamsOrderStmt { + ParamsOrderStmt(crate::client::sync::Stmt::new( + "UPDATE imaginary SET c=$1, a=$2, z=$2, r=$1", + )) + } + pub struct ParamsOrderStmt(crate::client::sync::Stmt); + impl ParamsOrderStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + c: &'a i32, + a: &'a i32, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[c, a]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::ParamsOrderParams, Result, C> + for ParamsOrderStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::ParamsOrderParams, + ) -> Result { + self.bind(client, ¶ms.c, ¶ms.a) + } + } +} +pub mod async_ { + use crate::client::async_::GenericClient; + use futures::{self, StreamExt, TryStreamExt}; + pub struct SelectBookQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::SelectBookBorrowed, + mapper: fn(super::SelectBookBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SelectBookQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::SelectBookBorrowed) -> R, + ) -> SelectBookQuery<'a, C, R, N> { + SelectBookQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct FindBooksQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::FindBooksBorrowed, + mapper: fn(super::FindBooksBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> FindBooksQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::FindBooksBorrowed) -> R, + ) -> FindBooksQuery<'a, C, R, N> { + FindBooksQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub fn insert_book() -> InsertBookStmt { + InsertBookStmt(crate::client::async_::Stmt::new( + "INSERT INTO book (author, name) VALUES ($1, $2)", + )) + } + pub struct InsertBookStmt(crate::client::async_::Stmt); + impl InsertBookStmt { + pub async fn bind<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql>( + &'a mut self, + client: &'a C, + author: &'a Option, + name: &'a T2, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[author, name]).await + } + } + impl<'a, C: GenericClient + Send + Sync, T1: crate::StringSql, T2: crate::StringSql> + crate::client::async_::Params< + 'a, + super::InsertBookParams, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for InsertBookStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::InsertBookParams, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.author, ¶ms.name)) + } + } + pub fn select_book() -> SelectBookStmt { + SelectBookStmt(crate::client::async_::Stmt::new("SELECT * FROM book")) + } + pub struct SelectBookStmt(crate::client::async_::Stmt); + impl SelectBookStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> SelectBookQuery<'a, C, super::SelectBook, 0> { + SelectBookQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::SelectBookBorrowed { + name: row.get(0), + author: row.get(1), + }, + mapper: |it| ::from(it), + } + } + } + pub fn find_books() -> FindBooksStmt { + FindBooksStmt(crate::client::async_::Stmt::new( + "SELECT * FROM book WHERE name = ANY ($1)", + )) + } + pub struct FindBooksStmt(crate::client::async_::Stmt); + impl FindBooksStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql, T2: crate::ArraySql>( + &'a mut self, + client: &'a C, + title: &'a T2, + ) -> FindBooksQuery<'a, C, super::FindBooks, 1> { + FindBooksQuery { + client, + params: [title], + stmt: &mut self.0, + extractor: |row| super::FindBooksBorrowed { + name: row.get(0), + author: row.get(1), + }, + mapper: |it| ::from(it), + } + } + } + pub fn params_use_twice() -> ParamsUseTwiceStmt { + ParamsUseTwiceStmt(crate::client::async_::Stmt::new( + "UPDATE book SET name = $1 WHERE length(name) > 42 AND length($1) < 42", + )) + } + pub struct ParamsUseTwiceStmt(crate::client::async_::Stmt); + impl ParamsUseTwiceStmt { + pub async fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + name: &'a T1, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[name]).await + } + } + pub fn params_order() -> ParamsOrderStmt { + ParamsOrderStmt(crate::client::async_::Stmt::new( + "UPDATE imaginary SET c=$1, a=$2, z=$2, r=$1", + )) + } + pub struct ParamsOrderStmt(crate::client::async_::Stmt); + impl ParamsOrderStmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + c: &'a i32, + a: &'a i32, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[c, a]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::ParamsOrderParams, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for ParamsOrderStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::ParamsOrderParams, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.c, ¶ms.a)) + } + } +} diff --git a/test_codegen/codegen/src/queries/stress.rs b/test_codegen/codegen/src/queries/stress.rs new file mode 100644 index 00000000..b19193de --- /dev/null +++ b/test_codegen/codegen/src/queries/stress.rs @@ -0,0 +1,2760 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct EverythingParams< + T1: crate::StringSql, + T2: crate::StringSql, + T3: crate::BytesSql, + T4: crate::JsonSql, + T5: crate::JsonSql, +> { + pub bool_: bool, + pub boolean_: bool, + pub char_: i8, + pub smallint_: i16, + pub int2_: i16, + pub smallserial_: i16, + pub serial2_: i16, + pub int_: i32, + pub int4_: i32, + pub serial_: i32, + pub serial4_: i32, + pub bingint_: i64, + pub int8_: i64, + pub bigserial_: i64, + pub serial8_: i64, + pub float4_: f32, + pub real_: f32, + pub float8_: f64, + pub double_precision_: f64, + pub text_: T1, + pub varchar_: T2, + pub bytea_: T3, + pub timestamp_: time::PrimitiveDateTime, + pub timestamp_without_time_zone_: time::PrimitiveDateTime, + pub timestamptz_: time::OffsetDateTime, + pub timestamp_with_time_zone_: time::OffsetDateTime, + pub date_: time::Date, + pub time_: time::Time, + pub json_: T4, + pub jsonb_: T5, + pub uuid_: uuid::Uuid, + pub inet_: std::net::IpAddr, + pub macaddr_: eui48::MacAddress, + pub numeric_: rust_decimal::Decimal, +} +#[derive(Debug)] +pub struct EverythingArrayParams< + T1: crate::ArraySql, + T2: crate::ArraySql, + T3: crate::ArraySql, + T4: crate::ArraySql, + T5: crate::ArraySql, + T6: crate::ArraySql, + T7: crate::ArraySql, + T8: crate::ArraySql, + T9: crate::ArraySql, + T10: crate::ArraySql, + T11: crate::ArraySql, + T12: crate::ArraySql, + T13: crate::ArraySql, + T14: crate::StringSql, + T15: crate::ArraySql, + T16: crate::StringSql, + T17: crate::ArraySql, + T18: crate::BytesSql, + T19: crate::ArraySql, + T20: crate::ArraySql, + T21: crate::ArraySql, + T22: crate::ArraySql, + T23: crate::ArraySql, + T24: crate::ArraySql, + T25: crate::ArraySql, + T26: crate::JsonSql, + T27: crate::ArraySql, + T28: crate::JsonSql, + T29: crate::ArraySql, + T30: crate::ArraySql, + T31: crate::ArraySql, + T32: crate::ArraySql, + T33: crate::ArraySql, +> { + pub bool_: T1, + pub boolean_: T2, + pub char_: T3, + pub smallint_: T4, + pub int2_: T5, + pub int_: T6, + pub int4_: T7, + pub bingint_: T8, + pub int8_: T9, + pub float4_: T10, + pub real_: T11, + pub float8_: T12, + pub double_precision_: T13, + pub text_: T15, + pub varchar_: T17, + pub bytea_: T19, + pub timestamp_: T20, + pub timestamp_without_time_zone_: T21, + pub timestamptz_: T22, + pub timestamp_with_time_zone_: T23, + pub date_: T24, + pub time_: T25, + pub json_: T27, + pub jsonb_: T29, + pub uuid_: T30, + pub inet_: T31, + pub macaddr_: T32, + pub numeric_: T33, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct Everything { + pub bool_: bool, + pub boolean_: bool, + pub char_: i8, + pub smallint_: i16, + pub int2_: i16, + pub smallserial_: i16, + pub serial2_: i16, + pub int_: i32, + pub int4_: i32, + pub serial_: i32, + pub serial4_: i32, + pub bingint_: i64, + pub int8_: i64, + pub bigserial_: i64, + pub serial8_: i64, + pub float4_: f32, + pub real_: f32, + pub float8_: f64, + pub double_precision_: f64, + pub text_: String, + pub varchar_: String, + pub bytea_: Vec, + pub timestamp_: time::PrimitiveDateTime, + pub timestamp_without_time_zone_: time::PrimitiveDateTime, + pub timestamptz_: time::OffsetDateTime, + pub timestamp_with_time_zone_: time::OffsetDateTime, + pub date_: time::Date, + pub time_: time::Time, + pub json_: serde_json::Value, + pub jsonb_: serde_json::Value, + pub uuid_: uuid::Uuid, + pub inet_: std::net::IpAddr, + pub macaddr_: eui48::MacAddress, + pub numeric_: rust_decimal::Decimal, +} +pub struct EverythingBorrowed<'a> { + pub bool_: bool, + pub boolean_: bool, + pub char_: i8, + pub smallint_: i16, + pub int2_: i16, + pub smallserial_: i16, + pub serial2_: i16, + pub int_: i32, + pub int4_: i32, + pub serial_: i32, + pub serial4_: i32, + pub bingint_: i64, + pub int8_: i64, + pub bigserial_: i64, + pub serial8_: i64, + pub float4_: f32, + pub real_: f32, + pub float8_: f64, + pub double_precision_: f64, + pub text_: &'a str, + pub varchar_: &'a str, + pub bytea_: &'a [u8], + pub timestamp_: time::PrimitiveDateTime, + pub timestamp_without_time_zone_: time::PrimitiveDateTime, + pub timestamptz_: time::OffsetDateTime, + pub timestamp_with_time_zone_: time::OffsetDateTime, + pub date_: time::Date, + pub time_: time::Time, + pub json_: postgres_types::Json<&'a serde_json::value::RawValue>, + pub jsonb_: postgres_types::Json<&'a serde_json::value::RawValue>, + pub uuid_: uuid::Uuid, + pub inet_: std::net::IpAddr, + pub macaddr_: eui48::MacAddress, + pub numeric_: rust_decimal::Decimal, +} +impl<'a> From> for Everything { + fn from( + EverythingBorrowed { + bool_, + boolean_, + char_, + smallint_, + int2_, + smallserial_, + serial2_, + int_, + int4_, + serial_, + serial4_, + bingint_, + int8_, + bigserial_, + serial8_, + float4_, + real_, + float8_, + double_precision_, + text_, + varchar_, + bytea_, + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_, + jsonb_, + uuid_, + inet_, + macaddr_, + numeric_, + }: EverythingBorrowed<'a>, + ) -> Self { + Self { + bool_, + boolean_, + char_, + smallint_, + int2_, + smallserial_, + serial2_, + int_, + int4_, + serial_, + serial4_, + bingint_, + int8_, + bigserial_, + serial8_, + float4_, + real_, + float8_, + double_precision_, + text_: text_.into(), + varchar_: varchar_.into(), + bytea_: bytea_.into(), + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_: serde_json::from_str(json_.0.get()).unwrap(), + jsonb_: serde_json::from_str(jsonb_.0.get()).unwrap(), + uuid_, + inet_, + macaddr_, + numeric_, + } + } +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct EverythingNull { + pub bool_: Option, + pub boolean_: Option, + pub char_: Option, + pub smallint_: Option, + pub int2_: Option, + pub smallserial_: Option, + pub serial2_: Option, + pub int_: Option, + pub int4_: Option, + pub serial_: Option, + pub serial4_: Option, + pub bingint_: Option, + pub int8_: Option, + pub bigserial_: Option, + pub serial8_: Option, + pub float4_: Option, + pub real_: Option, + pub float8_: Option, + pub double_precision_: Option, + pub text_: Option, + pub varchar_: Option, + pub bytea_: Option>, + pub timestamp_: Option, + pub timestamp_without_time_zone_: Option, + pub timestamptz_: Option, + pub timestamp_with_time_zone_: Option, + pub date_: Option, + pub time_: Option, + pub json_: Option, + pub jsonb_: Option, + pub uuid_: Option, + pub inet_: Option, + pub macaddr_: Option, + pub numeric_: Option, +} +pub struct EverythingNullBorrowed<'a> { + pub bool_: Option, + pub boolean_: Option, + pub char_: Option, + pub smallint_: Option, + pub int2_: Option, + pub smallserial_: Option, + pub serial2_: Option, + pub int_: Option, + pub int4_: Option, + pub serial_: Option, + pub serial4_: Option, + pub bingint_: Option, + pub int8_: Option, + pub bigserial_: Option, + pub serial8_: Option, + pub float4_: Option, + pub real_: Option, + pub float8_: Option, + pub double_precision_: Option, + pub text_: Option<&'a str>, + pub varchar_: Option<&'a str>, + pub bytea_: Option<&'a [u8]>, + pub timestamp_: Option, + pub timestamp_without_time_zone_: Option, + pub timestamptz_: Option, + pub timestamp_with_time_zone_: Option, + pub date_: Option, + pub time_: Option, + pub json_: Option>, + pub jsonb_: Option>, + pub uuid_: Option, + pub inet_: Option, + pub macaddr_: Option, + pub numeric_: Option, +} +impl<'a> From> for EverythingNull { + fn from( + EverythingNullBorrowed { + bool_, + boolean_, + char_, + smallint_, + int2_, + smallserial_, + serial2_, + int_, + int4_, + serial_, + serial4_, + bingint_, + int8_, + bigserial_, + serial8_, + float4_, + real_, + float8_, + double_precision_, + text_, + varchar_, + bytea_, + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_, + jsonb_, + uuid_, + inet_, + macaddr_, + numeric_, + }: EverythingNullBorrowed<'a>, + ) -> Self { + Self { + bool_, + boolean_, + char_, + smallint_, + int2_, + smallserial_, + serial2_, + int_, + int4_, + serial_, + serial4_, + bingint_, + int8_, + bigserial_, + serial8_, + float4_, + real_, + float8_, + double_precision_, + text_: text_.map(|v| v.into()), + varchar_: varchar_.map(|v| v.into()), + bytea_: bytea_.map(|v| v.into()), + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_: json_.map(|v| serde_json::from_str(v.0.get()).unwrap()), + jsonb_: jsonb_.map(|v| serde_json::from_str(v.0.get()).unwrap()), + uuid_, + inet_, + macaddr_, + numeric_, + } + } +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct EverythingArray { + pub bool_: Vec, + pub boolean_: Vec, + pub char_: Vec, + pub smallint_: Vec, + pub int2_: Vec, + pub int_: Vec, + pub int4_: Vec, + pub bingint_: Vec, + pub int8_: Vec, + pub float4_: Vec, + pub real_: Vec, + pub float8_: Vec, + pub double_precision_: Vec, + pub text_: Vec, + pub varchar_: Vec, + pub bytea_: Vec>, + pub timestamp_: Vec, + pub timestamp_without_time_zone_: Vec, + pub timestamptz_: Vec, + pub timestamp_with_time_zone_: Vec, + pub date_: Vec, + pub time_: Vec, + pub json_: Vec, + pub jsonb_: Vec, + pub uuid_: Vec, + pub inet_: Vec, + pub macaddr_: Vec, + pub numeric_: Vec, +} +pub struct EverythingArrayBorrowed<'a> { + pub bool_: crate::ArrayIterator<'a, bool>, + pub boolean_: crate::ArrayIterator<'a, bool>, + pub char_: crate::ArrayIterator<'a, i8>, + pub smallint_: crate::ArrayIterator<'a, i16>, + pub int2_: crate::ArrayIterator<'a, i16>, + pub int_: crate::ArrayIterator<'a, i32>, + pub int4_: crate::ArrayIterator<'a, i32>, + pub bingint_: crate::ArrayIterator<'a, i64>, + pub int8_: crate::ArrayIterator<'a, i64>, + pub float4_: crate::ArrayIterator<'a, f32>, + pub real_: crate::ArrayIterator<'a, f32>, + pub float8_: crate::ArrayIterator<'a, f64>, + pub double_precision_: crate::ArrayIterator<'a, f64>, + pub text_: crate::ArrayIterator<'a, &'a str>, + pub varchar_: crate::ArrayIterator<'a, &'a str>, + pub bytea_: crate::ArrayIterator<'a, &'a [u8]>, + pub timestamp_: crate::ArrayIterator<'a, time::PrimitiveDateTime>, + pub timestamp_without_time_zone_: crate::ArrayIterator<'a, time::PrimitiveDateTime>, + pub timestamptz_: crate::ArrayIterator<'a, time::OffsetDateTime>, + pub timestamp_with_time_zone_: crate::ArrayIterator<'a, time::OffsetDateTime>, + pub date_: crate::ArrayIterator<'a, time::Date>, + pub time_: crate::ArrayIterator<'a, time::Time>, + pub json_: crate::ArrayIterator<'a, postgres_types::Json<&'a serde_json::value::RawValue>>, + pub jsonb_: crate::ArrayIterator<'a, postgres_types::Json<&'a serde_json::value::RawValue>>, + pub uuid_: crate::ArrayIterator<'a, uuid::Uuid>, + pub inet_: crate::ArrayIterator<'a, std::net::IpAddr>, + pub macaddr_: crate::ArrayIterator<'a, eui48::MacAddress>, + pub numeric_: crate::ArrayIterator<'a, rust_decimal::Decimal>, +} +impl<'a> From> for EverythingArray { + fn from( + EverythingArrayBorrowed { + bool_, + boolean_, + char_, + smallint_, + int2_, + int_, + int4_, + bingint_, + int8_, + float4_, + real_, + float8_, + double_precision_, + text_, + varchar_, + bytea_, + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_, + jsonb_, + uuid_, + inet_, + macaddr_, + numeric_, + }: EverythingArrayBorrowed<'a>, + ) -> Self { + Self { + bool_: bool_.map(|v| v).collect(), + boolean_: boolean_.map(|v| v).collect(), + char_: char_.map(|v| v).collect(), + smallint_: smallint_.map(|v| v).collect(), + int2_: int2_.map(|v| v).collect(), + int_: int_.map(|v| v).collect(), + int4_: int4_.map(|v| v).collect(), + bingint_: bingint_.map(|v| v).collect(), + int8_: int8_.map(|v| v).collect(), + float4_: float4_.map(|v| v).collect(), + real_: real_.map(|v| v).collect(), + float8_: float8_.map(|v| v).collect(), + double_precision_: double_precision_.map(|v| v).collect(), + text_: text_.map(|v| v.into()).collect(), + varchar_: varchar_.map(|v| v.into()).collect(), + bytea_: bytea_.map(|v| v.into()).collect(), + timestamp_: timestamp_.map(|v| v).collect(), + timestamp_without_time_zone_: timestamp_without_time_zone_.map(|v| v).collect(), + timestamptz_: timestamptz_.map(|v| v).collect(), + timestamp_with_time_zone_: timestamp_with_time_zone_.map(|v| v).collect(), + date_: date_.map(|v| v).collect(), + time_: time_.map(|v| v).collect(), + json_: json_ + .map(|v| serde_json::from_str(v.0.get()).unwrap()) + .collect(), + jsonb_: jsonb_ + .map(|v| serde_json::from_str(v.0.get()).unwrap()) + .collect(), + uuid_: uuid_.map(|v| v).collect(), + inet_: inet_.map(|v| v).collect(), + macaddr_: macaddr_.map(|v| v).collect(), + numeric_: numeric_.map(|v| v).collect(), + } + } +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct EverythingArrayNull { + pub bool_: Option>, + pub boolean_: Option>, + pub char_: Option>, + pub smallint_: Option>, + pub int2_: Option>, + pub int_: Option>, + pub int4_: Option>, + pub bingint_: Option>, + pub int8_: Option>, + pub float4_: Option>, + pub real_: Option>, + pub float8_: Option>, + pub double_precision_: Option>, + pub text_: Option>, + pub varchar_: Option>, + pub bytea_: Option>>, + pub timestamp_: Option>, + pub timestamp_without_time_zone_: Option>, + pub timestamptz_: Option>, + pub timestamp_with_time_zone_: Option>, + pub date_: Option>, + pub time_: Option>, + pub json_: Option>, + pub jsonb_: Option>, + pub uuid_: Option>, + pub inet_: Option>, + pub macaddr_: Option>, + pub numeric_: Option>, +} +pub struct EverythingArrayNullBorrowed<'a> { + pub bool_: Option>, + pub boolean_: Option>, + pub char_: Option>, + pub smallint_: Option>, + pub int2_: Option>, + pub int_: Option>, + pub int4_: Option>, + pub bingint_: Option>, + pub int8_: Option>, + pub float4_: Option>, + pub real_: Option>, + pub float8_: Option>, + pub double_precision_: Option>, + pub text_: Option>, + pub varchar_: Option>, + pub bytea_: Option>, + pub timestamp_: Option>, + pub timestamp_without_time_zone_: Option>, + pub timestamptz_: Option>, + pub timestamp_with_time_zone_: Option>, + pub date_: Option>, + pub time_: Option>, + pub json_: + Option>>, + pub jsonb_: + Option>>, + pub uuid_: Option>, + pub inet_: Option>, + pub macaddr_: Option>, + pub numeric_: Option>, +} +impl<'a> From> for EverythingArrayNull { + fn from( + EverythingArrayNullBorrowed { + bool_, + boolean_, + char_, + smallint_, + int2_, + int_, + int4_, + bingint_, + int8_, + float4_, + real_, + float8_, + double_precision_, + text_, + varchar_, + bytea_, + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_, + jsonb_, + uuid_, + inet_, + macaddr_, + numeric_, + }: EverythingArrayNullBorrowed<'a>, + ) -> Self { + Self { + bool_: bool_.map(|v| v.map(|v| v).collect()), + boolean_: boolean_.map(|v| v.map(|v| v).collect()), + char_: char_.map(|v| v.map(|v| v).collect()), + smallint_: smallint_.map(|v| v.map(|v| v).collect()), + int2_: int2_.map(|v| v.map(|v| v).collect()), + int_: int_.map(|v| v.map(|v| v).collect()), + int4_: int4_.map(|v| v.map(|v| v).collect()), + bingint_: bingint_.map(|v| v.map(|v| v).collect()), + int8_: int8_.map(|v| v.map(|v| v).collect()), + float4_: float4_.map(|v| v.map(|v| v).collect()), + real_: real_.map(|v| v.map(|v| v).collect()), + float8_: float8_.map(|v| v.map(|v| v).collect()), + double_precision_: double_precision_.map(|v| v.map(|v| v).collect()), + text_: text_.map(|v| v.map(|v| v.into()).collect()), + varchar_: varchar_.map(|v| v.map(|v| v.into()).collect()), + bytea_: bytea_.map(|v| v.map(|v| v.into()).collect()), + timestamp_: timestamp_.map(|v| v.map(|v| v).collect()), + timestamp_without_time_zone_: timestamp_without_time_zone_ + .map(|v| v.map(|v| v).collect()), + timestamptz_: timestamptz_.map(|v| v.map(|v| v).collect()), + timestamp_with_time_zone_: timestamp_with_time_zone_.map(|v| v.map(|v| v).collect()), + date_: date_.map(|v| v.map(|v| v).collect()), + time_: time_.map(|v| v.map(|v| v).collect()), + json_: json_.map(|v| { + v.map(|v| serde_json::from_str(v.0.get()).unwrap()) + .collect() + }), + jsonb_: jsonb_.map(|v| { + v.map(|v| serde_json::from_str(v.0.get()).unwrap()) + .collect() + }), + uuid_: uuid_.map(|v| v.map(|v| v).collect()), + inet_: inet_.map(|v| v.map(|v| v).collect()), + macaddr_: macaddr_.map(|v| v.map(|v| v).collect()), + numeric_: numeric_.map(|v| v.map(|v| v).collect()), + } + } +} +pub mod sync { + use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + pub struct EverythingQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::EverythingBorrowed, + mapper: fn(super::EverythingBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> EverythingQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::EverythingBorrowed) -> R, + ) -> EverythingQuery<'a, C, R, N> { + EverythingQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct EverythingNullQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::EverythingNullBorrowed, + mapper: fn(super::EverythingNullBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> EverythingNullQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::EverythingNullBorrowed) -> R, + ) -> EverythingNullQuery<'a, C, R, N> { + EverythingNullQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct EverythingArrayQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::EverythingArrayBorrowed, + mapper: fn(super::EverythingArrayBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> EverythingArrayQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::EverythingArrayBorrowed) -> R, + ) -> EverythingArrayQuery<'a, C, R, N> { + EverythingArrayQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct EverythingArrayNullQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::EverythingArrayNullBorrowed, + mapper: fn(super::EverythingArrayNullBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> EverythingArrayNullQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::EverythingArrayNullBorrowed) -> R, + ) -> EverythingArrayNullQuery<'a, C, R, N> { + EverythingArrayNullQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct NightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> crate::types::NightmareCompositeBorrowed, + mapper: fn(crate::types::NightmareCompositeBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> NightmareCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::NightmareCompositeBorrowed) -> R, + ) -> NightmareCompositeQuery<'a, C, R, N> { + NightmareCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct SchemaNightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> crate::types::schema::NightmareCompositeBorrowed, + mapper: fn(crate::types::schema::NightmareCompositeBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SchemaNightmareCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::schema::NightmareCompositeBorrowed) -> R, + ) -> SchemaNightmareCompositeQuery<'a, C, R, N> { + SchemaNightmareCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub fn select_everything() -> SelectEverythingStmt { + SelectEverythingStmt(crate::client::sync::Stmt::new( + "SELECT + * +FROM + Everything", + )) + } + pub struct SelectEverythingStmt(crate::client::sync::Stmt); + impl SelectEverythingStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> EverythingQuery<'a, C, super::Everything, 0> { + EverythingQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::EverythingBorrowed { + bool_: row.get(0), + boolean_: row.get(1), + char_: row.get(2), + smallint_: row.get(3), + int2_: row.get(4), + smallserial_: row.get(5), + serial2_: row.get(6), + int_: row.get(7), + int4_: row.get(8), + serial_: row.get(9), + serial4_: row.get(10), + bingint_: row.get(11), + int8_: row.get(12), + bigserial_: row.get(13), + serial8_: row.get(14), + float4_: row.get(15), + real_: row.get(16), + float8_: row.get(17), + double_precision_: row.get(18), + text_: row.get(19), + varchar_: row.get(20), + bytea_: row.get(21), + timestamp_: row.get(22), + timestamp_without_time_zone_: row.get(23), + timestamptz_: row.get(24), + timestamp_with_time_zone_: row.get(25), + date_: row.get(26), + time_: row.get(27), + json_: row.get(28), + jsonb_: row.get(29), + uuid_: row.get(30), + inet_: row.get(31), + macaddr_: row.get(32), + numeric_: row.get(33), + }, + mapper: |it| ::from(it), + } + } + } + pub fn select_everything_null() -> SelectEverythingNullStmt { + SelectEverythingNullStmt(crate::client::sync::Stmt::new( + "SELECT + * +FROM + Everything", + )) + } + pub struct SelectEverythingNullStmt(crate::client::sync::Stmt); + impl SelectEverythingNullStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> EverythingNullQuery<'a, C, super::EverythingNull, 0> { + EverythingNullQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::EverythingNullBorrowed { + bool_: row.get(0), + boolean_: row.get(1), + char_: row.get(2), + smallint_: row.get(3), + int2_: row.get(4), + smallserial_: row.get(5), + serial2_: row.get(6), + int_: row.get(7), + int4_: row.get(8), + serial_: row.get(9), + serial4_: row.get(10), + bingint_: row.get(11), + int8_: row.get(12), + bigserial_: row.get(13), + serial8_: row.get(14), + float4_: row.get(15), + real_: row.get(16), + float8_: row.get(17), + double_precision_: row.get(18), + text_: row.get(19), + varchar_: row.get(20), + bytea_: row.get(21), + timestamp_: row.get(22), + timestamp_without_time_zone_: row.get(23), + timestamptz_: row.get(24), + timestamp_with_time_zone_: row.get(25), + date_: row.get(26), + time_: row.get(27), + json_: row.get(28), + jsonb_: row.get(29), + uuid_: row.get(30), + inet_: row.get(31), + macaddr_: row.get(32), + numeric_: row.get(33), + }, + mapper: |it| ::from(it), + } + } + } + pub fn insert_everything() -> InsertEverythingStmt { + InsertEverythingStmt(crate::client::sync::Stmt::new("INSERT INTO Everything (bool_, boolean_, char_, smallint_, int2_, smallserial_, serial2_, int_, int4_, serial_, serial4_, bingint_, int8_, bigserial_, serial8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)")) + } + pub struct InsertEverythingStmt(crate::client::sync::Stmt); + impl InsertEverythingStmt { + pub fn bind< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::StringSql, + T3: crate::BytesSql, + T4: crate::JsonSql, + T5: crate::JsonSql, + >( + &'a mut self, + client: &'a mut C, + bool_: &'a bool, + boolean_: &'a bool, + char_: &'a i8, + smallint_: &'a i16, + int2_: &'a i16, + smallserial_: &'a i16, + serial2_: &'a i16, + int_: &'a i32, + int4_: &'a i32, + serial_: &'a i32, + serial4_: &'a i32, + bingint_: &'a i64, + int8_: &'a i64, + bigserial_: &'a i64, + serial8_: &'a i64, + float4_: &'a f32, + real_: &'a f32, + float8_: &'a f64, + double_precision_: &'a f64, + text_: &'a T1, + varchar_: &'a T2, + bytea_: &'a T3, + timestamp_: &'a time::PrimitiveDateTime, + timestamp_without_time_zone_: &'a time::PrimitiveDateTime, + timestamptz_: &'a time::OffsetDateTime, + timestamp_with_time_zone_: &'a time::OffsetDateTime, + date_: &'a time::Date, + time_: &'a time::Time, + json_: &'a T4, + jsonb_: &'a T5, + uuid_: &'a uuid::Uuid, + inet_: &'a std::net::IpAddr, + macaddr_: &'a eui48::MacAddress, + numeric_: &'a rust_decimal::Decimal, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute( + stmt, + &[ + bool_, + boolean_, + char_, + smallint_, + int2_, + smallserial_, + serial2_, + int_, + int4_, + serial_, + serial4_, + bingint_, + int8_, + bigserial_, + serial8_, + float4_, + real_, + float8_, + double_precision_, + text_, + varchar_, + bytea_, + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_, + jsonb_, + uuid_, + inet_, + macaddr_, + numeric_, + ], + ) + } + } + impl< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::StringSql, + T3: crate::BytesSql, + T4: crate::JsonSql, + T5: crate::JsonSql, + > + crate::client::sync::Params< + 'a, + super::EverythingParams, + Result, + C, + > for InsertEverythingStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::EverythingParams, + ) -> Result { + self.bind( + client, + ¶ms.bool_, + ¶ms.boolean_, + ¶ms.char_, + ¶ms.smallint_, + ¶ms.int2_, + ¶ms.smallserial_, + ¶ms.serial2_, + ¶ms.int_, + ¶ms.int4_, + ¶ms.serial_, + ¶ms.serial4_, + ¶ms.bingint_, + ¶ms.int8_, + ¶ms.bigserial_, + ¶ms.serial8_, + ¶ms.float4_, + ¶ms.real_, + ¶ms.float8_, + ¶ms.double_precision_, + ¶ms.text_, + ¶ms.varchar_, + ¶ms.bytea_, + ¶ms.timestamp_, + ¶ms.timestamp_without_time_zone_, + ¶ms.timestamptz_, + ¶ms.timestamp_with_time_zone_, + ¶ms.date_, + ¶ms.time_, + ¶ms.json_, + ¶ms.jsonb_, + ¶ms.uuid_, + ¶ms.inet_, + ¶ms.macaddr_, + ¶ms.numeric_, + ) + } + } + pub fn select_everything_array() -> SelectEverythingArrayStmt { + SelectEverythingArrayStmt(crate::client::sync::Stmt::new( + "SELECT + * +FROM + EverythingArray", + )) + } + pub struct SelectEverythingArrayStmt(crate::client::sync::Stmt); + impl SelectEverythingArrayStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> EverythingArrayQuery<'a, C, super::EverythingArray, 0> { + EverythingArrayQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::EverythingArrayBorrowed { + bool_: row.get(0), + boolean_: row.get(1), + char_: row.get(2), + smallint_: row.get(3), + int2_: row.get(4), + int_: row.get(5), + int4_: row.get(6), + bingint_: row.get(7), + int8_: row.get(8), + float4_: row.get(9), + real_: row.get(10), + float8_: row.get(11), + double_precision_: row.get(12), + text_: row.get(13), + varchar_: row.get(14), + bytea_: row.get(15), + timestamp_: row.get(16), + timestamp_without_time_zone_: row.get(17), + timestamptz_: row.get(18), + timestamp_with_time_zone_: row.get(19), + date_: row.get(20), + time_: row.get(21), + json_: row.get(22), + jsonb_: row.get(23), + uuid_: row.get(24), + inet_: row.get(25), + macaddr_: row.get(26), + numeric_: row.get(27), + }, + mapper: |it| ::from(it), + } + } + } + pub fn select_everything_array_null() -> SelectEverythingArrayNullStmt { + SelectEverythingArrayNullStmt(crate::client::sync::Stmt::new( + "SELECT + * +FROM + EverythingArray", + )) + } + pub struct SelectEverythingArrayNullStmt(crate::client::sync::Stmt); + impl SelectEverythingArrayNullStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> EverythingArrayNullQuery<'a, C, super::EverythingArrayNull, 0> { + EverythingArrayNullQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::EverythingArrayNullBorrowed { + bool_: row.get(0), + boolean_: row.get(1), + char_: row.get(2), + smallint_: row.get(3), + int2_: row.get(4), + int_: row.get(5), + int4_: row.get(6), + bingint_: row.get(7), + int8_: row.get(8), + float4_: row.get(9), + real_: row.get(10), + float8_: row.get(11), + double_precision_: row.get(12), + text_: row.get(13), + varchar_: row.get(14), + bytea_: row.get(15), + timestamp_: row.get(16), + timestamp_without_time_zone_: row.get(17), + timestamptz_: row.get(18), + timestamp_with_time_zone_: row.get(19), + date_: row.get(20), + time_: row.get(21), + json_: row.get(22), + jsonb_: row.get(23), + uuid_: row.get(24), + inet_: row.get(25), + macaddr_: row.get(26), + numeric_: row.get(27), + }, + mapper: |it| ::from(it), + } + } + } + pub fn insert_everything_array() -> InsertEverythingArrayStmt { + InsertEverythingArrayStmt(crate::client::sync::Stmt::new("INSERT INTO EverythingArray (bool_, boolean_, char_, smallint_, int2_, int_, int4_, bingint_, int8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)")) + } + pub struct InsertEverythingArrayStmt(crate::client::sync::Stmt); + impl InsertEverythingArrayStmt { + pub fn bind< + 'a, + C: GenericClient, + T1: crate::ArraySql, + T2: crate::ArraySql, + T3: crate::ArraySql, + T4: crate::ArraySql, + T5: crate::ArraySql, + T6: crate::ArraySql, + T7: crate::ArraySql, + T8: crate::ArraySql, + T9: crate::ArraySql, + T10: crate::ArraySql, + T11: crate::ArraySql, + T12: crate::ArraySql, + T13: crate::ArraySql, + T14: crate::StringSql, + T15: crate::ArraySql, + T16: crate::StringSql, + T17: crate::ArraySql, + T18: crate::BytesSql, + T19: crate::ArraySql, + T20: crate::ArraySql, + T21: crate::ArraySql, + T22: crate::ArraySql, + T23: crate::ArraySql, + T24: crate::ArraySql, + T25: crate::ArraySql, + T26: crate::JsonSql, + T27: crate::ArraySql, + T28: crate::JsonSql, + T29: crate::ArraySql, + T30: crate::ArraySql, + T31: crate::ArraySql, + T32: crate::ArraySql, + T33: crate::ArraySql, + >( + &'a mut self, + client: &'a mut C, + bool_: &'a T1, + boolean_: &'a T2, + char_: &'a T3, + smallint_: &'a T4, + int2_: &'a T5, + int_: &'a T6, + int4_: &'a T7, + bingint_: &'a T8, + int8_: &'a T9, + float4_: &'a T10, + real_: &'a T11, + float8_: &'a T12, + double_precision_: &'a T13, + text_: &'a T15, + varchar_: &'a T17, + bytea_: &'a T19, + timestamp_: &'a T20, + timestamp_without_time_zone_: &'a T21, + timestamptz_: &'a T22, + timestamp_with_time_zone_: &'a T23, + date_: &'a T24, + time_: &'a T25, + json_: &'a T27, + jsonb_: &'a T29, + uuid_: &'a T30, + inet_: &'a T31, + macaddr_: &'a T32, + numeric_: &'a T33, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute( + stmt, + &[ + bool_, + boolean_, + char_, + smallint_, + int2_, + int_, + int4_, + bingint_, + int8_, + float4_, + real_, + float8_, + double_precision_, + text_, + varchar_, + bytea_, + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_, + jsonb_, + uuid_, + inet_, + macaddr_, + numeric_, + ], + ) + } + } + impl< + 'a, + C: GenericClient, + T1: crate::ArraySql, + T2: crate::ArraySql, + T3: crate::ArraySql, + T4: crate::ArraySql, + T5: crate::ArraySql, + T6: crate::ArraySql, + T7: crate::ArraySql, + T8: crate::ArraySql, + T9: crate::ArraySql, + T10: crate::ArraySql, + T11: crate::ArraySql, + T12: crate::ArraySql, + T13: crate::ArraySql, + T14: crate::StringSql, + T15: crate::ArraySql, + T16: crate::StringSql, + T17: crate::ArraySql, + T18: crate::BytesSql, + T19: crate::ArraySql, + T20: crate::ArraySql, + T21: crate::ArraySql, + T22: crate::ArraySql, + T23: crate::ArraySql, + T24: crate::ArraySql, + T25: crate::ArraySql, + T26: crate::JsonSql, + T27: crate::ArraySql, + T28: crate::JsonSql, + T29: crate::ArraySql, + T30: crate::ArraySql, + T31: crate::ArraySql, + T32: crate::ArraySql, + T33: crate::ArraySql, + > + crate::client::sync::Params< + 'a, + super::EverythingArrayParams< + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + T31, + T32, + T33, + >, + Result, + C, + > for InsertEverythingArrayStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::EverythingArrayParams< + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + T31, + T32, + T33, + >, + ) -> Result { + self.bind( + client, + ¶ms.bool_, + ¶ms.boolean_, + ¶ms.char_, + ¶ms.smallint_, + ¶ms.int2_, + ¶ms.int_, + ¶ms.int4_, + ¶ms.bingint_, + ¶ms.int8_, + ¶ms.float4_, + ¶ms.real_, + ¶ms.float8_, + ¶ms.double_precision_, + ¶ms.text_, + ¶ms.varchar_, + ¶ms.bytea_, + ¶ms.timestamp_, + ¶ms.timestamp_without_time_zone_, + ¶ms.timestamptz_, + ¶ms.timestamp_with_time_zone_, + ¶ms.date_, + ¶ms.time_, + ¶ms.json_, + ¶ms.jsonb_, + ¶ms.uuid_, + ¶ms.inet_, + ¶ms.macaddr_, + ¶ms.numeric_, + ) + } + } + pub fn select_nightmare() -> SelectNightmareStmt { + SelectNightmareStmt(crate::client::sync::Stmt::new( + "SELECT + * +FROM + nightmare", + )) + } + pub struct SelectNightmareStmt(crate::client::sync::Stmt); + impl SelectNightmareStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> NightmareCompositeQuery<'a, C, crate::types::NightmareComposite, 0> { + NightmareCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn insert_nightmare() -> InsertNightmareStmt { + InsertNightmareStmt(crate::client::sync::Stmt::new( + "INSERT INTO nightmare (composite) + VALUES ($1)", + )) + } + pub struct InsertNightmareStmt(crate::client::sync::Stmt); + impl InsertNightmareStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + composite: &'a crate::types::NightmareCompositeParams<'a>, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[composite]) + } + } + pub fn select_schema_nightmare() -> SelectSchemaNightmareStmt { + SelectSchemaNightmareStmt(crate::client::sync::Stmt::new( + "SELECT + * +FROM + schema.nightmare", + )) + } + pub struct SelectSchemaNightmareStmt(crate::client::sync::Stmt); + impl SelectSchemaNightmareStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> SchemaNightmareCompositeQuery<'a, C, crate::types::schema::NightmareComposite, 0> + { + SchemaNightmareCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn insert_schema_nightmare() -> InsertSchemaNightmareStmt { + InsertSchemaNightmareStmt(crate::client::sync::Stmt::new( + "INSERT INTO schema.nightmare (composite) + VALUES ($1)", + )) + } + pub struct InsertSchemaNightmareStmt(crate::client::sync::Stmt); + impl InsertSchemaNightmareStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + composite: &'a crate::types::schema::NightmareCompositeParams<'a>, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[composite]) + } + } +} +pub mod async_ { + use crate::client::async_::GenericClient; + use futures::{self, StreamExt, TryStreamExt}; + pub struct EverythingQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::EverythingBorrowed, + mapper: fn(super::EverythingBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> EverythingQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::EverythingBorrowed) -> R, + ) -> EverythingQuery<'a, C, R, N> { + EverythingQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct EverythingNullQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::EverythingNullBorrowed, + mapper: fn(super::EverythingNullBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> EverythingNullQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::EverythingNullBorrowed) -> R, + ) -> EverythingNullQuery<'a, C, R, N> { + EverythingNullQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct EverythingArrayQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::EverythingArrayBorrowed, + mapper: fn(super::EverythingArrayBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> EverythingArrayQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::EverythingArrayBorrowed) -> R, + ) -> EverythingArrayQuery<'a, C, R, N> { + EverythingArrayQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct EverythingArrayNullQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::EverythingArrayNullBorrowed, + mapper: fn(super::EverythingArrayNullBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> EverythingArrayNullQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(super::EverythingArrayNullBorrowed) -> R, + ) -> EverythingArrayNullQuery<'a, C, R, N> { + EverythingArrayNullQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct NightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> crate::types::NightmareCompositeBorrowed, + mapper: fn(crate::types::NightmareCompositeBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> NightmareCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::NightmareCompositeBorrowed) -> R, + ) -> NightmareCompositeQuery<'a, C, R, N> { + NightmareCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct SchemaNightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> crate::types::schema::NightmareCompositeBorrowed, + mapper: fn(crate::types::schema::NightmareCompositeBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> SchemaNightmareCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::schema::NightmareCompositeBorrowed) -> R, + ) -> SchemaNightmareCompositeQuery<'a, C, R, N> { + SchemaNightmareCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub fn select_everything() -> SelectEverythingStmt { + SelectEverythingStmt(crate::client::async_::Stmt::new( + "SELECT + * +FROM + Everything", + )) + } + pub struct SelectEverythingStmt(crate::client::async_::Stmt); + impl SelectEverythingStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> EverythingQuery<'a, C, super::Everything, 0> { + EverythingQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::EverythingBorrowed { + bool_: row.get(0), + boolean_: row.get(1), + char_: row.get(2), + smallint_: row.get(3), + int2_: row.get(4), + smallserial_: row.get(5), + serial2_: row.get(6), + int_: row.get(7), + int4_: row.get(8), + serial_: row.get(9), + serial4_: row.get(10), + bingint_: row.get(11), + int8_: row.get(12), + bigserial_: row.get(13), + serial8_: row.get(14), + float4_: row.get(15), + real_: row.get(16), + float8_: row.get(17), + double_precision_: row.get(18), + text_: row.get(19), + varchar_: row.get(20), + bytea_: row.get(21), + timestamp_: row.get(22), + timestamp_without_time_zone_: row.get(23), + timestamptz_: row.get(24), + timestamp_with_time_zone_: row.get(25), + date_: row.get(26), + time_: row.get(27), + json_: row.get(28), + jsonb_: row.get(29), + uuid_: row.get(30), + inet_: row.get(31), + macaddr_: row.get(32), + numeric_: row.get(33), + }, + mapper: |it| ::from(it), + } + } + } + pub fn select_everything_null() -> SelectEverythingNullStmt { + SelectEverythingNullStmt(crate::client::async_::Stmt::new( + "SELECT + * +FROM + Everything", + )) + } + pub struct SelectEverythingNullStmt(crate::client::async_::Stmt); + impl SelectEverythingNullStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> EverythingNullQuery<'a, C, super::EverythingNull, 0> { + EverythingNullQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::EverythingNullBorrowed { + bool_: row.get(0), + boolean_: row.get(1), + char_: row.get(2), + smallint_: row.get(3), + int2_: row.get(4), + smallserial_: row.get(5), + serial2_: row.get(6), + int_: row.get(7), + int4_: row.get(8), + serial_: row.get(9), + serial4_: row.get(10), + bingint_: row.get(11), + int8_: row.get(12), + bigserial_: row.get(13), + serial8_: row.get(14), + float4_: row.get(15), + real_: row.get(16), + float8_: row.get(17), + double_precision_: row.get(18), + text_: row.get(19), + varchar_: row.get(20), + bytea_: row.get(21), + timestamp_: row.get(22), + timestamp_without_time_zone_: row.get(23), + timestamptz_: row.get(24), + timestamp_with_time_zone_: row.get(25), + date_: row.get(26), + time_: row.get(27), + json_: row.get(28), + jsonb_: row.get(29), + uuid_: row.get(30), + inet_: row.get(31), + macaddr_: row.get(32), + numeric_: row.get(33), + }, + mapper: |it| ::from(it), + } + } + } + pub fn insert_everything() -> InsertEverythingStmt { + InsertEverythingStmt(crate::client::async_::Stmt::new("INSERT INTO Everything (bool_, boolean_, char_, smallint_, int2_, smallserial_, serial2_, int_, int4_, serial_, serial4_, bingint_, int8_, bigserial_, serial8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)")) + } + pub struct InsertEverythingStmt(crate::client::async_::Stmt); + impl InsertEverythingStmt { + pub async fn bind< + 'a, + C: GenericClient, + T1: crate::StringSql, + T2: crate::StringSql, + T3: crate::BytesSql, + T4: crate::JsonSql, + T5: crate::JsonSql, + >( + &'a mut self, + client: &'a C, + bool_: &'a bool, + boolean_: &'a bool, + char_: &'a i8, + smallint_: &'a i16, + int2_: &'a i16, + smallserial_: &'a i16, + serial2_: &'a i16, + int_: &'a i32, + int4_: &'a i32, + serial_: &'a i32, + serial4_: &'a i32, + bingint_: &'a i64, + int8_: &'a i64, + bigserial_: &'a i64, + serial8_: &'a i64, + float4_: &'a f32, + real_: &'a f32, + float8_: &'a f64, + double_precision_: &'a f64, + text_: &'a T1, + varchar_: &'a T2, + bytea_: &'a T3, + timestamp_: &'a time::PrimitiveDateTime, + timestamp_without_time_zone_: &'a time::PrimitiveDateTime, + timestamptz_: &'a time::OffsetDateTime, + timestamp_with_time_zone_: &'a time::OffsetDateTime, + date_: &'a time::Date, + time_: &'a time::Time, + json_: &'a T4, + jsonb_: &'a T5, + uuid_: &'a uuid::Uuid, + inet_: &'a std::net::IpAddr, + macaddr_: &'a eui48::MacAddress, + numeric_: &'a rust_decimal::Decimal, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client + .execute( + stmt, + &[ + bool_, + boolean_, + char_, + smallint_, + int2_, + smallserial_, + serial2_, + int_, + int4_, + serial_, + serial4_, + bingint_, + int8_, + bigserial_, + serial8_, + float4_, + real_, + float8_, + double_precision_, + text_, + varchar_, + bytea_, + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_, + jsonb_, + uuid_, + inet_, + macaddr_, + numeric_, + ], + ) + .await + } + } + impl< + 'a, + C: GenericClient + Send + Sync, + T1: crate::StringSql, + T2: crate::StringSql, + T3: crate::BytesSql, + T4: crate::JsonSql, + T5: crate::JsonSql, + > + crate::client::async_::Params< + 'a, + super::EverythingParams, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for InsertEverythingStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::EverythingParams, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind( + client, + ¶ms.bool_, + ¶ms.boolean_, + ¶ms.char_, + ¶ms.smallint_, + ¶ms.int2_, + ¶ms.smallserial_, + ¶ms.serial2_, + ¶ms.int_, + ¶ms.int4_, + ¶ms.serial_, + ¶ms.serial4_, + ¶ms.bingint_, + ¶ms.int8_, + ¶ms.bigserial_, + ¶ms.serial8_, + ¶ms.float4_, + ¶ms.real_, + ¶ms.float8_, + ¶ms.double_precision_, + ¶ms.text_, + ¶ms.varchar_, + ¶ms.bytea_, + ¶ms.timestamp_, + ¶ms.timestamp_without_time_zone_, + ¶ms.timestamptz_, + ¶ms.timestamp_with_time_zone_, + ¶ms.date_, + ¶ms.time_, + ¶ms.json_, + ¶ms.jsonb_, + ¶ms.uuid_, + ¶ms.inet_, + ¶ms.macaddr_, + ¶ms.numeric_, + )) + } + } + pub fn select_everything_array() -> SelectEverythingArrayStmt { + SelectEverythingArrayStmt(crate::client::async_::Stmt::new( + "SELECT + * +FROM + EverythingArray", + )) + } + pub struct SelectEverythingArrayStmt(crate::client::async_::Stmt); + impl SelectEverythingArrayStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> EverythingArrayQuery<'a, C, super::EverythingArray, 0> { + EverythingArrayQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::EverythingArrayBorrowed { + bool_: row.get(0), + boolean_: row.get(1), + char_: row.get(2), + smallint_: row.get(3), + int2_: row.get(4), + int_: row.get(5), + int4_: row.get(6), + bingint_: row.get(7), + int8_: row.get(8), + float4_: row.get(9), + real_: row.get(10), + float8_: row.get(11), + double_precision_: row.get(12), + text_: row.get(13), + varchar_: row.get(14), + bytea_: row.get(15), + timestamp_: row.get(16), + timestamp_without_time_zone_: row.get(17), + timestamptz_: row.get(18), + timestamp_with_time_zone_: row.get(19), + date_: row.get(20), + time_: row.get(21), + json_: row.get(22), + jsonb_: row.get(23), + uuid_: row.get(24), + inet_: row.get(25), + macaddr_: row.get(26), + numeric_: row.get(27), + }, + mapper: |it| ::from(it), + } + } + } + pub fn select_everything_array_null() -> SelectEverythingArrayNullStmt { + SelectEverythingArrayNullStmt(crate::client::async_::Stmt::new( + "SELECT + * +FROM + EverythingArray", + )) + } + pub struct SelectEverythingArrayNullStmt(crate::client::async_::Stmt); + impl SelectEverythingArrayNullStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> EverythingArrayNullQuery<'a, C, super::EverythingArrayNull, 0> { + EverythingArrayNullQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::EverythingArrayNullBorrowed { + bool_: row.get(0), + boolean_: row.get(1), + char_: row.get(2), + smallint_: row.get(3), + int2_: row.get(4), + int_: row.get(5), + int4_: row.get(6), + bingint_: row.get(7), + int8_: row.get(8), + float4_: row.get(9), + real_: row.get(10), + float8_: row.get(11), + double_precision_: row.get(12), + text_: row.get(13), + varchar_: row.get(14), + bytea_: row.get(15), + timestamp_: row.get(16), + timestamp_without_time_zone_: row.get(17), + timestamptz_: row.get(18), + timestamp_with_time_zone_: row.get(19), + date_: row.get(20), + time_: row.get(21), + json_: row.get(22), + jsonb_: row.get(23), + uuid_: row.get(24), + inet_: row.get(25), + macaddr_: row.get(26), + numeric_: row.get(27), + }, + mapper: |it| ::from(it), + } + } + } + pub fn insert_everything_array() -> InsertEverythingArrayStmt { + InsertEverythingArrayStmt(crate::client::async_::Stmt::new("INSERT INTO EverythingArray (bool_, boolean_, char_, smallint_, int2_, int_, int4_, bingint_, int8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)")) + } + pub struct InsertEverythingArrayStmt(crate::client::async_::Stmt); + impl InsertEverythingArrayStmt { + pub async fn bind< + 'a, + C: GenericClient, + T1: crate::ArraySql, + T2: crate::ArraySql, + T3: crate::ArraySql, + T4: crate::ArraySql, + T5: crate::ArraySql, + T6: crate::ArraySql, + T7: crate::ArraySql, + T8: crate::ArraySql, + T9: crate::ArraySql, + T10: crate::ArraySql, + T11: crate::ArraySql, + T12: crate::ArraySql, + T13: crate::ArraySql, + T14: crate::StringSql, + T15: crate::ArraySql, + T16: crate::StringSql, + T17: crate::ArraySql, + T18: crate::BytesSql, + T19: crate::ArraySql, + T20: crate::ArraySql, + T21: crate::ArraySql, + T22: crate::ArraySql, + T23: crate::ArraySql, + T24: crate::ArraySql, + T25: crate::ArraySql, + T26: crate::JsonSql, + T27: crate::ArraySql, + T28: crate::JsonSql, + T29: crate::ArraySql, + T30: crate::ArraySql, + T31: crate::ArraySql, + T32: crate::ArraySql, + T33: crate::ArraySql, + >( + &'a mut self, + client: &'a C, + bool_: &'a T1, + boolean_: &'a T2, + char_: &'a T3, + smallint_: &'a T4, + int2_: &'a T5, + int_: &'a T6, + int4_: &'a T7, + bingint_: &'a T8, + int8_: &'a T9, + float4_: &'a T10, + real_: &'a T11, + float8_: &'a T12, + double_precision_: &'a T13, + text_: &'a T15, + varchar_: &'a T17, + bytea_: &'a T19, + timestamp_: &'a T20, + timestamp_without_time_zone_: &'a T21, + timestamptz_: &'a T22, + timestamp_with_time_zone_: &'a T23, + date_: &'a T24, + time_: &'a T25, + json_: &'a T27, + jsonb_: &'a T29, + uuid_: &'a T30, + inet_: &'a T31, + macaddr_: &'a T32, + numeric_: &'a T33, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client + .execute( + stmt, + &[ + bool_, + boolean_, + char_, + smallint_, + int2_, + int_, + int4_, + bingint_, + int8_, + float4_, + real_, + float8_, + double_precision_, + text_, + varchar_, + bytea_, + timestamp_, + timestamp_without_time_zone_, + timestamptz_, + timestamp_with_time_zone_, + date_, + time_, + json_, + jsonb_, + uuid_, + inet_, + macaddr_, + numeric_, + ], + ) + .await + } + } + impl< + 'a, + C: GenericClient + Send + Sync, + T1: crate::ArraySql, + T2: crate::ArraySql, + T3: crate::ArraySql, + T4: crate::ArraySql, + T5: crate::ArraySql, + T6: crate::ArraySql, + T7: crate::ArraySql, + T8: crate::ArraySql, + T9: crate::ArraySql, + T10: crate::ArraySql, + T11: crate::ArraySql, + T12: crate::ArraySql, + T13: crate::ArraySql, + T14: crate::StringSql, + T15: crate::ArraySql, + T16: crate::StringSql, + T17: crate::ArraySql, + T18: crate::BytesSql, + T19: crate::ArraySql, + T20: crate::ArraySql, + T21: crate::ArraySql, + T22: crate::ArraySql, + T23: crate::ArraySql, + T24: crate::ArraySql, + T25: crate::ArraySql, + T26: crate::JsonSql, + T27: crate::ArraySql, + T28: crate::JsonSql, + T29: crate::ArraySql, + T30: crate::ArraySql, + T31: crate::ArraySql, + T32: crate::ArraySql, + T33: crate::ArraySql, + > + crate::client::async_::Params< + 'a, + super::EverythingArrayParams< + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + T31, + T32, + T33, + >, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for InsertEverythingArrayStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::EverythingArrayParams< + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + T31, + T32, + T33, + >, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind( + client, + ¶ms.bool_, + ¶ms.boolean_, + ¶ms.char_, + ¶ms.smallint_, + ¶ms.int2_, + ¶ms.int_, + ¶ms.int4_, + ¶ms.bingint_, + ¶ms.int8_, + ¶ms.float4_, + ¶ms.real_, + ¶ms.float8_, + ¶ms.double_precision_, + ¶ms.text_, + ¶ms.varchar_, + ¶ms.bytea_, + ¶ms.timestamp_, + ¶ms.timestamp_without_time_zone_, + ¶ms.timestamptz_, + ¶ms.timestamp_with_time_zone_, + ¶ms.date_, + ¶ms.time_, + ¶ms.json_, + ¶ms.jsonb_, + ¶ms.uuid_, + ¶ms.inet_, + ¶ms.macaddr_, + ¶ms.numeric_, + )) + } + } + pub fn select_nightmare() -> SelectNightmareStmt { + SelectNightmareStmt(crate::client::async_::Stmt::new( + "SELECT + * +FROM + nightmare", + )) + } + pub struct SelectNightmareStmt(crate::client::async_::Stmt); + impl SelectNightmareStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> NightmareCompositeQuery<'a, C, crate::types::NightmareComposite, 0> { + NightmareCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn insert_nightmare() -> InsertNightmareStmt { + InsertNightmareStmt(crate::client::async_::Stmt::new( + "INSERT INTO nightmare (composite) + VALUES ($1)", + )) + } + pub struct InsertNightmareStmt(crate::client::async_::Stmt); + impl InsertNightmareStmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + composite: &'a crate::types::NightmareCompositeParams<'a>, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[composite]).await + } + } + pub fn select_schema_nightmare() -> SelectSchemaNightmareStmt { + SelectSchemaNightmareStmt(crate::client::async_::Stmt::new( + "SELECT + * +FROM + schema.nightmare", + )) + } + pub struct SelectSchemaNightmareStmt(crate::client::async_::Stmt); + impl SelectSchemaNightmareStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> SchemaNightmareCompositeQuery<'a, C, crate::types::schema::NightmareComposite, 0> + { + SchemaNightmareCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn insert_schema_nightmare() -> InsertSchemaNightmareStmt { + InsertSchemaNightmareStmt(crate::client::async_::Stmt::new( + "INSERT INTO schema.nightmare (composite) + VALUES ($1)", + )) + } + pub struct InsertSchemaNightmareStmt(crate::client::async_::Stmt); + impl InsertSchemaNightmareStmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + composite: &'a crate::types::schema::NightmareCompositeParams<'a>, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[composite]).await + } + } +} diff --git a/test_codegen/codegen/src/queries/syntax.rs b/test_codegen/codegen/src/queries/syntax.rs new file mode 100644 index 00000000..a9e87744 --- /dev/null +++ b/test_codegen/codegen/src/queries/syntax.rs @@ -0,0 +1,1653 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(Debug)] +pub struct ImplicitCompactParams { + pub name: Option, + pub price: Option, +} +#[derive(Debug)] +pub struct ImplicitSpacedParams { + pub name: Option, + pub price: Option, +} +#[derive(Debug)] +pub struct Params { + pub name: T1, + pub price: f64, +} +#[derive(Debug)] +pub struct ParamsSpace { + pub name: T1, + pub price: f64, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySqlParams { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql1Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql2Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql3Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql4Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql6Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql7Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql8Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql9Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(Clone, Copy, Debug)] +pub struct TrickySql10Params { + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq, Copy)] +pub struct Row { + pub id: i32, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq, Copy)] +pub struct RowSpace { + pub id: i32, +} +#[derive(serde::Serialize, Debug, Clone, PartialEq)] +pub struct Typeof { + pub trick_y: String, + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +pub struct TypeofBorrowed<'a> { + pub trick_y: &'a str, + pub r#async: crate::types::SyntaxComposite, + pub r#enum: crate::types::SyntaxEnum, +} +impl<'a> From> for Typeof { + fn from( + TypeofBorrowed { + trick_y, + r#async, + r#enum, + }: TypeofBorrowed<'a>, + ) -> Self { + Self { + trick_y: trick_y.into(), + r#async, + r#enum, + } + } +} +pub mod sync { + use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + pub struct CloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> crate::types::CloneCompositeBorrowed, + mapper: fn(crate::types::CloneCompositeBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> CloneCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::CloneCompositeBorrowed) -> R, + ) -> CloneCompositeQuery<'a, C, R, N> { + CloneCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct Optioni32Query<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> Option, + mapper: fn(Option) -> T, + } + impl<'a, C, T: 'a, const N: usize> Optioni32Query<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(Option) -> R) -> Optioni32Query<'a, C, R, N> { + Optioni32Query { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct RowQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::Row, + mapper: fn(super::Row) -> T, + } + impl<'a, C, T: 'a, const N: usize> RowQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::Row) -> R) -> RowQuery<'a, C, R, N> { + RowQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct RowSpaceQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::RowSpace, + mapper: fn(super::RowSpace) -> T, + } + impl<'a, C, T: 'a, const N: usize> RowSpaceQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::RowSpace) -> R) -> RowSpaceQuery<'a, C, R, N> { + RowSpaceQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub struct TypeofQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a mut C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::sync::Stmt, + extractor: fn(&postgres::Row) -> super::TypeofBorrowed, + mapper: fn(super::TypeofBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> TypeofQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::TypeofBorrowed) -> R) -> TypeofQuery<'a, C, R, N> { + TypeofQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client)?; + let row = self.client.query_one(stmt, &self.params)?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub fn all(self) -> Result, postgres::Error> { + self.iter()?.collect() + } + pub fn opt(self) -> Result, postgres::Error> { + let stmt = self.stmt.prepare(self.client)?; + Ok(self + .client + .query_opt(stmt, &self.params)? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub fn iter( + self, + ) -> Result> + 'a, postgres::Error> + { + let stmt = self.stmt.prepare(self.client)?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params))? + .iterator() + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); + Ok(it) + } + } + pub fn select_compact() -> SelectCompactStmt { + SelectCompactStmt(crate::client::sync::Stmt::new("SELECT * FROM clone")) + } + pub struct SelectCompactStmt(crate::client::sync::Stmt); + impl SelectCompactStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> CloneCompositeQuery<'a, C, crate::types::CloneComposite, 0> { + CloneCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn select_spaced() -> SelectSpacedStmt { + SelectSpacedStmt(crate::client::sync::Stmt::new(" SELECT * FROM clone ")) + } + pub struct SelectSpacedStmt(crate::client::sync::Stmt); + impl SelectSpacedStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> CloneCompositeQuery<'a, C, crate::types::CloneComposite, 0> { + CloneCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn implicit_compact() -> ImplicitCompactStmt { + ImplicitCompactStmt(crate::client::sync::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct ImplicitCompactStmt(crate::client::sync::Stmt); + impl ImplicitCompactStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + name: &'a Option, + price: &'a Option, + ) -> Optioni32Query<'a, C, Option, 2> { + Optioni32Query { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it, + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::sync::Params< + 'a, + super::ImplicitCompactParams, + Optioni32Query<'a, C, Option, 2>, + C, + > for ImplicitCompactStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::ImplicitCompactParams, + ) -> Optioni32Query<'a, C, Option, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn implicit_spaced() -> ImplicitSpacedStmt { + ImplicitSpacedStmt(crate::client::sync::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct ImplicitSpacedStmt(crate::client::sync::Stmt); + impl ImplicitSpacedStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + name: &'a Option, + price: &'a Option, + ) -> Optioni32Query<'a, C, Option, 2> { + Optioni32Query { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it, + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::sync::Params< + 'a, + super::ImplicitSpacedParams, + Optioni32Query<'a, C, Option, 2>, + C, + > for ImplicitSpacedStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::ImplicitSpacedParams, + ) -> Optioni32Query<'a, C, Option, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn named_compact() -> NamedCompactStmt { + NamedCompactStmt(crate::client::sync::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct NamedCompactStmt(crate::client::sync::Stmt); + impl NamedCompactStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + name: &'a T1, + price: &'a f64, + ) -> RowQuery<'a, C, super::Row, 2> { + RowQuery { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| super::Row { id: row.get(0) }, + mapper: |it| ::from(it), + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::sync::Params<'a, super::Params, RowQuery<'a, C, super::Row, 2>, C> + for NamedCompactStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::Params, + ) -> RowQuery<'a, C, super::Row, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn named_spaced() -> NamedSpacedStmt { + NamedSpacedStmt(crate::client::sync::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct NamedSpacedStmt(crate::client::sync::Stmt); + impl NamedSpacedStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a mut C, + name: &'a T1, + price: &'a f64, + ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { + RowSpaceQuery { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| super::RowSpace { id: row.get(0) }, + mapper: |it| ::from(it), + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::sync::Params< + 'a, + super::ParamsSpace, + RowSpaceQuery<'a, C, super::RowSpace, 2>, + C, + > for NamedSpacedStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::ParamsSpace, + ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn tricky_sql() -> TrickySqlStmt { + TrickySqlStmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a bind_param\', $1, $2)")) + } + pub struct TrickySqlStmt(crate::client::sync::Stmt); + impl TrickySqlStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySqlParams, Result, C> + for TrickySqlStmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySqlParams, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql1() -> TrickySql1Stmt { + TrickySql1Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a :bind_param', $1, $2)")) + } + pub struct TrickySql1Stmt(crate::client::sync::Stmt); + impl TrickySql1Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql1Params, Result, C> + for TrickySql1Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql1Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql2() -> TrickySql2Stmt { + TrickySql2Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a '':bind_param''', $1, $2)")) + } + pub struct TrickySql2Stmt(crate::client::sync::Stmt); + impl TrickySql2Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql2Params, Result, C> + for TrickySql2Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql2Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql3() -> TrickySql3Stmt { + TrickySql3Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($$this is not a :bind_param$$, $1, $2)")) + } + pub struct TrickySql3Stmt(crate::client::sync::Stmt); + impl TrickySql3Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql3Params, Result, C> + for TrickySql3Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql3Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql4() -> TrickySql4Stmt { + TrickySql4Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($tag$this is not a :bind_param$tag$, $1, $2)")) + } + pub struct TrickySql4Stmt(crate::client::sync::Stmt); + impl TrickySql4Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql4Params, Result, C> + for TrickySql4Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql4Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql6() -> TrickySql6Stmt { + TrickySql6Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is not a '':bind_param''', $1, $2)")) + } + pub struct TrickySql6Stmt(crate::client::sync::Stmt); + impl TrickySql6Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql6Params, Result, C> + for TrickySql6Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql6Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql7() -> TrickySql7Stmt { + TrickySql7Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is not a \':bind_param\'', $1, $2)")) + } + pub struct TrickySql7Stmt(crate::client::sync::Stmt); + impl TrickySql7Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql7Params, Result, C> + for TrickySql7Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql7Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql8() -> TrickySql8Stmt { + TrickySql8Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is ''not'' a \':bind_param\'', $1, $2)")) + } + pub struct TrickySql8Stmt(crate::client::sync::Stmt); + impl TrickySql8Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql8Params, Result, C> + for TrickySql8Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql8Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql9() -> TrickySql9Stmt { + TrickySql9Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is \'not\' a \':bind_param\'', $1, $2)")) + } + pub struct TrickySql9Stmt(crate::client::sync::Stmt); + impl TrickySql9Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql9Params, Result, C> + for TrickySql9Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql9Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn tricky_sql10() -> TrickySql10Stmt { + TrickySql10Stmt(crate::client::sync::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is just a cast'::text, $1, $2)")) + } + pub struct TrickySql10Stmt(crate::client::sync::Stmt); + impl TrickySql10Stmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client)?; + client.execute(stmt, &[r#async, r#enum]) + } + } + impl<'a, C: GenericClient> + crate::client::sync::Params<'a, super::TrickySql10Params, Result, C> + for TrickySql10Stmt + { + fn params( + &'a mut self, + client: &'a mut C, + params: &'a super::TrickySql10Params, + ) -> Result { + self.bind(client, ¶ms.r#async, ¶ms.r#enum) + } + } + pub fn r#typeof() -> RTypeofStmt { + RTypeofStmt(crate::client::sync::Stmt::new("SELECT * FROM syntax")) + } + pub struct RTypeofStmt(crate::client::sync::Stmt); + impl RTypeofStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a mut C, + ) -> TypeofQuery<'a, C, super::Typeof, 0> { + TypeofQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::TypeofBorrowed { + trick_y: row.get(0), + r#async: row.get(1), + r#enum: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } +} +pub mod async_ { + use crate::client::async_::GenericClient; + use futures::{self, StreamExt, TryStreamExt}; + pub struct CloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> crate::types::CloneCompositeBorrowed, + mapper: fn(crate::types::CloneCompositeBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> CloneCompositeQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map( + self, + mapper: fn(crate::types::CloneCompositeBorrowed) -> R, + ) -> CloneCompositeQuery<'a, C, R, N> { + CloneCompositeQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct Optioni32Query<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> Option, + mapper: fn(Option) -> T, + } + impl<'a, C, T: 'a, const N: usize> Optioni32Query<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(Option) -> R) -> Optioni32Query<'a, C, R, N> { + Optioni32Query { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct RowQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::Row, + mapper: fn(super::Row) -> T, + } + impl<'a, C, T: 'a, const N: usize> RowQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::Row) -> R) -> RowQuery<'a, C, R, N> { + RowQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct RowSpaceQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::RowSpace, + mapper: fn(super::RowSpace) -> T, + } + impl<'a, C, T: 'a, const N: usize> RowSpaceQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::RowSpace) -> R) -> RowSpaceQuery<'a, C, R, N> { + RowSpaceQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub struct TypeofQuery<'a, C: GenericClient, T, const N: usize> { + client: &'a C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + stmt: &'a mut crate::client::async_::Stmt, + extractor: fn(&tokio_postgres::Row) -> super::TypeofBorrowed, + mapper: fn(super::TypeofBorrowed) -> T, + } + impl<'a, C, T: 'a, const N: usize> TypeofQuery<'a, C, T, N> + where + C: GenericClient, + { + pub fn map(self, mapper: fn(super::TypeofBorrowed) -> R) -> TypeofQuery<'a, C, R, N> { + TypeofQuery { + client: self.client, + params: self.params, + stmt: self.stmt, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let stmt = self.stmt.prepare(self.client).await?; + let row = self.client.query_one(stmt, &self.params).await?; + Ok((self.mapper)((self.extractor)(&row))) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let stmt = self.stmt.prepare(self.client).await?; + Ok(self + .client + .query_opt(stmt, &self.params) + .await? + .map(|row| (self.mapper)((self.extractor)(&row)))) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + 'a, + tokio_postgres::Error, + > { + let stmt = self.stmt.prepare(self.client).await?; + let it = self + .client + .query_raw(stmt, crate::slice_iter(&self.params)) + .await? + .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) + .into_stream(); + Ok(it) + } + } + pub fn select_compact() -> SelectCompactStmt { + SelectCompactStmt(crate::client::async_::Stmt::new("SELECT * FROM clone")) + } + pub struct SelectCompactStmt(crate::client::async_::Stmt); + impl SelectCompactStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> CloneCompositeQuery<'a, C, crate::types::CloneComposite, 0> { + CloneCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn select_spaced() -> SelectSpacedStmt { + SelectSpacedStmt(crate::client::async_::Stmt::new( + " SELECT * FROM clone ", + )) + } + pub struct SelectSpacedStmt(crate::client::async_::Stmt); + impl SelectSpacedStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> CloneCompositeQuery<'a, C, crate::types::CloneComposite, 0> { + CloneCompositeQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it.into(), + } + } + } + pub fn implicit_compact() -> ImplicitCompactStmt { + ImplicitCompactStmt(crate::client::async_::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct ImplicitCompactStmt(crate::client::async_::Stmt); + impl ImplicitCompactStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + name: &'a Option, + price: &'a Option, + ) -> Optioni32Query<'a, C, Option, 2> { + Optioni32Query { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it, + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::async_::Params< + 'a, + super::ImplicitCompactParams, + Optioni32Query<'a, C, Option, 2>, + C, + > for ImplicitCompactStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::ImplicitCompactParams, + ) -> Optioni32Query<'a, C, Option, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn implicit_spaced() -> ImplicitSpacedStmt { + ImplicitSpacedStmt(crate::client::async_::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct ImplicitSpacedStmt(crate::client::async_::Stmt); + impl ImplicitSpacedStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + name: &'a Option, + price: &'a Option, + ) -> Optioni32Query<'a, C, Option, 2> { + Optioni32Query { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| row.get(0), + mapper: |it| it, + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::async_::Params< + 'a, + super::ImplicitSpacedParams, + Optioni32Query<'a, C, Option, 2>, + C, + > for ImplicitSpacedStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::ImplicitSpacedParams, + ) -> Optioni32Query<'a, C, Option, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn named_compact() -> NamedCompactStmt { + NamedCompactStmt(crate::client::async_::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct NamedCompactStmt(crate::client::async_::Stmt); + impl NamedCompactStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + name: &'a T1, + price: &'a f64, + ) -> RowQuery<'a, C, super::Row, 2> { + RowQuery { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| super::Row { id: row.get(0) }, + mapper: |it| ::from(it), + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::async_::Params<'a, super::Params, RowQuery<'a, C, super::Row, 2>, C> + for NamedCompactStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::Params, + ) -> RowQuery<'a, C, super::Row, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn named_spaced() -> NamedSpacedStmt { + NamedSpacedStmt(crate::client::async_::Stmt::new( + "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", + )) + } + pub struct NamedSpacedStmt(crate::client::async_::Stmt); + impl NamedSpacedStmt { + pub fn bind<'a, C: GenericClient, T1: crate::StringSql>( + &'a mut self, + client: &'a C, + name: &'a T1, + price: &'a f64, + ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { + RowSpaceQuery { + client, + params: [name, price], + stmt: &mut self.0, + extractor: |row| super::RowSpace { id: row.get(0) }, + mapper: |it| ::from(it), + } + } + } + impl<'a, C: GenericClient, T1: crate::StringSql> + crate::client::async_::Params< + 'a, + super::ParamsSpace, + RowSpaceQuery<'a, C, super::RowSpace, 2>, + C, + > for NamedSpacedStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::ParamsSpace, + ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { + self.bind(client, ¶ms.name, ¶ms.price) + } + } + pub fn tricky_sql() -> TrickySqlStmt { + TrickySqlStmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a bind_param\', $1, $2)")) + } + pub struct TrickySqlStmt(crate::client::async_::Stmt); + impl TrickySqlStmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySqlParams, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySqlStmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySqlParams, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql1() -> TrickySql1Stmt { + TrickySql1Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a :bind_param', $1, $2)")) + } + pub struct TrickySql1Stmt(crate::client::async_::Stmt); + impl TrickySql1Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql1Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql1Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql1Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql2() -> TrickySql2Stmt { + TrickySql2Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a '':bind_param''', $1, $2)")) + } + pub struct TrickySql2Stmt(crate::client::async_::Stmt); + impl TrickySql2Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql2Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql2Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql2Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql3() -> TrickySql3Stmt { + TrickySql3Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($$this is not a :bind_param$$, $1, $2)")) + } + pub struct TrickySql3Stmt(crate::client::async_::Stmt); + impl TrickySql3Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql3Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql3Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql3Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql4() -> TrickySql4Stmt { + TrickySql4Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($tag$this is not a :bind_param$tag$, $1, $2)")) + } + pub struct TrickySql4Stmt(crate::client::async_::Stmt); + impl TrickySql4Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql4Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql4Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql4Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql6() -> TrickySql6Stmt { + TrickySql6Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is not a '':bind_param''', $1, $2)")) + } + pub struct TrickySql6Stmt(crate::client::async_::Stmt); + impl TrickySql6Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql6Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql6Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql6Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql7() -> TrickySql7Stmt { + TrickySql7Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is not a \':bind_param\'', $1, $2)")) + } + pub struct TrickySql7Stmt(crate::client::async_::Stmt); + impl TrickySql7Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql7Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql7Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql7Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql8() -> TrickySql8Stmt { + TrickySql8Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is ''not'' a \':bind_param\'', $1, $2)")) + } + pub struct TrickySql8Stmt(crate::client::async_::Stmt); + impl TrickySql8Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql8Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql8Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql8Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql9() -> TrickySql9Stmt { + TrickySql9Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is \'not\' a \':bind_param\'', $1, $2)")) + } + pub struct TrickySql9Stmt(crate::client::async_::Stmt); + impl TrickySql9Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql9Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql9Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql9Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn tricky_sql10() -> TrickySql10Stmt { + TrickySql10Stmt(crate::client::async_::Stmt::new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is just a cast'::text, $1, $2)")) + } + pub struct TrickySql10Stmt(crate::client::async_::Stmt); + impl TrickySql10Stmt { + pub async fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + r#async: &'a crate::types::SyntaxComposite, + r#enum: &'a crate::types::SyntaxEnum, + ) -> Result { + let stmt = self.0.prepare(client).await?; + client.execute(stmt, &[r#async, r#enum]).await + } + } + impl<'a, C: GenericClient + Send + Sync> + crate::client::async_::Params< + 'a, + super::TrickySql10Params, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for TrickySql10Stmt + { + fn params( + &'a mut self, + client: &'a C, + params: &'a super::TrickySql10Params, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) + } + } + pub fn r#typeof() -> RTypeofStmt { + RTypeofStmt(crate::client::async_::Stmt::new("SELECT * FROM syntax")) + } + pub struct RTypeofStmt(crate::client::async_::Stmt); + impl RTypeofStmt { + pub fn bind<'a, C: GenericClient>( + &'a mut self, + client: &'a C, + ) -> TypeofQuery<'a, C, super::Typeof, 0> { + TypeofQuery { + client, + params: [], + stmt: &mut self.0, + extractor: |row| super::TypeofBorrowed { + trick_y: row.get(0), + r#async: row.get(1), + r#enum: row.get(2), + }, + mapper: |it| ::from(it), + } + } + } +} diff --git a/crates/client_core/src/type_traits.rs b/test_codegen/codegen/src/type_traits.rs similarity index 90% rename from crates/client_core/src/type_traits.rs rename to test_codegen/codegen/src/type_traits.rs index e818a1cb..e8c19895 100644 --- a/crates/client_core/src/type_traits.rs +++ b/test_codegen/codegen/src/type_traits.rs @@ -1,30 +1,23 @@ -use std::borrow::Cow; +// This file was generated with `cornucopia`. Do not modify. -use crate::domain::escape_domain_to_sql; +use super::domain::escape_domain_to_sql; use postgres_protocol::types::{self, ArrayDimension}; use postgres_types::{private::BytesMut, to_sql_checked, IsNull, Kind, ToSql, Type}; - +use std::borrow::Cow; pub trait StringSql: std::fmt::Debug + ToSql + Sync {} impl StringSql for &T {} impl StringSql for String {} impl StringSql for &str {} impl StringSql for Cow<'_, str> {} impl StringSql for Box {} - pub trait BytesSql: std::fmt::Debug + ToSql + Send + Sync {} impl BytesSql for &T {} impl BytesSql for Vec {} impl BytesSql for &[u8] {} - -#[cfg(feature = "with-serde_json-1")] pub trait JsonSql: std::fmt::Debug + ToSql + Sync + Send {} -#[cfg(feature = "with-serde_json-1")] impl JsonSql for &T {} -#[cfg(feature = "with-serde_json-1")] impl JsonSql for serde_json::value::Value {} -#[cfg(feature = "with-serde_json-1")] impl JsonSql for postgres_types::Json {} - pub trait ArraySql: std::fmt::Debug + ToSql + Send + Sync { type Item; fn escape_domain_to_sql( @@ -35,7 +28,6 @@ pub trait ArraySql: std::fmt::Debug + ToSql + Send + Sync { } impl> ArraySql for &A { type Item = T; - fn escape_domain_to_sql( &self, ty: &Type, @@ -46,7 +38,6 @@ impl> ArraySql for &A { } impl ArraySql for Vec { type Item = T; - fn escape_domain_to_sql( &self, ty: &Type, @@ -55,10 +46,8 @@ impl ArraySql for Vec { escape_domain_to_sql(ty, w, self.iter()) } } - impl ArraySql for &[T] { type Item = T; - fn escape_domain_to_sql( &self, ty: &Type, @@ -67,7 +56,6 @@ impl ArraySql for &[T] { escape_domain_to_sql(ty, w, self.iter()) } } - impl< T: std::fmt::Debug + ToSql + Send + Sync, I: Iterator + ExactSizeIterator, @@ -75,7 +63,6 @@ impl< > ArraySql for IterSql { type Item = T; - fn escape_domain_to_sql( &self, ty: &Type, @@ -84,9 +71,7 @@ impl< escape_domain_to_sql(ty, w, (self.0)()) } } - pub struct IterSql + ExactSizeIterator, F: Fn() -> I + Sync>(pub F); - impl + ExactSizeIterator, F: Fn() -> I + Sync> std::fmt::Debug for IterSql { @@ -94,8 +79,6 @@ impl + ExactSizeIterator, F: Fn() -> I + Sync> s f.debug_tuple("ArrayFn").finish() } } - -// Taken from `postgres` impl + ExactSizeIterator, F: Fn() -> I + Sync> ToSql for IterSql { @@ -108,14 +91,11 @@ impl + ExactSizeIterator, F: Fn() -> I + Sync> T Kind::Array(ref member) => member, _ => panic!("expected array type"), }; - let iter = (self.0)(); - let dimension = ArrayDimension { len: downcast(iter.len())?, lower_bound: 1, }; - types::array_to_sql( Some(dimension), member_type.oid(), @@ -128,20 +108,16 @@ impl + ExactSizeIterator, F: Fn() -> I + Sync> T )?; Ok(IsNull::No) } - fn accepts(ty: &Type) -> bool { match *ty.kind() { Kind::Array(ref member) => T::accepts(member), _ => false, } } - to_sql_checked!(); } - -// https://github.com/sfackler/rust-postgres/blob/765395f288861209a644c621bf72172acd482515/postgres-types/src/lib.rs fn downcast(len: usize) -> Result> { - if len > i32::max_value() as usize { + if len > i32::MAX as usize { Err("value too large to transmit".into()) } else { Ok(len as i32) diff --git a/test_codegen/codegen/src/types.rs b/test_codegen/codegen/src/types.rs new file mode 100644 index 00000000..e985ac7d --- /dev/null +++ b/test_codegen/codegen/src/types.rs @@ -0,0 +1,1345 @@ +// This file was generated with `cornucopia`. Do not modify. + +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Clone, PartialEq)] +#[postgres(name = "clone_composite")] +pub struct CloneComposite { + #[postgres(name = "first")] + pub first: i32, + #[postgres(name = "second")] + pub second: String, +} +#[derive(Debug)] +pub struct CloneCompositeBorrowed<'a> { + pub first: i32, + pub second: &'a str, +} +impl<'a> From> for CloneComposite { + fn from(CloneCompositeBorrowed { first, second }: CloneCompositeBorrowed<'a>) -> Self { + Self { + first, + second: second.into(), + } + } +} +impl<'a> postgres_types::FromSql<'a> for CloneCompositeBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let first = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let second = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + Ok(CloneCompositeBorrowed { first, second }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "clone_composite" && ty.schema() == "public" + } +} +impl<'a> postgres_types::ToSql for CloneCompositeBorrowed<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let CloneCompositeBorrowed { first, second } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "first" => postgres_types::ToSql::to_sql(first, field.type_(), out), + "second" => postgres_types::ToSql::to_sql(second, field.type_(), out), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "clone_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 2 { + return false; + } + fields.iter().all(|f| match f.name() { + "first" => ::accepts(f.type_()), + "second" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Copy, Clone, PartialEq)] +#[postgres(name = "copy_composite")] +pub struct CopyComposite { + #[postgres(name = "first")] + pub first: i32, + #[postgres(name = "second")] + pub second: f64, +} +impl<'a> postgres_types::ToSql for CopyComposite { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let CopyComposite { first, second } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "first" => postgres_types::ToSql::to_sql(first, field.type_(), out), + "second" => postgres_types::ToSql::to_sql(second, field.type_(), out), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "copy_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 2 { + return false; + } + fields.iter().all(|f| match f.name() { + "first" => ::accepts(f.type_()), + "second" => ::accepts(f.type_()), + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Clone, PartialEq)] +#[postgres(name = "domain_composite")] +pub struct DomainComposite { + #[postgres(name = "txt")] + pub txt: String, + #[postgres(name = "json")] + pub json: serde_json::Value, + #[postgres(name = "nb")] + pub nb: i32, + #[postgres(name = "arr")] + pub arr: Vec, +} +#[derive(Debug)] +pub struct DomainCompositeBorrowed<'a> { + pub txt: &'a str, + pub json: postgres_types::Json<&'a serde_json::value::RawValue>, + pub nb: i32, + pub arr: crate::ArrayIterator<'a, postgres_types::Json<&'a serde_json::value::RawValue>>, +} +impl<'a> From> for DomainComposite { + fn from(DomainCompositeBorrowed { txt, json, nb, arr }: DomainCompositeBorrowed<'a>) -> Self { + Self { + txt: txt.into(), + json: serde_json::from_str(json.0.get()).unwrap(), + nb, + arr: arr + .map(|v| serde_json::from_str(v.0.get()).unwrap()) + .collect(), + } + } +} +impl<'a> postgres_types::FromSql<'a> for DomainCompositeBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let txt = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let json = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let nb = postgres_types::private::read_value(fields[2].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let arr = postgres_types::private::read_value(fields[3].type_(), &mut out)?; + Ok(DomainCompositeBorrowed { txt, json, nb, arr }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "domain_composite" && ty.schema() == "public" + } +} +#[derive(Debug)] +pub struct DomainCompositeParams<'a> { + pub txt: &'a str, + pub json: &'a serde_json::value::Value, + pub nb: i32, + pub arr: &'a [&'a serde_json::value::Value], +} +impl<'a> postgres_types::ToSql for DomainCompositeParams<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let DomainCompositeParams { txt, json, nb, arr } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "txt" => postgres_types::ToSql::to_sql(&crate::Domain(txt), field.type_(), out), + "json" => postgres_types::ToSql::to_sql(&crate::Domain(json), field.type_(), out), + "nb" => postgres_types::ToSql::to_sql(&crate::Domain(nb), field.type_(), out), + "arr" => postgres_types::ToSql::to_sql( + &crate::Domain(&crate::DomainArray(arr)), + field.type_(), + out, + ), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "domain_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 4 { + return false; + } + fields.iter().all(|f| match f.name() + { + "txt" => as + postgres_types::ToSql>::accepts(f.type_()),"json" => as + postgres_types::ToSql>::accepts(f.type_()),"nb" => as + postgres_types::ToSql>::accepts(f.type_()),"arr" => > as + postgres_types::ToSql>::accepts(f.type_()),_ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Clone, PartialEq)] +#[postgres(name = "named_composite")] +pub struct NamedComposite { + #[postgres(name = "wow")] + pub wow: Option, + #[postgres(name = "such_cool")] + pub such_cool: Option, +} +#[derive(Debug)] +pub struct NamedCompositeBorrowed<'a> { + pub wow: Option<&'a str>, + pub such_cool: Option, +} +impl<'a> From> for NamedComposite { + fn from(NamedCompositeBorrowed { wow, such_cool }: NamedCompositeBorrowed<'a>) -> Self { + Self { + wow: wow.map(|v| v.into()), + such_cool, + } + } +} +impl<'a> postgres_types::FromSql<'a> for NamedCompositeBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let wow = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let such_cool = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + Ok(NamedCompositeBorrowed { wow, such_cool }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "named_composite" && ty.schema() == "public" + } +} +impl<'a> postgres_types::ToSql for NamedCompositeBorrowed<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let NamedCompositeBorrowed { wow, such_cool } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "wow" => postgres_types::ToSql::to_sql(wow, field.type_(), out), + "such_cool" => postgres_types::ToSql::to_sql(such_cool, field.type_(), out), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "named_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 2 { + return false; + } + fields.iter().all(|f| match f.name() { + "wow" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), + "such_cool" => ::accepts(f.type_()), + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[allow(non_camel_case_types)] +pub enum EnumWithDot { + variant_with_dot, +} +impl<'a> postgres_types::ToSql for EnumWithDot { + fn to_sql( + &self, + ty: &postgres_types::Type, + buf: &mut postgres_types::private::BytesMut, + ) -> Result> { + let s = match *self { + EnumWithDot::variant_with_dot => "variant.with_dot", + }; + buf.extend_from_slice(s.as_bytes()); + std::result::Result::Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "enum.with_dot" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 1 { + return false; + } + variants.iter().all(|v| match &**v { + "variant.with_dot" => true, + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +impl<'a> postgres_types::FromSql<'a> for EnumWithDot { + fn from_sql( + ty: &postgres_types::Type, + buf: &'a [u8], + ) -> Result> { + match std::str::from_utf8(buf)? { + "variant.with_dot" => Ok(EnumWithDot::variant_with_dot), + s => Result::Err(Into::into(format!("invalid variant `{}`", s))), + } + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "enum.with_dot" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 1 { + return false; + } + variants.iter().all(|v| match &**v { + "variant.with_dot" => true, + _ => false, + }) + } + _ => false, + } + } +} +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Copy, Clone, PartialEq)] +#[postgres(name = "named_composite.with_dot")] +pub struct NamedCompositeWithDot { + #[postgres(name = "this.is.inconceivable")] + pub this_is_inconceivable: Option, +} +impl<'a> postgres_types::ToSql for NamedCompositeWithDot { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let NamedCompositeWithDot { + this_is_inconceivable, + } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "this.is.inconceivable" => { + postgres_types::ToSql::to_sql(this_is_inconceivable, field.type_(), out) + } + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "named_composite.with_dot" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 1 { + return false; + } + fields.iter().all(|f| match f.name() { + "this.is.inconceivable" => { + ::accepts(f.type_()) + } + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Clone, PartialEq)] +#[postgres(name = "nullity_composite")] +pub struct NullityComposite { + #[postgres(name = "jsons")] + pub jsons: Option>>, + #[postgres(name = "id")] + pub id: i32, +} +#[derive(Debug)] +pub struct NullityCompositeBorrowed<'a> { + pub jsons: Option< + crate::ArrayIterator<'a, Option>>, + >, + pub id: i32, +} +impl<'a> From> for NullityComposite { + fn from(NullityCompositeBorrowed { jsons, id }: NullityCompositeBorrowed<'a>) -> Self { + Self { + jsons: jsons.map(|v| { + v.map(|v| v.map(|v| serde_json::from_str(v.0.get()).unwrap())) + .collect() + }), + id, + } + } +} +impl<'a> postgres_types::FromSql<'a> for NullityCompositeBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let jsons = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let id = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + Ok(NullityCompositeBorrowed { jsons, id }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "nullity_composite" && ty.schema() == "public" + } +} +#[derive(Debug)] +pub struct NullityCompositeParams<'a> { + pub jsons: Option<&'a [Option<&'a serde_json::value::Value>]>, + pub id: i32, +} +impl<'a> postgres_types::ToSql for NullityCompositeParams<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let NullityCompositeParams { jsons, id } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "jsons" => postgres_types::ToSql::to_sql(jsons, field.type_(), out), + "id" => postgres_types::ToSql::to_sql(id, field.type_(), out), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "nullity_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 2 { + return false; + } + fields.iter().all(|f| match f.name() { + "jsons" => { + <&'a [&'a serde_json::value::Value] as postgres_types::ToSql>::accepts( + f.type_(), + ) + } + "id" => ::accepts(f.type_()), + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[allow(non_camel_case_types)] +pub enum SpongebobCharacter { + Bob, + Patrick, + Squidward, +} +impl<'a> postgres_types::ToSql for SpongebobCharacter { + fn to_sql( + &self, + ty: &postgres_types::Type, + buf: &mut postgres_types::private::BytesMut, + ) -> Result> { + let s = match *self { + SpongebobCharacter::Bob => "Bob", + SpongebobCharacter::Patrick => "Patrick", + SpongebobCharacter::Squidward => "Squidward", + }; + buf.extend_from_slice(s.as_bytes()); + std::result::Result::Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "spongebob_character" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 3 { + return false; + } + variants.iter().all(|v| match &**v { + "Bob" => true, + "Patrick" => true, + "Squidward" => true, + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +impl<'a> postgres_types::FromSql<'a> for SpongebobCharacter { + fn from_sql( + ty: &postgres_types::Type, + buf: &'a [u8], + ) -> Result> { + match std::str::from_utf8(buf)? { + "Bob" => Ok(SpongebobCharacter::Bob), + "Patrick" => Ok(SpongebobCharacter::Patrick), + "Squidward" => Ok(SpongebobCharacter::Squidward), + s => Result::Err(Into::into(format!("invalid variant `{}`", s))), + } + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "spongebob_character" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 3 { + return false; + } + variants.iter().all(|v| match &**v { + "Bob" => true, + "Patrick" => true, + "Squidward" => true, + _ => false, + }) + } + _ => false, + } + } +} +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Clone, PartialEq)] +#[postgres(name = "custom_composite")] +pub struct CustomComposite { + #[postgres(name = "wow")] + pub wow: String, + #[postgres(name = "such_cool")] + pub such_cool: i32, + #[postgres(name = "nice")] + pub nice: SpongebobCharacter, +} +#[derive(Debug)] +pub struct CustomCompositeBorrowed<'a> { + pub wow: &'a str, + pub such_cool: i32, + pub nice: SpongebobCharacter, +} +impl<'a> From> for CustomComposite { + fn from( + CustomCompositeBorrowed { + wow, + such_cool, + nice, + }: CustomCompositeBorrowed<'a>, + ) -> Self { + Self { + wow: wow.into(), + such_cool, + nice, + } + } +} +impl<'a> postgres_types::FromSql<'a> for CustomCompositeBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let wow = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let such_cool = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let nice = postgres_types::private::read_value(fields[2].type_(), &mut out)?; + Ok(CustomCompositeBorrowed { + wow, + such_cool, + nice, + }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "custom_composite" && ty.schema() == "public" + } +} +impl<'a> postgres_types::ToSql for CustomCompositeBorrowed<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let CustomCompositeBorrowed { + wow, + such_cool, + nice, + } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "wow" => postgres_types::ToSql::to_sql(wow, field.type_(), out), + "such_cool" => postgres_types::ToSql::to_sql(such_cool, field.type_(), out), + "nice" => postgres_types::ToSql::to_sql(nice, field.type_(), out), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "custom_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 3 { + return false; + } + fields.iter().all(|f| match f.name() { + "wow" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), + "such_cool" => ::accepts(f.type_()), + "nice" => ::accepts(f.type_()), + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Clone, PartialEq)] +#[postgres(name = "nightmare_composite")] +pub struct NightmareComposite { + #[postgres(name = "custom")] + pub custom: Vec, + #[postgres(name = "spongebob")] + pub spongebob: Vec, + #[postgres(name = "domain")] + pub domain: String, +} +#[derive(Debug)] +pub struct NightmareCompositeBorrowed<'a> { + pub custom: crate::ArrayIterator<'a, CustomCompositeBorrowed<'a>>, + pub spongebob: crate::ArrayIterator<'a, SpongebobCharacter>, + pub domain: &'a str, +} +impl<'a> From> for NightmareComposite { + fn from( + NightmareCompositeBorrowed { + custom, + spongebob, + domain, + }: NightmareCompositeBorrowed<'a>, + ) -> Self { + Self { + custom: custom.map(|v| v.into()).collect(), + spongebob: spongebob.map(|v| v).collect(), + domain: domain.into(), + } + } +} +impl<'a> postgres_types::FromSql<'a> for NightmareCompositeBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let custom = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let spongebob = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let domain = postgres_types::private::read_value(fields[2].type_(), &mut out)?; + Ok(NightmareCompositeBorrowed { + custom, + spongebob, + domain, + }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "nightmare_composite" && ty.schema() == "public" + } +} +#[derive(Debug)] +pub struct NightmareCompositeParams<'a> { + pub custom: &'a [CustomCompositeBorrowed<'a>], + pub spongebob: &'a [SpongebobCharacter], + pub domain: &'a str, +} +impl<'a> postgres_types::ToSql for NightmareCompositeParams<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let NightmareCompositeParams { + custom, + spongebob, + domain, + } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "custom" => postgres_types::ToSql::to_sql(custom, field.type_(), out), + "spongebob" => postgres_types::ToSql::to_sql(spongebob, field.type_(), out), + "domain" => { + postgres_types::ToSql::to_sql(&crate::Domain(domain), field.type_(), out) + } + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "nightmare_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 3 { + return false; + } + fields.iter().all(|f| match f.name() { + "custom" => { + <&'a [CustomCompositeBorrowed<'a>] as postgres_types::ToSql>::accepts( + f.type_(), + ) + } + "spongebob" => { + <&'a [SpongebobCharacter] as postgres_types::ToSql>::accepts(f.type_()) + } + "domain" => { + as postgres_types::ToSql>::accepts(f.type_()) + } + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, postgres_types::FromSql, Copy, Clone, PartialEq)] +#[postgres(name = "syntax_composite")] +pub struct SyntaxComposite { + #[postgres(name = "async")] + pub r#async: i32, +} +impl<'a> postgres_types::ToSql for SyntaxComposite { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let SyntaxComposite { r#async } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "async" => postgres_types::ToSql::to_sql(r#async, field.type_(), out), + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "syntax_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 1 { + return false; + } + fields.iter().all(|f| match f.name() { + "async" => ::accepts(f.type_()), + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +#[derive(serde::Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[allow(non_camel_case_types)] +pub enum SyntaxEnum { + r#async, + r#box, + I_Love_Chocolate, +} +impl<'a> postgres_types::ToSql for SyntaxEnum { + fn to_sql( + &self, + ty: &postgres_types::Type, + buf: &mut postgres_types::private::BytesMut, + ) -> Result> { + let s = match *self { + SyntaxEnum::r#async => "async", + SyntaxEnum::r#box => "box", + SyntaxEnum::I_Love_Chocolate => "I Love Chocolate", + }; + buf.extend_from_slice(s.as_bytes()); + std::result::Result::Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "syntax_enum" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 3 { + return false; + } + variants.iter().all(|v| match &**v { + "async" => true, + "box" => true, + "I Love Chocolate" => true, + _ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } +} +impl<'a> postgres_types::FromSql<'a> for SyntaxEnum { + fn from_sql( + ty: &postgres_types::Type, + buf: &'a [u8], + ) -> Result> { + match std::str::from_utf8(buf)? { + "async" => Ok(SyntaxEnum::r#async), + "box" => Ok(SyntaxEnum::r#box), + "I Love Chocolate" => Ok(SyntaxEnum::I_Love_Chocolate), + s => Result::Err(Into::into(format!("invalid variant `{}`", s))), + } + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "syntax_enum" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Enum(ref variants) => { + if variants.len() != 3 { + return false; + } + variants.iter().all(|v| match &**v { + "async" => true, + "box" => true, + "I Love Chocolate" => true, + _ => false, + }) + } + _ => false, + } + } +} +pub mod schema { + #[derive(serde::Serialize, Debug, postgres_types::FromSql, Clone, PartialEq)] + #[postgres(name = "nightmare_composite")] + pub struct NightmareComposite { + #[postgres(name = "custom")] + pub custom: Vec, + #[postgres(name = "spongebob")] + pub spongebob: Vec, + #[postgres(name = "domain")] + pub domain: String, + } + #[derive(Debug)] + pub struct NightmareCompositeBorrowed<'a> { + pub custom: crate::ArrayIterator<'a, super::CustomCompositeBorrowed<'a>>, + pub spongebob: crate::ArrayIterator<'a, super::SpongebobCharacter>, + pub domain: &'a str, + } + impl<'a> From> for NightmareComposite { + fn from( + NightmareCompositeBorrowed { + custom, + spongebob, + domain, + }: NightmareCompositeBorrowed<'a>, + ) -> Self { + Self { + custom: custom.map(|v| v.into()).collect(), + spongebob: spongebob.map(|v| v).collect(), + domain: domain.into(), + } + } + } + impl<'a> postgres_types::FromSql<'a> for NightmareCompositeBorrowed<'a> { + fn from_sql( + ty: &postgres_types::Type, + out: &'a [u8], + ) -> Result, Box> + { + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + let mut out = out; + let num_fields = postgres_types::private::read_be_i32(&mut out)?; + if num_fields as usize != fields.len() { + return std::result::Result::Err(std::convert::Into::into(format!( + "invalid field count: {} vs {}", + num_fields, + fields.len() + ))); + } + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let custom = postgres_types::private::read_value(fields[0].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let spongebob = postgres_types::private::read_value(fields[1].type_(), &mut out)?; + let _oid = postgres_types::private::read_be_i32(&mut out)?; + let domain = postgres_types::private::read_value(fields[2].type_(), &mut out)?; + Ok(NightmareCompositeBorrowed { + custom, + spongebob, + domain, + }) + } + fn accepts(ty: &postgres_types::Type) -> bool { + ty.name() == "nightmare_composite" && ty.schema() == "schema" + } + } + #[derive(Debug)] + pub struct NightmareCompositeParams<'a> { + pub custom: &'a [super::CustomCompositeBorrowed<'a>], + pub spongebob: &'a [super::SpongebobCharacter], + pub domain: &'a str, + } + impl<'a> postgres_types::ToSql for NightmareCompositeParams<'a> { + fn to_sql( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + let NightmareCompositeParams { + custom, + spongebob, + domain, + } = self; + let fields = match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => fields, + _ => unreachable!(), + }; + out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); + for field in fields { + out.extend_from_slice(&field.type_().oid().to_be_bytes()); + let base = out.len(); + out.extend_from_slice(&[0; 4]); + let r = match field.name() { + "custom" => postgres_types::ToSql::to_sql(custom, field.type_(), out), + "spongebob" => postgres_types::ToSql::to_sql(spongebob, field.type_(), out), + "domain" => { + postgres_types::ToSql::to_sql(&crate::Domain(domain), field.type_(), out) + } + _ => unreachable!(), + }; + let count = match r? { + postgres_types::IsNull::Yes => -1, + postgres_types::IsNull::No => { + let len = out.len() - base - 4; + if len > i32::MAX as usize { + return Err(Into::into("value too large to transmit")); + } + len as i32 + } + }; + out[base..base + 4].copy_from_slice(&count.to_be_bytes()); + } + Ok(postgres_types::IsNull::No) + } + fn accepts(ty: &postgres_types::Type) -> bool { + if ty.name() != "nightmare_composite" { + return false; + } + match *ty.kind() { + postgres_types::Kind::Composite(ref fields) => { + if fields.len() != 3 { + return false; + } + fields.iter().all(|f| match f.name() + { + "custom" => <&'a [super::CustomCompositeBorrowed<'a>] as + postgres_types::ToSql>::accepts(f.type_()),"spongebob" => <&'a [super::SpongebobCharacter] as + postgres_types::ToSql>::accepts(f.type_()),"domain" => as + postgres_types::ToSql>::accepts(f.type_()),_ => false, + }) + } + _ => false, + } + } + fn to_sql_checked( + &self, + ty: &postgres_types::Type, + out: &mut postgres_types::private::BytesMut, + ) -> Result> { + postgres_types::__to_sql_checked(self, ty, out) + } + } +} diff --git a/test_codegen/codegen/src/utils.rs b/test_codegen/codegen/src/utils.rs new file mode 100644 index 00000000..fca59fa2 --- /dev/null +++ b/test_codegen/codegen/src/utils.rs @@ -0,0 +1,14 @@ +// This file was generated with `cornucopia`. Do not modify. + +use postgres_types::{Kind, ToSql, Type}; +pub fn escape_domain(ty: &Type) -> &Type { + match ty.kind() { + Kind::Domain(ty) => ty, + _ => ty, + } +} +pub fn slice_iter<'a>( + s: &'a [&'a (dyn ToSql + Sync)], +) -> impl ExactSizeIterator + 'a { + s.iter().map(|s| *s as _) +} diff --git a/test_codegen/queries/stress.sql b/test_codegen/queries/stress.sql index e7d9e9e7..da56994b 100644 --- a/test_codegen/queries/stress.sql +++ b/test_codegen/queries/stress.sql @@ -40,3 +40,14 @@ FROM INSERT INTO nightmare (composite) VALUES (:composite); + +--! select_schema_nightmare +SELECT + * +FROM + schema.nightmare; + +--! insert_schema_nightmare +INSERT INTO schema.nightmare (composite) + VALUES (:composite); + diff --git a/test_codegen/schema.sql b/test_codegen/schema.sql index 7d7fcea9..8e2e99b4 100644 --- a/test_codegen/schema.sql +++ b/test_codegen/schema.sql @@ -189,6 +189,20 @@ CREATE TABLE nightmare ( composite nightmare_composite NOT NULL ); +-- Schema + +CREATE SCHEMA schema; + +CREATE TYPE schema.nightmare_composite AS ( + custom custom_composite[], + spongebob spongebob_character[], + domain my_domain +); + +CREATE TABLE schema.nightmare ( + composite schema.nightmare_composite NOT NULL +); + -- Syntax CREATE TYPE syntax_composite AS ( diff --git a/test_codegen/src/cornucopia.rs b/test_codegen/src/cornucopia.rs deleted file mode 100644 index 38df419d..00000000 --- a/test_codegen/src/cornucopia.rs +++ /dev/null @@ -1,8294 +0,0 @@ -// This file was generated with `cornucopia`. Do not modify. - -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod types { - pub mod public { - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Clone, PartialEq)] - #[postgres(name = "clone_composite")] - pub struct CloneComposite { - #[postgres(name = "first")] - pub first: i32, - #[postgres(name = "second")] - pub second: String, - } - #[derive(Debug)] - pub struct CloneCompositeBorrowed<'a> { - pub first: i32, - pub second: &'a str, - } - impl<'a> From> for CloneComposite { - fn from(CloneCompositeBorrowed { first, second }: CloneCompositeBorrowed<'a>) -> Self { - Self { - first, - second: second.into(), - } - } - } - impl<'a> postgres_types::FromSql<'a> for CloneCompositeBorrowed<'a> { - fn from_sql( - ty: &postgres_types::Type, - out: &'a [u8], - ) -> Result, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err(std::convert::Into::into(format!( - "invalid field count: {} vs {}", - num_fields, - fields.len() - ))); - } - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let first = postgres_types::private::read_value(fields[0].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let second = postgres_types::private::read_value(fields[1].type_(), &mut out)?; - Ok(CloneCompositeBorrowed { first, second }) - } - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "clone_composite" && ty.schema() == "public" - } - } - impl<'a> postgres_types::ToSql for CloneCompositeBorrowed<'a> { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let CloneCompositeBorrowed { first, second } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "first" => postgres_types::ToSql::to_sql(first, field.type_(), out), - "second" => postgres_types::ToSql::to_sql(second, field.type_(), out), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "clone_composite" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 2 { - return false; - } - fields.iter().all(|f| match f.name() { - "first" => ::accepts(f.type_()), - "second" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Copy, Clone, PartialEq)] - #[postgres(name = "copy_composite")] - pub struct CopyComposite { - #[postgres(name = "first")] - pub first: i32, - #[postgres(name = "second")] - pub second: f64, - } - impl<'a> postgres_types::ToSql for CopyComposite { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let CopyComposite { first, second } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "first" => postgres_types::ToSql::to_sql(first, field.type_(), out), - "second" => postgres_types::ToSql::to_sql(second, field.type_(), out), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "copy_composite" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 2 { - return false; - } - fields.iter().all(|f| match f.name() { - "first" => ::accepts(f.type_()), - "second" => ::accepts(f.type_()), - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Clone, PartialEq)] - #[postgres(name = "domain_composite")] - pub struct DomainComposite { - #[postgres(name = "txt")] - pub txt: String, - #[postgres(name = "json")] - pub json: serde_json::Value, - #[postgres(name = "nb")] - pub nb: i32, - #[postgres(name = "arr")] - pub arr: Vec, - } - #[derive(Debug)] - pub struct DomainCompositeBorrowed<'a> { - pub txt: &'a str, - pub json: postgres_types::Json<&'a serde_json::value::RawValue>, - pub nb: i32, - pub arr: cornucopia_async::ArrayIterator< - 'a, - postgres_types::Json<&'a serde_json::value::RawValue>, - >, - } - impl<'a> From> for DomainComposite { - fn from( - DomainCompositeBorrowed { txt, json, nb, arr }: DomainCompositeBorrowed<'a>, - ) -> Self { - Self { - txt: txt.into(), - json: serde_json::from_str(json.0.get()).unwrap(), - nb, - arr: arr - .map(|v| serde_json::from_str(v.0.get()).unwrap()) - .collect(), - } - } - } - impl<'a> postgres_types::FromSql<'a> for DomainCompositeBorrowed<'a> { - fn from_sql( - ty: &postgres_types::Type, - out: &'a [u8], - ) -> Result, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err(std::convert::Into::into(format!( - "invalid field count: {} vs {}", - num_fields, - fields.len() - ))); - } - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let txt = postgres_types::private::read_value(fields[0].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let json = postgres_types::private::read_value(fields[1].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let nb = postgres_types::private::read_value(fields[2].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let arr = postgres_types::private::read_value(fields[3].type_(), &mut out)?; - Ok(DomainCompositeBorrowed { txt, json, nb, arr }) - } - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "domain_composite" && ty.schema() == "public" - } - } - #[derive(Debug)] - pub struct DomainCompositeParams<'a> { - pub txt: &'a str, - pub json: &'a serde_json::value::Value, - pub nb: i32, - pub arr: &'a [&'a serde_json::value::Value], - } - impl<'a> postgres_types::ToSql for DomainCompositeParams<'a> { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let DomainCompositeParams { txt, json, nb, arr } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "txt" => postgres_types::ToSql::to_sql( - &cornucopia_async::private::Domain(txt), - field.type_(), - out, - ), - "json" => postgres_types::ToSql::to_sql( - &cornucopia_async::private::Domain(json), - field.type_(), - out, - ), - "nb" => postgres_types::ToSql::to_sql( - &cornucopia_async::private::Domain(nb), - field.type_(), - out, - ), - "arr" => postgres_types::ToSql::to_sql( - &cornucopia_async::private::Domain( - &cornucopia_async::private::DomainArray(arr), - ), - field.type_(), - out, - ), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "domain_composite" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 4 { - return false; - } - fields.iter().all(| f | match f.name() - { - "txt" => < cornucopia_async::private::Domain::<&'a str> as postgres_types :: - ToSql > :: accepts(f.type_()),"json" => < cornucopia_async::private::Domain::<&'a serde_json::value::Value> as postgres_types :: - ToSql > :: accepts(f.type_()),"nb" => < cornucopia_async::private::Domain:: as postgres_types :: - ToSql > :: accepts(f.type_()),"arr" => < cornucopia_async::private::Domain::> as postgres_types :: - ToSql > :: accepts(f.type_()),_ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Clone, PartialEq)] - #[postgres(name = "named_composite")] - pub struct NamedComposite { - #[postgres(name = "wow")] - pub wow: Option, - #[postgres(name = "such_cool")] - pub such_cool: Option, - } - #[derive(Debug)] - pub struct NamedCompositeBorrowed<'a> { - pub wow: Option<&'a str>, - pub such_cool: Option, - } - impl<'a> From> for NamedComposite { - fn from(NamedCompositeBorrowed { wow, such_cool }: NamedCompositeBorrowed<'a>) -> Self { - Self { - wow: wow.map(|v| v.into()), - such_cool, - } - } - } - impl<'a> postgres_types::FromSql<'a> for NamedCompositeBorrowed<'a> { - fn from_sql( - ty: &postgres_types::Type, - out: &'a [u8], - ) -> Result, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err(std::convert::Into::into(format!( - "invalid field count: {} vs {}", - num_fields, - fields.len() - ))); - } - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let wow = postgres_types::private::read_value(fields[0].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let such_cool = postgres_types::private::read_value(fields[1].type_(), &mut out)?; - Ok(NamedCompositeBorrowed { wow, such_cool }) - } - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "named_composite" && ty.schema() == "public" - } - } - impl<'a> postgres_types::ToSql for NamedCompositeBorrowed<'a> { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let NamedCompositeBorrowed { wow, such_cool } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "wow" => postgres_types::ToSql::to_sql(wow, field.type_(), out), - "such_cool" => postgres_types::ToSql::to_sql(such_cool, field.type_(), out), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "named_composite" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 2 { - return false; - } - fields.iter().all(|f| match f.name() { - "wow" => <&'a str as postgres_types::ToSql>::accepts(f.type_()), - "such_cool" => ::accepts(f.type_()), - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, Clone, Copy, PartialEq, Eq)] - #[allow(non_camel_case_types)] - pub enum EnumWithDot { - variant_with_dot, - } - impl<'a> postgres_types::ToSql for EnumWithDot { - fn to_sql( - &self, - ty: &postgres_types::Type, - buf: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let s = match *self { - EnumWithDot::variant_with_dot => "variant.with_dot", - }; - buf.extend_from_slice(s.as_bytes()); - std::result::Result::Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "enum.with_dot" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 1 { - return false; - } - variants.iter().all(|v| match &**v { - "variant.with_dot" => true, - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - impl<'a> postgres_types::FromSql<'a> for EnumWithDot { - fn from_sql( - ty: &postgres_types::Type, - buf: &'a [u8], - ) -> Result> { - match std::str::from_utf8(buf)? { - "variant.with_dot" => Ok(EnumWithDot::variant_with_dot), - s => Result::Err(Into::into(format!("invalid variant `{}`", s))), - } - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "enum.with_dot" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 1 { - return false; - } - variants.iter().all(|v| match &**v { - "variant.with_dot" => true, - _ => false, - }) - } - _ => false, - } - } - } - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Copy, Clone, PartialEq)] - #[postgres(name = "named_composite.with_dot")] - pub struct NamedCompositeWithDot { - #[postgres(name = "this.is.inconceivable")] - pub this_is_inconceivable: Option, - } - impl<'a> postgres_types::ToSql for NamedCompositeWithDot { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let NamedCompositeWithDot { - this_is_inconceivable, - } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "this.is.inconceivable" => { - postgres_types::ToSql::to_sql(this_is_inconceivable, field.type_(), out) - } - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "named_composite.with_dot" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 1 { - return false; - } - fields.iter().all(|f| match f.name() { - "this.is.inconceivable" => { - ::accepts( - f.type_(), - ) - } - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Clone, PartialEq)] - #[postgres(name = "nullity_composite")] - pub struct NullityComposite { - #[postgres(name = "jsons")] - pub jsons: Option>>, - #[postgres(name = "id")] - pub id: i32, - } - #[derive(Debug)] - pub struct NullityCompositeBorrowed<'a> { - pub jsons: Option< - cornucopia_async::ArrayIterator< - 'a, - Option>, - >, - >, - pub id: i32, - } - impl<'a> From> for NullityComposite { - fn from(NullityCompositeBorrowed { jsons, id }: NullityCompositeBorrowed<'a>) -> Self { - Self { - jsons: jsons.map(|v| { - v.map(|v| v.map(|v| serde_json::from_str(v.0.get()).unwrap())) - .collect() - }), - id, - } - } - } - impl<'a> postgres_types::FromSql<'a> for NullityCompositeBorrowed<'a> { - fn from_sql( - ty: &postgres_types::Type, - out: &'a [u8], - ) -> Result, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err(std::convert::Into::into(format!( - "invalid field count: {} vs {}", - num_fields, - fields.len() - ))); - } - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let jsons = postgres_types::private::read_value(fields[0].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let id = postgres_types::private::read_value(fields[1].type_(), &mut out)?; - Ok(NullityCompositeBorrowed { jsons, id }) - } - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "nullity_composite" && ty.schema() == "public" - } - } - #[derive(Debug)] - pub struct NullityCompositeParams<'a> { - pub jsons: Option<&'a [Option<&'a serde_json::value::Value>]>, - pub id: i32, - } - impl<'a> postgres_types::ToSql for NullityCompositeParams<'a> { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let NullityCompositeParams { jsons, id } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "jsons" => postgres_types::ToSql::to_sql(jsons, field.type_(), out), - "id" => postgres_types::ToSql::to_sql(id, field.type_(), out), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "nullity_composite" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 2 { - return false; - } - fields.iter().all(|f| { - match f.name() - { - "jsons" => < &'a [&'a serde_json::value::Value] as postgres_types :: - ToSql > :: accepts(f.type_()),"id" => < i32 as postgres_types :: - ToSql > :: accepts(f.type_()),_ => false, - } - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, Clone, Copy, PartialEq, Eq)] - #[allow(non_camel_case_types)] - pub enum SpongebobCharacter { - Bob, - Patrick, - Squidward, - } - impl<'a> postgres_types::ToSql for SpongebobCharacter { - fn to_sql( - &self, - ty: &postgres_types::Type, - buf: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let s = match *self { - SpongebobCharacter::Bob => "Bob", - SpongebobCharacter::Patrick => "Patrick", - SpongebobCharacter::Squidward => "Squidward", - }; - buf.extend_from_slice(s.as_bytes()); - std::result::Result::Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "spongebob_character" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 3 { - return false; - } - variants.iter().all(|v| match &**v { - "Bob" => true, - "Patrick" => true, - "Squidward" => true, - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - impl<'a> postgres_types::FromSql<'a> for SpongebobCharacter { - fn from_sql( - ty: &postgres_types::Type, - buf: &'a [u8], - ) -> Result> { - match std::str::from_utf8(buf)? { - "Bob" => Ok(SpongebobCharacter::Bob), - "Patrick" => Ok(SpongebobCharacter::Patrick), - "Squidward" => Ok(SpongebobCharacter::Squidward), - s => Result::Err(Into::into(format!("invalid variant `{}`", s))), - } - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "spongebob_character" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 3 { - return false; - } - variants.iter().all(|v| match &**v { - "Bob" => true, - "Patrick" => true, - "Squidward" => true, - _ => false, - }) - } - _ => false, - } - } - } - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Clone, PartialEq)] - #[postgres(name = "custom_composite")] - pub struct CustomComposite { - #[postgres(name = "wow")] - pub wow: String, - #[postgres(name = "such_cool")] - pub such_cool: i32, - #[postgres(name = "nice")] - pub nice: super::public::SpongebobCharacter, - } - #[derive(Debug)] - pub struct CustomCompositeBorrowed<'a> { - pub wow: &'a str, - pub such_cool: i32, - pub nice: super::public::SpongebobCharacter, - } - impl<'a> From> for CustomComposite { - fn from( - CustomCompositeBorrowed { - wow, - such_cool, - nice, - }: CustomCompositeBorrowed<'a>, - ) -> Self { - Self { - wow: wow.into(), - such_cool, - nice, - } - } - } - impl<'a> postgres_types::FromSql<'a> for CustomCompositeBorrowed<'a> { - fn from_sql( - ty: &postgres_types::Type, - out: &'a [u8], - ) -> Result, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err(std::convert::Into::into(format!( - "invalid field count: {} vs {}", - num_fields, - fields.len() - ))); - } - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let wow = postgres_types::private::read_value(fields[0].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let such_cool = postgres_types::private::read_value(fields[1].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let nice = postgres_types::private::read_value(fields[2].type_(), &mut out)?; - Ok(CustomCompositeBorrowed { - wow, - such_cool, - nice, - }) - } - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "custom_composite" && ty.schema() == "public" - } - } - impl<'a> postgres_types::ToSql for CustomCompositeBorrowed<'a> { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let CustomCompositeBorrowed { - wow, - such_cool, - nice, - } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "wow" => postgres_types::ToSql::to_sql(wow, field.type_(), out), - "such_cool" => postgres_types::ToSql::to_sql(such_cool, field.type_(), out), - "nice" => postgres_types::ToSql::to_sql(nice, field.type_(), out), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "custom_composite" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 3 { - return false; - } - fields.iter().all(| f | match f.name() - { - "wow" => < &'a str as postgres_types :: - ToSql > :: accepts(f.type_()),"such_cool" => < i32 as postgres_types :: - ToSql > :: accepts(f.type_()),"nice" => < super::public::SpongebobCharacter as postgres_types :: - ToSql > :: accepts(f.type_()),_ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Clone, PartialEq)] - #[postgres(name = "nightmare_composite")] - pub struct NightmareComposite { - #[postgres(name = "custom")] - pub custom: Vec, - #[postgres(name = "spongebob")] - pub spongebob: Vec, - #[postgres(name = "domain")] - pub domain: String, - } - #[derive(Debug)] - pub struct NightmareCompositeBorrowed<'a> { - pub custom: - cornucopia_async::ArrayIterator<'a, super::public::CustomCompositeBorrowed<'a>>, - pub spongebob: cornucopia_async::ArrayIterator<'a, super::public::SpongebobCharacter>, - pub domain: &'a str, - } - impl<'a> From> for NightmareComposite { - fn from( - NightmareCompositeBorrowed { - custom, - spongebob, - domain, - }: NightmareCompositeBorrowed<'a>, - ) -> Self { - Self { - custom: custom.map(|v| v.into()).collect(), - spongebob: spongebob.map(|v| v).collect(), - domain: domain.into(), - } - } - } - impl<'a> postgres_types::FromSql<'a> for NightmareCompositeBorrowed<'a> { - fn from_sql( - ty: &postgres_types::Type, - out: &'a [u8], - ) -> Result, Box> - { - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - let mut out = out; - let num_fields = postgres_types::private::read_be_i32(&mut out)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err(std::convert::Into::into(format!( - "invalid field count: {} vs {}", - num_fields, - fields.len() - ))); - } - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let custom = postgres_types::private::read_value(fields[0].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let spongebob = postgres_types::private::read_value(fields[1].type_(), &mut out)?; - let _oid = postgres_types::private::read_be_i32(&mut out)?; - let domain = postgres_types::private::read_value(fields[2].type_(), &mut out)?; - Ok(NightmareCompositeBorrowed { - custom, - spongebob, - domain, - }) - } - fn accepts(ty: &postgres_types::Type) -> bool { - ty.name() == "nightmare_composite" && ty.schema() == "public" - } - } - #[derive(Debug)] - pub struct NightmareCompositeParams<'a> { - pub custom: &'a [super::public::CustomCompositeBorrowed<'a>], - pub spongebob: &'a [super::public::SpongebobCharacter], - pub domain: &'a str, - } - impl<'a> postgres_types::ToSql for NightmareCompositeParams<'a> { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let NightmareCompositeParams { - custom, - spongebob, - domain, - } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "custom" => postgres_types::ToSql::to_sql(custom, field.type_(), out), - "spongebob" => postgres_types::ToSql::to_sql(spongebob, field.type_(), out), - "domain" => postgres_types::ToSql::to_sql( - &cornucopia_async::private::Domain(domain), - field.type_(), - out, - ), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "nightmare_composite" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 3 { - return false; - } - fields.iter().all(| f | match f.name() - { - "custom" => < &'a [super::public::CustomCompositeBorrowed<'a>] as postgres_types :: - ToSql > :: accepts(f.type_()),"spongebob" => < &'a [super::public::SpongebobCharacter] as postgres_types :: - ToSql > :: accepts(f.type_()),"domain" => < cornucopia_async::private::Domain::<&'a str> as postgres_types :: - ToSql > :: accepts(f.type_()),_ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, postgres_types :: FromSql, Copy, Clone, PartialEq)] - #[postgres(name = "syntax_composite")] - pub struct SyntaxComposite { - #[postgres(name = "async")] - pub r#async: i32, - } - impl<'a> postgres_types::ToSql for SyntaxComposite { - fn to_sql( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let SyntaxComposite { r#async } = self; - let fields = match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - out.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - for field in fields { - out.extend_from_slice(&field.type_().oid().to_be_bytes()); - let base = out.len(); - out.extend_from_slice(&[0; 4]); - let r = match field.name() { - "async" => postgres_types::ToSql::to_sql(r#async, field.type_(), out), - _ => unreachable!(), - }; - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = out.len() - base - 4; - if len > i32::max_value() as usize { - return Err(Into::into("value too large to transmit")); - } - len as i32 - } - }; - out[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "syntax_composite" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Composite(ref fields) => { - if fields.len() != 1 { - return false; - } - fields.iter().all(|f| match f.name() { - "async" => ::accepts(f.type_()), - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - #[derive(serde::Serialize, Debug, Clone, Copy, PartialEq, Eq)] - #[allow(non_camel_case_types)] - pub enum SyntaxEnum { - r#async, - r#box, - I_Love_Chocolate, - } - impl<'a> postgres_types::ToSql for SyntaxEnum { - fn to_sql( - &self, - ty: &postgres_types::Type, - buf: &mut postgres_types::private::BytesMut, - ) -> Result> - { - let s = match *self { - SyntaxEnum::r#async => "async", - SyntaxEnum::r#box => "box", - SyntaxEnum::I_Love_Chocolate => "I Love Chocolate", - }; - buf.extend_from_slice(s.as_bytes()); - std::result::Result::Ok(postgres_types::IsNull::No) - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "syntax_enum" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 3 { - return false; - } - variants.iter().all(|v| match &**v { - "async" => true, - "box" => true, - "I Love Chocolate" => true, - _ => false, - }) - } - _ => false, - } - } - fn to_sql_checked( - &self, - ty: &postgres_types::Type, - out: &mut postgres_types::private::BytesMut, - ) -> Result> - { - postgres_types::__to_sql_checked(self, ty, out) - } - } - impl<'a> postgres_types::FromSql<'a> for SyntaxEnum { - fn from_sql( - ty: &postgres_types::Type, - buf: &'a [u8], - ) -> Result> { - match std::str::from_utf8(buf)? { - "async" => Ok(SyntaxEnum::r#async), - "box" => Ok(SyntaxEnum::r#box), - "I Love Chocolate" => Ok(SyntaxEnum::I_Love_Chocolate), - s => Result::Err(Into::into(format!("invalid variant `{}`", s))), - } - } - fn accepts(ty: &postgres_types::Type) -> bool { - if ty.name() != "syntax_enum" { - return false; - } - match *ty.kind() { - postgres_types::Kind::Enum(ref variants) => { - if variants.len() != 3 { - return false; - } - variants.iter().all(|v| match &**v { - "async" => true, - "box" => true, - "I Love Chocolate" => true, - _ => false, - }) - } - _ => false, - } - } - } - } -} -#[allow(clippy::all, clippy::pedantic)] -#[allow(unused_variables)] -#[allow(unused_imports)] -#[allow(dead_code)] -pub mod queries { - pub mod copy { - pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct PublicCloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn( - &postgres::Row, - ) - -> super::super::super::types::public::CloneCompositeBorrowed, - mapper: fn(super::super::super::types::public::CloneCompositeBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicCloneCompositeQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::super::types::public::CloneCompositeBorrowed) -> R, - ) -> PublicCloneCompositeQuery<'a, C, R, N> { - PublicCloneCompositeQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct PublicCopyCompositeQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::super::super::types::public::CopyComposite, - mapper: fn(super::super::super::types::public::CopyComposite) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicCopyCompositeQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::super::types::public::CopyComposite) -> R, - ) -> PublicCopyCompositeQuery<'a, C, R, N> { - PublicCopyCompositeQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn insert_clone() -> InsertCloneStmt { - InsertCloneStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO clone (composite) VALUES ($1)", - )) - } - pub struct InsertCloneStmt(cornucopia_sync::private::Stmt); - impl InsertCloneStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - composite: &'a super::super::super::types::public::CloneCompositeBorrowed<'a>, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[composite]) - } - } - pub fn select_clone() -> SelectCloneStmt { - SelectCloneStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM clone")) - } - pub struct SelectCloneStmt(cornucopia_sync::private::Stmt); - impl SelectCloneStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> PublicCloneCompositeQuery< - 'a, - C, - super::super::super::types::public::CloneComposite, - 0, - > { - PublicCloneCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn insert_copy() -> InsertCopyStmt { - InsertCopyStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO copy (composite) VALUES ($1)", - )) - } - pub struct InsertCopyStmt(cornucopia_sync::private::Stmt); - impl InsertCopyStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - composite: &'a super::super::super::types::public::CopyComposite, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[composite]) - } - } - pub fn select_copy() -> SelectCopyStmt { - SelectCopyStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM copy")) - } - pub struct SelectCopyStmt(cornucopia_sync::private::Stmt); - impl SelectCopyStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> PublicCopyCompositeQuery< - 'a, - C, - super::super::super::types::public::CopyComposite, - 0, - > { - PublicCopyCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it, - } - } - } - } - pub mod async_ { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct PublicCloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn( - &tokio_postgres::Row, - ) - -> super::super::super::types::public::CloneCompositeBorrowed, - mapper: fn(super::super::super::types::public::CloneCompositeBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicCloneCompositeQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::super::types::public::CloneCompositeBorrowed) -> R, - ) -> PublicCloneCompositeQuery<'a, C, R, N> { - PublicCloneCompositeQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct PublicCopyCompositeQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: - fn(&tokio_postgres::Row) -> super::super::super::types::public::CopyComposite, - mapper: fn(super::super::super::types::public::CopyComposite) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicCopyCompositeQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::super::types::public::CopyComposite) -> R, - ) -> PublicCopyCompositeQuery<'a, C, R, N> { - PublicCopyCompositeQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn insert_clone() -> InsertCloneStmt { - InsertCloneStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO clone (composite) VALUES ($1)", - )) - } - pub struct InsertCloneStmt(cornucopia_async::private::Stmt); - impl InsertCloneStmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - composite: &'a super::super::super::types::public::CloneCompositeBorrowed<'a>, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[composite]).await - } - } - pub fn select_clone() -> SelectCloneStmt { - SelectCloneStmt(cornucopia_async::private::Stmt::new("SELECT * FROM clone")) - } - pub struct SelectCloneStmt(cornucopia_async::private::Stmt); - impl SelectCloneStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> PublicCloneCompositeQuery< - 'a, - C, - super::super::super::types::public::CloneComposite, - 0, - > { - PublicCloneCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn insert_copy() -> InsertCopyStmt { - InsertCopyStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO copy (composite) VALUES ($1)", - )) - } - pub struct InsertCopyStmt(cornucopia_async::private::Stmt); - impl InsertCopyStmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - composite: &'a super::super::super::types::public::CopyComposite, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[composite]).await - } - } - pub fn select_copy() -> SelectCopyStmt { - SelectCopyStmt(cornucopia_async::private::Stmt::new("SELECT * FROM copy")) - } - pub struct SelectCopyStmt(cornucopia_async::private::Stmt); - impl SelectCopyStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> PublicCopyCompositeQuery< - 'a, - C, - super::super::super::types::public::CopyComposite, - 0, - > { - PublicCopyCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it, - } - } - } - } - } - pub mod domain { - #[derive(Debug)] - pub struct InsertNightmareDomainParams< - 'a, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::JsonSql, - T3: cornucopia_async::JsonSql, - T4: cornucopia_async::ArraySql, - > { - pub txt: T1, - pub json: T2, - pub nb: i32, - pub arr: T4, - pub composite: Option>, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct SelectNightmareDomain { - pub txt: String, - pub json: serde_json::Value, - pub nb: i32, - pub arr: Vec, - } - pub struct SelectNightmareDomainBorrowed<'a> { - pub txt: &'a str, - pub json: postgres_types::Json<&'a serde_json::value::RawValue>, - pub nb: i32, - pub arr: cornucopia_async::ArrayIterator< - 'a, - postgres_types::Json<&'a serde_json::value::RawValue>, - >, - } - impl<'a> From> for SelectNightmareDomain { - fn from( - SelectNightmareDomainBorrowed { txt, json, nb, arr }: SelectNightmareDomainBorrowed< - 'a, - >, - ) -> Self { - Self { - txt: txt.into(), - json: serde_json::from_str(json.0.get()).unwrap(), - nb, - arr: arr - .map(|v| serde_json::from_str(v.0.get()).unwrap()) - .collect(), - } - } - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct SelectNightmareDomainNull { - pub txt: Option, - pub json: Option, - pub nb: Option, - pub arr: Option>>, - pub composite: Option, - } - pub struct SelectNightmareDomainNullBorrowed<'a> { - pub txt: Option<&'a str>, - pub json: Option>, - pub nb: Option, - pub arr: Option< - cornucopia_async::ArrayIterator< - 'a, - Option>, - >, - >, - pub composite: Option>, - } - impl<'a> From> for SelectNightmareDomainNull { - fn from( - SelectNightmareDomainNullBorrowed { - txt, - json, - nb, - arr, - composite, - }: SelectNightmareDomainNullBorrowed<'a>, - ) -> Self { - Self { - txt: txt.map(|v| v.into()), - json: json.map(|v| serde_json::from_str(v.0.get()).unwrap()), - nb, - arr: arr.map(|v| { - v.map(|v| v.map(|v| serde_json::from_str(v.0.get()).unwrap())) - .collect() - }), - composite: composite.map(|v| v.into()), - } - } - } - pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct SelectNightmareDomainQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::SelectNightmareDomainBorrowed, - mapper: fn(super::SelectNightmareDomainBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectNightmareDomainQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::SelectNightmareDomainBorrowed) -> R, - ) -> SelectNightmareDomainQuery<'a, C, R, N> { - SelectNightmareDomainQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct SelectNightmareDomainNullQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::SelectNightmareDomainNullBorrowed, - mapper: fn(super::SelectNightmareDomainNullBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectNightmareDomainNullQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::SelectNightmareDomainNullBorrowed) -> R, - ) -> SelectNightmareDomainNullQuery<'a, C, R, N> { - SelectNightmareDomainNullQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn select_nightmare_domain() -> SelectNightmareDomainStmt { - SelectNightmareDomainStmt(cornucopia_sync::private::Stmt::new( - "SELECT txt, json, nb, arr FROM nightmare_domain", - )) - } - pub struct SelectNightmareDomainStmt(cornucopia_sync::private::Stmt); - impl SelectNightmareDomainStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> SelectNightmareDomainQuery<'a, C, super::SelectNightmareDomain, 0> - { - SelectNightmareDomainQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::SelectNightmareDomainBorrowed { - txt: row.get(0), - json: row.get(1), - nb: row.get(2), - arr: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn insert_nightmare_domain() -> InsertNightmareDomainStmt { - InsertNightmareDomainStmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO nightmare_domain (txt, json, nb, arr, composite) VALUES ($1, $2, $3, $4, $5)")) - } - pub struct InsertNightmareDomainStmt(cornucopia_sync::private::Stmt); - impl InsertNightmareDomainStmt { - pub fn bind< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::JsonSql, - T3: cornucopia_sync::JsonSql, - T4: cornucopia_sync::ArraySql, - >( - &'a mut self, - client: &'a mut C, - txt: &'a T1, - json: &'a T2, - nb: &'a i32, - arr: &'a T4, - composite: &'a Option< - super::super::super::types::public::DomainCompositeParams<'a>, - >, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute( - stmt, - &[ - &cornucopia_sync::private::Domain(txt), - &cornucopia_sync::private::Domain(json), - &cornucopia_sync::private::Domain(nb), - &cornucopia_sync::private::Domain( - &cornucopia_sync::private::DomainArray(arr), - ), - composite, - ], - ) - } - } - impl< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::JsonSql, - T3: cornucopia_sync::JsonSql, - T4: cornucopia_sync::ArraySql, - > - cornucopia_sync::Params< - 'a, - super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, - Result, - C, - > for InsertNightmareDomainStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, - ) -> Result { - self.bind( - client, - ¶ms.txt, - ¶ms.json, - ¶ms.nb, - ¶ms.arr, - ¶ms.composite, - ) - } - } - pub fn select_nightmare_domain_null() -> SelectNightmareDomainNullStmt { - SelectNightmareDomainNullStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM nightmare_domain", - )) - } - pub struct SelectNightmareDomainNullStmt(cornucopia_sync::private::Stmt); - impl SelectNightmareDomainNullStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> SelectNightmareDomainNullQuery<'a, C, super::SelectNightmareDomainNull, 0> - { - SelectNightmareDomainNullQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::SelectNightmareDomainNullBorrowed { - txt: row.get(0), - json: row.get(1), - nb: row.get(2), - arr: row.get(3), - composite: row.get(4), - }, - mapper: |it| ::from(it), - } - } - } - } - pub mod async_ { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct SelectNightmareDomainQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::SelectNightmareDomainBorrowed, - mapper: fn(super::SelectNightmareDomainBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectNightmareDomainQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::SelectNightmareDomainBorrowed) -> R, - ) -> SelectNightmareDomainQuery<'a, C, R, N> { - SelectNightmareDomainQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct SelectNightmareDomainNullQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::SelectNightmareDomainNullBorrowed, - mapper: fn(super::SelectNightmareDomainNullBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectNightmareDomainNullQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::SelectNightmareDomainNullBorrowed) -> R, - ) -> SelectNightmareDomainNullQuery<'a, C, R, N> { - SelectNightmareDomainNullQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn select_nightmare_domain() -> SelectNightmareDomainStmt { - SelectNightmareDomainStmt(cornucopia_async::private::Stmt::new( - "SELECT txt, json, nb, arr FROM nightmare_domain", - )) - } - pub struct SelectNightmareDomainStmt(cornucopia_async::private::Stmt); - impl SelectNightmareDomainStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> SelectNightmareDomainQuery<'a, C, super::SelectNightmareDomain, 0> - { - SelectNightmareDomainQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::SelectNightmareDomainBorrowed { - txt: row.get(0), - json: row.get(1), - nb: row.get(2), - arr: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn insert_nightmare_domain() -> InsertNightmareDomainStmt { - InsertNightmareDomainStmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO nightmare_domain (txt, json, nb, arr, composite) VALUES ($1, $2, $3, $4, $5)")) - } - pub struct InsertNightmareDomainStmt(cornucopia_async::private::Stmt); - impl InsertNightmareDomainStmt { - pub async fn bind< - 'a, - C: GenericClient, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::JsonSql, - T3: cornucopia_async::JsonSql, - T4: cornucopia_async::ArraySql, - >( - &'a mut self, - client: &'a C, - txt: &'a T1, - json: &'a T2, - nb: &'a i32, - arr: &'a T4, - composite: &'a Option< - super::super::super::types::public::DomainCompositeParams<'a>, - >, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client - .execute( - stmt, - &[ - &cornucopia_async::private::Domain(txt), - &cornucopia_async::private::Domain(json), - &cornucopia_async::private::Domain(nb), - &cornucopia_async::private::Domain( - &cornucopia_async::private::DomainArray(arr), - ), - composite, - ], - ) - .await - } - } - impl< - 'a, - C: GenericClient + Send + Sync, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::JsonSql, - T3: cornucopia_async::JsonSql, - T4: cornucopia_async::ArraySql, - > - cornucopia_async::Params< - 'a, - super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for InsertNightmareDomainStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind( - client, - ¶ms.txt, - ¶ms.json, - ¶ms.nb, - ¶ms.arr, - ¶ms.composite, - )) - } - } - pub fn select_nightmare_domain_null() -> SelectNightmareDomainNullStmt { - SelectNightmareDomainNullStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM nightmare_domain", - )) - } - pub struct SelectNightmareDomainNullStmt(cornucopia_async::private::Stmt); - impl SelectNightmareDomainNullStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> SelectNightmareDomainNullQuery<'a, C, super::SelectNightmareDomainNull, 0> - { - SelectNightmareDomainNullQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::SelectNightmareDomainNullBorrowed { - txt: row.get(0), - json: row.get(1), - nb: row.get(2), - arr: row.get(3), - composite: row.get(4), - }, - mapper: |it| ::from(it), - } - } - } - } - } - pub mod named { - #[derive(Debug)] - pub struct NamedParams { - pub name: T1, - pub price: Option, - } - #[derive(Debug)] - pub struct NamedComplexParams<'a> { - pub named: super::super::types::public::NamedCompositeBorrowed<'a>, - pub named_with_dot: Option, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq, Copy)] - pub struct Id { - pub id: i32, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct Named { - pub id: i32, - pub name: String, - pub price: Option, - pub show: bool, - } - pub struct NamedBorrowed<'a> { - pub id: i32, - pub name: &'a str, - pub price: Option, - pub show: bool, - } - impl<'a> From> for Named { - fn from( - NamedBorrowed { - id, - name, - price, - show, - }: NamedBorrowed<'a>, - ) -> Self { - Self { - id, - name: name.into(), - price, - show, - } - } - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct NamedComplex { - pub named: super::super::types::public::NamedComposite, - pub named_with_dot: Option, - } - pub struct NamedComplexBorrowed<'a> { - pub named: super::super::types::public::NamedCompositeBorrowed<'a>, - pub named_with_dot: Option, - } - impl<'a> From> for NamedComplex { - fn from( - NamedComplexBorrowed { - named, - named_with_dot, - }: NamedComplexBorrowed<'a>, - ) -> Self { - Self { - named: named.into(), - named_with_dot, - } - } - } - pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct IdQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::Id, - mapper: fn(super::Id) -> T, - } - impl<'a, C, T: 'a, const N: usize> IdQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(super::Id) -> R) -> IdQuery<'a, C, R, N> { - IdQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct NamedQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::NamedBorrowed, - mapper: fn(super::NamedBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> NamedQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::NamedBorrowed) -> R, - ) -> NamedQuery<'a, C, R, N> { - NamedQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct NamedComplexQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::NamedComplexBorrowed, - mapper: fn(super::NamedComplexBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> NamedComplexQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::NamedComplexBorrowed) -> R, - ) -> NamedComplexQuery<'a, C, R, N> { - NamedComplexQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn new_named_visible() -> NewNamedVisibleStmt { - NewNamedVisibleStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, true) RETURNING id ", - )) - } - pub struct NewNamedVisibleStmt(cornucopia_sync::private::Stmt); - impl NewNamedVisibleStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - name: &'a T1, - price: &'a Option, - ) -> IdQuery<'a, C, super::Id, 2> { - IdQuery { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| super::Id { id: row.get(0) }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_sync::StringSql> - cornucopia_sync::Params<'a, super::NamedParams, IdQuery<'a, C, super::Id, 2>, C> - for NewNamedVisibleStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::NamedParams, - ) -> IdQuery<'a, C, super::Id, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn new_named_hidden() -> NewNamedHiddenStmt { - NewNamedHiddenStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO named (price, name, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct NewNamedHiddenStmt(cornucopia_sync::private::Stmt); - impl NewNamedHiddenStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - price: &'a Option, - name: &'a T1, - ) -> IdQuery<'a, C, super::Id, 2> { - IdQuery { - client, - params: [price, name], - stmt: &mut self.0, - extractor: |row| super::Id { id: row.get(0) }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_sync::StringSql> - cornucopia_sync::Params<'a, super::NamedParams, IdQuery<'a, C, super::Id, 2>, C> - for NewNamedHiddenStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::NamedParams, - ) -> IdQuery<'a, C, super::Id, 2> { - self.bind(client, ¶ms.price, ¶ms.name) - } - } - pub fn named() -> NamedStmt { - NamedStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM named")) - } - pub struct NamedStmt(cornucopia_sync::private::Stmt); - impl NamedStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> NamedQuery<'a, C, super::Named, 0> { - NamedQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::NamedBorrowed { - id: row.get(0), - name: row.get(1), - price: row.get(2), - show: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn named_by_id() -> NamedByIdStmt { - NamedByIdStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM named WHERE id = $1", - )) - } - pub struct NamedByIdStmt(cornucopia_sync::private::Stmt); - impl NamedByIdStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - id: &'a i32, - ) -> NamedQuery<'a, C, super::Named, 1> { - NamedQuery { - client, - params: [id], - stmt: &mut self.0, - extractor: |row| super::NamedBorrowed { - id: row.get(0), - name: row.get(1), - price: row.get(2), - show: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn new_named_complex() -> NewNamedComplexStmt { - NewNamedComplexStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO named_complex (named, \"named.with_dot\") VALUES ($1, $2)", - )) - } - pub struct NewNamedComplexStmt(cornucopia_sync::private::Stmt); - impl NewNamedComplexStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - named: &'a super::super::super::types::public::NamedCompositeBorrowed<'a>, - named_with_dot: &'a Option< - super::super::super::types::public::NamedCompositeWithDot, - >, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[named, named_with_dot]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::NamedComplexParams<'a>, - Result, - C, - > for NewNamedComplexStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::NamedComplexParams<'a>, - ) -> Result { - self.bind(client, ¶ms.named, ¶ms.named_with_dot) - } - } - pub fn named_complex() -> NamedComplexStmt { - NamedComplexStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM named_complex", - )) - } - pub struct NamedComplexStmt(cornucopia_sync::private::Stmt); - impl NamedComplexStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> NamedComplexQuery<'a, C, super::NamedComplex, 0> { - NamedComplexQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::NamedComplexBorrowed { - named: row.get(0), - named_with_dot: row.get(1), - }, - mapper: |it| ::from(it), - } - } - } - } - pub mod async_ { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct IdQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::Id, - mapper: fn(super::Id) -> T, - } - impl<'a, C, T: 'a, const N: usize> IdQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(super::Id) -> R) -> IdQuery<'a, C, R, N> { - IdQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct NamedQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::NamedBorrowed, - mapper: fn(super::NamedBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> NamedQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::NamedBorrowed) -> R, - ) -> NamedQuery<'a, C, R, N> { - NamedQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct NamedComplexQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::NamedComplexBorrowed, - mapper: fn(super::NamedComplexBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> NamedComplexQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::NamedComplexBorrowed) -> R, - ) -> NamedComplexQuery<'a, C, R, N> { - NamedComplexQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn new_named_visible() -> NewNamedVisibleStmt { - NewNamedVisibleStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, true) RETURNING id ", - )) - } - pub struct NewNamedVisibleStmt(cornucopia_async::private::Stmt); - impl NewNamedVisibleStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - name: &'a T1, - price: &'a Option, - ) -> IdQuery<'a, C, super::Id, 2> { - IdQuery { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| super::Id { id: row.get(0) }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_async::StringSql> - cornucopia_async::Params< - 'a, - super::NamedParams, - IdQuery<'a, C, super::Id, 2>, - C, - > for NewNamedVisibleStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::NamedParams, - ) -> IdQuery<'a, C, super::Id, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn new_named_hidden() -> NewNamedHiddenStmt { - NewNamedHiddenStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO named (price, name, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct NewNamedHiddenStmt(cornucopia_async::private::Stmt); - impl NewNamedHiddenStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - price: &'a Option, - name: &'a T1, - ) -> IdQuery<'a, C, super::Id, 2> { - IdQuery { - client, - params: [price, name], - stmt: &mut self.0, - extractor: |row| super::Id { id: row.get(0) }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_async::StringSql> - cornucopia_async::Params< - 'a, - super::NamedParams, - IdQuery<'a, C, super::Id, 2>, - C, - > for NewNamedHiddenStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::NamedParams, - ) -> IdQuery<'a, C, super::Id, 2> { - self.bind(client, ¶ms.price, ¶ms.name) - } - } - pub fn named() -> NamedStmt { - NamedStmt(cornucopia_async::private::Stmt::new("SELECT * FROM named")) - } - pub struct NamedStmt(cornucopia_async::private::Stmt); - impl NamedStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> NamedQuery<'a, C, super::Named, 0> { - NamedQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::NamedBorrowed { - id: row.get(0), - name: row.get(1), - price: row.get(2), - show: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn named_by_id() -> NamedByIdStmt { - NamedByIdStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM named WHERE id = $1", - )) - } - pub struct NamedByIdStmt(cornucopia_async::private::Stmt); - impl NamedByIdStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - id: &'a i32, - ) -> NamedQuery<'a, C, super::Named, 1> { - NamedQuery { - client, - params: [id], - stmt: &mut self.0, - extractor: |row| super::NamedBorrowed { - id: row.get(0), - name: row.get(1), - price: row.get(2), - show: row.get(3), - }, - mapper: |it| ::from(it), - } - } - } - pub fn new_named_complex() -> NewNamedComplexStmt { - NewNamedComplexStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO named_complex (named, \"named.with_dot\") VALUES ($1, $2)", - )) - } - pub struct NewNamedComplexStmt(cornucopia_async::private::Stmt); - impl NewNamedComplexStmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - named: &'a super::super::super::types::public::NamedCompositeBorrowed<'a>, - named_with_dot: &'a Option< - super::super::super::types::public::NamedCompositeWithDot, - >, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[named, named_with_dot]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::NamedComplexParams<'a>, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for NewNamedComplexStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::NamedComplexParams<'a>, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.named, ¶ms.named_with_dot)) - } - } - pub fn named_complex() -> NamedComplexStmt { - NamedComplexStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM named_complex", - )) - } - pub struct NamedComplexStmt(cornucopia_async::private::Stmt); - impl NamedComplexStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> NamedComplexQuery<'a, C, super::NamedComplex, 0> { - NamedComplexQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::NamedComplexBorrowed { - named: row.get(0), - named_with_dot: row.get(1), - }, - mapper: |it| ::from(it), - } - } - } - } - } - pub mod nullity { - #[derive(Debug)] - pub struct NullityParams< - 'a, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::ArraySql>, - T3: cornucopia_async::StringSql, - > { - pub texts: T2, - pub name: T3, - pub composite: Option>, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct Nullity { - pub texts: Vec>, - pub name: String, - pub composite: Option, - } - pub struct NullityBorrowed<'a> { - pub texts: cornucopia_async::ArrayIterator<'a, Option<&'a str>>, - pub name: &'a str, - pub composite: Option>, - } - impl<'a> From> for Nullity { - fn from( - NullityBorrowed { - texts, - name, - composite, - }: NullityBorrowed<'a>, - ) -> Self { - Self { - texts: texts.map(|v| v.map(|v| v.into())).collect(), - name: name.into(), - composite: composite.map(|v| v.into()), - } - } - } - pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct NullityQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::NullityBorrowed, - mapper: fn(super::NullityBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> NullityQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::NullityBorrowed) -> R, - ) -> NullityQuery<'a, C, R, N> { - NullityQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn new_nullity() -> NewNullityStmt { - NewNullityStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO nullity(texts, name, composite) VALUES ($1, $2, $3)", - )) - } - pub struct NewNullityStmt(cornucopia_sync::private::Stmt); - impl NewNullityStmt { - pub fn bind< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::ArraySql>, - T3: cornucopia_sync::StringSql, - >( - &'a mut self, - client: &'a mut C, - texts: &'a T2, - name: &'a T3, - composite: &'a Option< - super::super::super::types::public::NullityCompositeParams<'a>, - >, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[texts, name, composite]) - } - } - impl< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::ArraySql>, - T3: cornucopia_sync::StringSql, - > - cornucopia_sync::Params< - 'a, - super::NullityParams<'a, T1, T2, T3>, - Result, - C, - > for NewNullityStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::NullityParams<'a, T1, T2, T3>, - ) -> Result { - self.bind(client, ¶ms.texts, ¶ms.name, ¶ms.composite) - } - } - pub fn nullity() -> NullityStmt { - NullityStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM nullity")) - } - pub struct NullityStmt(cornucopia_sync::private::Stmt); - impl NullityStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> NullityQuery<'a, C, super::Nullity, 0> { - NullityQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::NullityBorrowed { - texts: row.get(0), - name: row.get(1), - composite: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - } - pub mod async_ { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct NullityQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::NullityBorrowed, - mapper: fn(super::NullityBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> NullityQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::NullityBorrowed) -> R, - ) -> NullityQuery<'a, C, R, N> { - NullityQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn new_nullity() -> NewNullityStmt { - NewNullityStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO nullity(texts, name, composite) VALUES ($1, $2, $3)", - )) - } - pub struct NewNullityStmt(cornucopia_async::private::Stmt); - impl NewNullityStmt { - pub async fn bind< - 'a, - C: GenericClient, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::ArraySql>, - T3: cornucopia_async::StringSql, - >( - &'a mut self, - client: &'a C, - texts: &'a T2, - name: &'a T3, - composite: &'a Option< - super::super::super::types::public::NullityCompositeParams<'a>, - >, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[texts, name, composite]).await - } - } - impl< - 'a, - C: GenericClient + Send + Sync, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::ArraySql>, - T3: cornucopia_async::StringSql, - > - cornucopia_async::Params< - 'a, - super::NullityParams<'a, T1, T2, T3>, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for NewNullityStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::NullityParams<'a, T1, T2, T3>, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.texts, ¶ms.name, ¶ms.composite)) - } - } - pub fn nullity() -> NullityStmt { - NullityStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM nullity", - )) - } - pub struct NullityStmt(cornucopia_async::private::Stmt); - impl NullityStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> NullityQuery<'a, C, super::Nullity, 0> { - NullityQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::NullityBorrowed { - texts: row.get(0), - name: row.get(1), - composite: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - } - } - pub mod params { - #[derive(Debug)] - pub struct InsertBookParams< - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - > { - pub author: Option, - pub name: T2, - } - #[derive(Clone, Copy, Debug)] - pub struct ParamsOrderParams { - pub c: i32, - pub a: i32, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct SelectBook { - pub name: String, - pub author: Option, - } - pub struct SelectBookBorrowed<'a> { - pub name: &'a str, - pub author: Option<&'a str>, - } - impl<'a> From> for SelectBook { - fn from(SelectBookBorrowed { name, author }: SelectBookBorrowed<'a>) -> Self { - Self { - name: name.into(), - author: author.map(|v| v.into()), - } - } - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct FindBooks { - pub name: String, - pub author: Option, - } - pub struct FindBooksBorrowed<'a> { - pub name: &'a str, - pub author: Option<&'a str>, - } - impl<'a> From> for FindBooks { - fn from(FindBooksBorrowed { name, author }: FindBooksBorrowed<'a>) -> Self { - Self { - name: name.into(), - author: author.map(|v| v.into()), - } - } - } - pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct SelectBookQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::SelectBookBorrowed, - mapper: fn(super::SelectBookBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectBookQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::SelectBookBorrowed) -> R, - ) -> SelectBookQuery<'a, C, R, N> { - SelectBookQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct FindBooksQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::FindBooksBorrowed, - mapper: fn(super::FindBooksBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> FindBooksQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::FindBooksBorrowed) -> R, - ) -> FindBooksQuery<'a, C, R, N> { - FindBooksQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn insert_book() -> InsertBookStmt { - InsertBookStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO book (author, name) VALUES ($1, $2)", - )) - } - pub struct InsertBookStmt(cornucopia_sync::private::Stmt); - impl InsertBookStmt { - pub fn bind< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::StringSql, - >( - &'a mut self, - client: &'a mut C, - author: &'a Option, - name: &'a T2, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[author, name]) - } - } - impl< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::StringSql, - > - cornucopia_sync::Params< - 'a, - super::InsertBookParams, - Result, - C, - > for InsertBookStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::InsertBookParams, - ) -> Result { - self.bind(client, ¶ms.author, ¶ms.name) - } - } - pub fn select_book() -> SelectBookStmt { - SelectBookStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM book")) - } - pub struct SelectBookStmt(cornucopia_sync::private::Stmt); - impl SelectBookStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> SelectBookQuery<'a, C, super::SelectBook, 0> { - SelectBookQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::SelectBookBorrowed { - name: row.get(0), - author: row.get(1), - }, - mapper: |it| ::from(it), - } - } - } - pub fn find_books() -> FindBooksStmt { - FindBooksStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM book WHERE name = ANY ($1)", - )) - } - pub struct FindBooksStmt(cornucopia_sync::private::Stmt); - impl FindBooksStmt { - pub fn bind< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::ArraySql, - >( - &'a mut self, - client: &'a mut C, - title: &'a T2, - ) -> FindBooksQuery<'a, C, super::FindBooks, 1> { - FindBooksQuery { - client, - params: [title], - stmt: &mut self.0, - extractor: |row| super::FindBooksBorrowed { - name: row.get(0), - author: row.get(1), - }, - mapper: |it| ::from(it), - } - } - } - pub fn params_use_twice() -> ParamsUseTwiceStmt { - ParamsUseTwiceStmt(cornucopia_sync::private::Stmt::new( - "UPDATE book SET name = $1 WHERE length(name) > 42 AND length($1) < 42", - )) - } - pub struct ParamsUseTwiceStmt(cornucopia_sync::private::Stmt); - impl ParamsUseTwiceStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - name: &'a T1, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[name]) - } - } - pub fn params_order() -> ParamsOrderStmt { - ParamsOrderStmt(cornucopia_sync::private::Stmt::new( - "UPDATE imaginary SET c=$1, a=$2, z=$2, r=$1", - )) - } - pub struct ParamsOrderStmt(cornucopia_sync::private::Stmt); - impl ParamsOrderStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - c: &'a i32, - a: &'a i32, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[c, a]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::ParamsOrderParams, - Result, - C, - > for ParamsOrderStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::ParamsOrderParams, - ) -> Result { - self.bind(client, ¶ms.c, ¶ms.a) - } - } - } - pub mod async_ { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct SelectBookQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::SelectBookBorrowed, - mapper: fn(super::SelectBookBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> SelectBookQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::SelectBookBorrowed) -> R, - ) -> SelectBookQuery<'a, C, R, N> { - SelectBookQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct FindBooksQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::FindBooksBorrowed, - mapper: fn(super::FindBooksBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> FindBooksQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::FindBooksBorrowed) -> R, - ) -> FindBooksQuery<'a, C, R, N> { - FindBooksQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn insert_book() -> InsertBookStmt { - InsertBookStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO book (author, name) VALUES ($1, $2)", - )) - } - pub struct InsertBookStmt(cornucopia_async::private::Stmt); - impl InsertBookStmt { - pub async fn bind< - 'a, - C: GenericClient, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - >( - &'a mut self, - client: &'a C, - author: &'a Option, - name: &'a T2, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[author, name]).await - } - } - impl< - 'a, - C: GenericClient + Send + Sync, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - > - cornucopia_async::Params< - 'a, - super::InsertBookParams, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for InsertBookStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::InsertBookParams, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.author, ¶ms.name)) - } - } - pub fn select_book() -> SelectBookStmt { - SelectBookStmt(cornucopia_async::private::Stmt::new("SELECT * FROM book")) - } - pub struct SelectBookStmt(cornucopia_async::private::Stmt); - impl SelectBookStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> SelectBookQuery<'a, C, super::SelectBook, 0> { - SelectBookQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::SelectBookBorrowed { - name: row.get(0), - author: row.get(1), - }, - mapper: |it| ::from(it), - } - } - } - pub fn find_books() -> FindBooksStmt { - FindBooksStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM book WHERE name = ANY ($1)", - )) - } - pub struct FindBooksStmt(cornucopia_async::private::Stmt); - impl FindBooksStmt { - pub fn bind< - 'a, - C: GenericClient, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::ArraySql, - >( - &'a mut self, - client: &'a C, - title: &'a T2, - ) -> FindBooksQuery<'a, C, super::FindBooks, 1> { - FindBooksQuery { - client, - params: [title], - stmt: &mut self.0, - extractor: |row| super::FindBooksBorrowed { - name: row.get(0), - author: row.get(1), - }, - mapper: |it| ::from(it), - } - } - } - pub fn params_use_twice() -> ParamsUseTwiceStmt { - ParamsUseTwiceStmt(cornucopia_async::private::Stmt::new( - "UPDATE book SET name = $1 WHERE length(name) > 42 AND length($1) < 42", - )) - } - pub struct ParamsUseTwiceStmt(cornucopia_async::private::Stmt); - impl ParamsUseTwiceStmt { - pub async fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - name: &'a T1, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[name]).await - } - } - pub fn params_order() -> ParamsOrderStmt { - ParamsOrderStmt(cornucopia_async::private::Stmt::new( - "UPDATE imaginary SET c=$1, a=$2, z=$2, r=$1", - )) - } - pub struct ParamsOrderStmt(cornucopia_async::private::Stmt); - impl ParamsOrderStmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - c: &'a i32, - a: &'a i32, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[c, a]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::ParamsOrderParams, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for ParamsOrderStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::ParamsOrderParams, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.c, ¶ms.a)) - } - } - } - } - pub mod stress { - #[derive(Debug)] - pub struct EverythingParams< - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - T3: cornucopia_async::BytesSql, - T4: cornucopia_async::JsonSql, - T5: cornucopia_async::JsonSql, - > { - pub bool_: bool, - pub boolean_: bool, - pub char_: i8, - pub smallint_: i16, - pub int2_: i16, - pub smallserial_: i16, - pub serial2_: i16, - pub int_: i32, - pub int4_: i32, - pub serial_: i32, - pub serial4_: i32, - pub bingint_: i64, - pub int8_: i64, - pub bigserial_: i64, - pub serial8_: i64, - pub float4_: f32, - pub real_: f32, - pub float8_: f64, - pub double_precision_: f64, - pub text_: T1, - pub varchar_: T2, - pub bytea_: T3, - pub timestamp_: time::PrimitiveDateTime, - pub timestamp_without_time_zone_: time::PrimitiveDateTime, - pub timestamptz_: time::OffsetDateTime, - pub timestamp_with_time_zone_: time::OffsetDateTime, - pub date_: time::Date, - pub time_: time::Time, - pub json_: T4, - pub jsonb_: T5, - pub uuid_: uuid::Uuid, - pub inet_: std::net::IpAddr, - pub macaddr_: eui48::MacAddress, - pub numeric_: rust_decimal::Decimal, - } - #[derive(Debug)] - pub struct EverythingArrayParams< - T1: cornucopia_async::ArraySql, - T2: cornucopia_async::ArraySql, - T3: cornucopia_async::ArraySql, - T4: cornucopia_async::ArraySql, - T5: cornucopia_async::ArraySql, - T6: cornucopia_async::ArraySql, - T7: cornucopia_async::ArraySql, - T8: cornucopia_async::ArraySql, - T9: cornucopia_async::ArraySql, - T10: cornucopia_async::ArraySql, - T11: cornucopia_async::ArraySql, - T12: cornucopia_async::ArraySql, - T13: cornucopia_async::ArraySql, - T14: cornucopia_async::StringSql, - T15: cornucopia_async::ArraySql, - T16: cornucopia_async::StringSql, - T17: cornucopia_async::ArraySql, - T18: cornucopia_async::BytesSql, - T19: cornucopia_async::ArraySql, - T20: cornucopia_async::ArraySql, - T21: cornucopia_async::ArraySql, - T22: cornucopia_async::ArraySql, - T23: cornucopia_async::ArraySql, - T24: cornucopia_async::ArraySql, - T25: cornucopia_async::ArraySql, - T26: cornucopia_async::JsonSql, - T27: cornucopia_async::ArraySql, - T28: cornucopia_async::JsonSql, - T29: cornucopia_async::ArraySql, - T30: cornucopia_async::ArraySql, - T31: cornucopia_async::ArraySql, - T32: cornucopia_async::ArraySql, - T33: cornucopia_async::ArraySql, - > { - pub bool_: T1, - pub boolean_: T2, - pub char_: T3, - pub smallint_: T4, - pub int2_: T5, - pub int_: T6, - pub int4_: T7, - pub bingint_: T8, - pub int8_: T9, - pub float4_: T10, - pub real_: T11, - pub float8_: T12, - pub double_precision_: T13, - pub text_: T15, - pub varchar_: T17, - pub bytea_: T19, - pub timestamp_: T20, - pub timestamp_without_time_zone_: T21, - pub timestamptz_: T22, - pub timestamp_with_time_zone_: T23, - pub date_: T24, - pub time_: T25, - pub json_: T27, - pub jsonb_: T29, - pub uuid_: T30, - pub inet_: T31, - pub macaddr_: T32, - pub numeric_: T33, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct Everything { - pub bool_: bool, - pub boolean_: bool, - pub char_: i8, - pub smallint_: i16, - pub int2_: i16, - pub smallserial_: i16, - pub serial2_: i16, - pub int_: i32, - pub int4_: i32, - pub serial_: i32, - pub serial4_: i32, - pub bingint_: i64, - pub int8_: i64, - pub bigserial_: i64, - pub serial8_: i64, - pub float4_: f32, - pub real_: f32, - pub float8_: f64, - pub double_precision_: f64, - pub text_: String, - pub varchar_: String, - pub bytea_: Vec, - pub timestamp_: time::PrimitiveDateTime, - pub timestamp_without_time_zone_: time::PrimitiveDateTime, - pub timestamptz_: time::OffsetDateTime, - pub timestamp_with_time_zone_: time::OffsetDateTime, - pub date_: time::Date, - pub time_: time::Time, - pub json_: serde_json::Value, - pub jsonb_: serde_json::Value, - pub uuid_: uuid::Uuid, - pub inet_: std::net::IpAddr, - pub macaddr_: eui48::MacAddress, - pub numeric_: rust_decimal::Decimal, - } - pub struct EverythingBorrowed<'a> { - pub bool_: bool, - pub boolean_: bool, - pub char_: i8, - pub smallint_: i16, - pub int2_: i16, - pub smallserial_: i16, - pub serial2_: i16, - pub int_: i32, - pub int4_: i32, - pub serial_: i32, - pub serial4_: i32, - pub bingint_: i64, - pub int8_: i64, - pub bigserial_: i64, - pub serial8_: i64, - pub float4_: f32, - pub real_: f32, - pub float8_: f64, - pub double_precision_: f64, - pub text_: &'a str, - pub varchar_: &'a str, - pub bytea_: &'a [u8], - pub timestamp_: time::PrimitiveDateTime, - pub timestamp_without_time_zone_: time::PrimitiveDateTime, - pub timestamptz_: time::OffsetDateTime, - pub timestamp_with_time_zone_: time::OffsetDateTime, - pub date_: time::Date, - pub time_: time::Time, - pub json_: postgres_types::Json<&'a serde_json::value::RawValue>, - pub jsonb_: postgres_types::Json<&'a serde_json::value::RawValue>, - pub uuid_: uuid::Uuid, - pub inet_: std::net::IpAddr, - pub macaddr_: eui48::MacAddress, - pub numeric_: rust_decimal::Decimal, - } - impl<'a> From> for Everything { - fn from( - EverythingBorrowed { - bool_, - boolean_, - char_, - smallint_, - int2_, - smallserial_, - serial2_, - int_, - int4_, - serial_, - serial4_, - bingint_, - int8_, - bigserial_, - serial8_, - float4_, - real_, - float8_, - double_precision_, - text_, - varchar_, - bytea_, - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_, - jsonb_, - uuid_, - inet_, - macaddr_, - numeric_, - }: EverythingBorrowed<'a>, - ) -> Self { - Self { - bool_, - boolean_, - char_, - smallint_, - int2_, - smallserial_, - serial2_, - int_, - int4_, - serial_, - serial4_, - bingint_, - int8_, - bigserial_, - serial8_, - float4_, - real_, - float8_, - double_precision_, - text_: text_.into(), - varchar_: varchar_.into(), - bytea_: bytea_.into(), - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_: serde_json::from_str(json_.0.get()).unwrap(), - jsonb_: serde_json::from_str(jsonb_.0.get()).unwrap(), - uuid_, - inet_, - macaddr_, - numeric_, - } - } - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct EverythingNull { - pub bool_: Option, - pub boolean_: Option, - pub char_: Option, - pub smallint_: Option, - pub int2_: Option, - pub smallserial_: Option, - pub serial2_: Option, - pub int_: Option, - pub int4_: Option, - pub serial_: Option, - pub serial4_: Option, - pub bingint_: Option, - pub int8_: Option, - pub bigserial_: Option, - pub serial8_: Option, - pub float4_: Option, - pub real_: Option, - pub float8_: Option, - pub double_precision_: Option, - pub text_: Option, - pub varchar_: Option, - pub bytea_: Option>, - pub timestamp_: Option, - pub timestamp_without_time_zone_: Option, - pub timestamptz_: Option, - pub timestamp_with_time_zone_: Option, - pub date_: Option, - pub time_: Option, - pub json_: Option, - pub jsonb_: Option, - pub uuid_: Option, - pub inet_: Option, - pub macaddr_: Option, - pub numeric_: Option, - } - pub struct EverythingNullBorrowed<'a> { - pub bool_: Option, - pub boolean_: Option, - pub char_: Option, - pub smallint_: Option, - pub int2_: Option, - pub smallserial_: Option, - pub serial2_: Option, - pub int_: Option, - pub int4_: Option, - pub serial_: Option, - pub serial4_: Option, - pub bingint_: Option, - pub int8_: Option, - pub bigserial_: Option, - pub serial8_: Option, - pub float4_: Option, - pub real_: Option, - pub float8_: Option, - pub double_precision_: Option, - pub text_: Option<&'a str>, - pub varchar_: Option<&'a str>, - pub bytea_: Option<&'a [u8]>, - pub timestamp_: Option, - pub timestamp_without_time_zone_: Option, - pub timestamptz_: Option, - pub timestamp_with_time_zone_: Option, - pub date_: Option, - pub time_: Option, - pub json_: Option>, - pub jsonb_: Option>, - pub uuid_: Option, - pub inet_: Option, - pub macaddr_: Option, - pub numeric_: Option, - } - impl<'a> From> for EverythingNull { - fn from( - EverythingNullBorrowed { - bool_, - boolean_, - char_, - smallint_, - int2_, - smallserial_, - serial2_, - int_, - int4_, - serial_, - serial4_, - bingint_, - int8_, - bigserial_, - serial8_, - float4_, - real_, - float8_, - double_precision_, - text_, - varchar_, - bytea_, - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_, - jsonb_, - uuid_, - inet_, - macaddr_, - numeric_, - }: EverythingNullBorrowed<'a>, - ) -> Self { - Self { - bool_, - boolean_, - char_, - smallint_, - int2_, - smallserial_, - serial2_, - int_, - int4_, - serial_, - serial4_, - bingint_, - int8_, - bigserial_, - serial8_, - float4_, - real_, - float8_, - double_precision_, - text_: text_.map(|v| v.into()), - varchar_: varchar_.map(|v| v.into()), - bytea_: bytea_.map(|v| v.into()), - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_: json_.map(|v| serde_json::from_str(v.0.get()).unwrap()), - jsonb_: jsonb_.map(|v| serde_json::from_str(v.0.get()).unwrap()), - uuid_, - inet_, - macaddr_, - numeric_, - } - } - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct EverythingArray { - pub bool_: Vec, - pub boolean_: Vec, - pub char_: Vec, - pub smallint_: Vec, - pub int2_: Vec, - pub int_: Vec, - pub int4_: Vec, - pub bingint_: Vec, - pub int8_: Vec, - pub float4_: Vec, - pub real_: Vec, - pub float8_: Vec, - pub double_precision_: Vec, - pub text_: Vec, - pub varchar_: Vec, - pub bytea_: Vec>, - pub timestamp_: Vec, - pub timestamp_without_time_zone_: Vec, - pub timestamptz_: Vec, - pub timestamp_with_time_zone_: Vec, - pub date_: Vec, - pub time_: Vec, - pub json_: Vec, - pub jsonb_: Vec, - pub uuid_: Vec, - pub inet_: Vec, - pub macaddr_: Vec, - pub numeric_: Vec, - } - pub struct EverythingArrayBorrowed<'a> { - pub bool_: cornucopia_async::ArrayIterator<'a, bool>, - pub boolean_: cornucopia_async::ArrayIterator<'a, bool>, - pub char_: cornucopia_async::ArrayIterator<'a, i8>, - pub smallint_: cornucopia_async::ArrayIterator<'a, i16>, - pub int2_: cornucopia_async::ArrayIterator<'a, i16>, - pub int_: cornucopia_async::ArrayIterator<'a, i32>, - pub int4_: cornucopia_async::ArrayIterator<'a, i32>, - pub bingint_: cornucopia_async::ArrayIterator<'a, i64>, - pub int8_: cornucopia_async::ArrayIterator<'a, i64>, - pub float4_: cornucopia_async::ArrayIterator<'a, f32>, - pub real_: cornucopia_async::ArrayIterator<'a, f32>, - pub float8_: cornucopia_async::ArrayIterator<'a, f64>, - pub double_precision_: cornucopia_async::ArrayIterator<'a, f64>, - pub text_: cornucopia_async::ArrayIterator<'a, &'a str>, - pub varchar_: cornucopia_async::ArrayIterator<'a, &'a str>, - pub bytea_: cornucopia_async::ArrayIterator<'a, &'a [u8]>, - pub timestamp_: cornucopia_async::ArrayIterator<'a, time::PrimitiveDateTime>, - pub timestamp_without_time_zone_: - cornucopia_async::ArrayIterator<'a, time::PrimitiveDateTime>, - pub timestamptz_: cornucopia_async::ArrayIterator<'a, time::OffsetDateTime>, - pub timestamp_with_time_zone_: - cornucopia_async::ArrayIterator<'a, time::OffsetDateTime>, - pub date_: cornucopia_async::ArrayIterator<'a, time::Date>, - pub time_: cornucopia_async::ArrayIterator<'a, time::Time>, - pub json_: cornucopia_async::ArrayIterator< - 'a, - postgres_types::Json<&'a serde_json::value::RawValue>, - >, - pub jsonb_: cornucopia_async::ArrayIterator< - 'a, - postgres_types::Json<&'a serde_json::value::RawValue>, - >, - pub uuid_: cornucopia_async::ArrayIterator<'a, uuid::Uuid>, - pub inet_: cornucopia_async::ArrayIterator<'a, std::net::IpAddr>, - pub macaddr_: cornucopia_async::ArrayIterator<'a, eui48::MacAddress>, - pub numeric_: cornucopia_async::ArrayIterator<'a, rust_decimal::Decimal>, - } - impl<'a> From> for EverythingArray { - fn from( - EverythingArrayBorrowed { - bool_, - boolean_, - char_, - smallint_, - int2_, - int_, - int4_, - bingint_, - int8_, - float4_, - real_, - float8_, - double_precision_, - text_, - varchar_, - bytea_, - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_, - jsonb_, - uuid_, - inet_, - macaddr_, - numeric_, - }: EverythingArrayBorrowed<'a>, - ) -> Self { - Self { - bool_: bool_.map(|v| v).collect(), - boolean_: boolean_.map(|v| v).collect(), - char_: char_.map(|v| v).collect(), - smallint_: smallint_.map(|v| v).collect(), - int2_: int2_.map(|v| v).collect(), - int_: int_.map(|v| v).collect(), - int4_: int4_.map(|v| v).collect(), - bingint_: bingint_.map(|v| v).collect(), - int8_: int8_.map(|v| v).collect(), - float4_: float4_.map(|v| v).collect(), - real_: real_.map(|v| v).collect(), - float8_: float8_.map(|v| v).collect(), - double_precision_: double_precision_.map(|v| v).collect(), - text_: text_.map(|v| v.into()).collect(), - varchar_: varchar_.map(|v| v.into()).collect(), - bytea_: bytea_.map(|v| v.into()).collect(), - timestamp_: timestamp_.map(|v| v).collect(), - timestamp_without_time_zone_: timestamp_without_time_zone_.map(|v| v).collect(), - timestamptz_: timestamptz_.map(|v| v).collect(), - timestamp_with_time_zone_: timestamp_with_time_zone_.map(|v| v).collect(), - date_: date_.map(|v| v).collect(), - time_: time_.map(|v| v).collect(), - json_: json_ - .map(|v| serde_json::from_str(v.0.get()).unwrap()) - .collect(), - jsonb_: jsonb_ - .map(|v| serde_json::from_str(v.0.get()).unwrap()) - .collect(), - uuid_: uuid_.map(|v| v).collect(), - inet_: inet_.map(|v| v).collect(), - macaddr_: macaddr_.map(|v| v).collect(), - numeric_: numeric_.map(|v| v).collect(), - } - } - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct EverythingArrayNull { - pub bool_: Option>, - pub boolean_: Option>, - pub char_: Option>, - pub smallint_: Option>, - pub int2_: Option>, - pub int_: Option>, - pub int4_: Option>, - pub bingint_: Option>, - pub int8_: Option>, - pub float4_: Option>, - pub real_: Option>, - pub float8_: Option>, - pub double_precision_: Option>, - pub text_: Option>, - pub varchar_: Option>, - pub bytea_: Option>>, - pub timestamp_: Option>, - pub timestamp_without_time_zone_: Option>, - pub timestamptz_: Option>, - pub timestamp_with_time_zone_: Option>, - pub date_: Option>, - pub time_: Option>, - pub json_: Option>, - pub jsonb_: Option>, - pub uuid_: Option>, - pub inet_: Option>, - pub macaddr_: Option>, - pub numeric_: Option>, - } - pub struct EverythingArrayNullBorrowed<'a> { - pub bool_: Option>, - pub boolean_: Option>, - pub char_: Option>, - pub smallint_: Option>, - pub int2_: Option>, - pub int_: Option>, - pub int4_: Option>, - pub bingint_: Option>, - pub int8_: Option>, - pub float4_: Option>, - pub real_: Option>, - pub float8_: Option>, - pub double_precision_: Option>, - pub text_: Option>, - pub varchar_: Option>, - pub bytea_: Option>, - pub timestamp_: Option>, - pub timestamp_without_time_zone_: - Option>, - pub timestamptz_: Option>, - pub timestamp_with_time_zone_: - Option>, - pub date_: Option>, - pub time_: Option>, - pub json_: Option< - cornucopia_async::ArrayIterator< - 'a, - postgres_types::Json<&'a serde_json::value::RawValue>, - >, - >, - pub jsonb_: Option< - cornucopia_async::ArrayIterator< - 'a, - postgres_types::Json<&'a serde_json::value::RawValue>, - >, - >, - pub uuid_: Option>, - pub inet_: Option>, - pub macaddr_: Option>, - pub numeric_: Option>, - } - impl<'a> From> for EverythingArrayNull { - fn from( - EverythingArrayNullBorrowed { - bool_, - boolean_, - char_, - smallint_, - int2_, - int_, - int4_, - bingint_, - int8_, - float4_, - real_, - float8_, - double_precision_, - text_, - varchar_, - bytea_, - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_, - jsonb_, - uuid_, - inet_, - macaddr_, - numeric_, - }: EverythingArrayNullBorrowed<'a>, - ) -> Self { - Self { - bool_: bool_.map(|v| v.map(|v| v).collect()), - boolean_: boolean_.map(|v| v.map(|v| v).collect()), - char_: char_.map(|v| v.map(|v| v).collect()), - smallint_: smallint_.map(|v| v.map(|v| v).collect()), - int2_: int2_.map(|v| v.map(|v| v).collect()), - int_: int_.map(|v| v.map(|v| v).collect()), - int4_: int4_.map(|v| v.map(|v| v).collect()), - bingint_: bingint_.map(|v| v.map(|v| v).collect()), - int8_: int8_.map(|v| v.map(|v| v).collect()), - float4_: float4_.map(|v| v.map(|v| v).collect()), - real_: real_.map(|v| v.map(|v| v).collect()), - float8_: float8_.map(|v| v.map(|v| v).collect()), - double_precision_: double_precision_.map(|v| v.map(|v| v).collect()), - text_: text_.map(|v| v.map(|v| v.into()).collect()), - varchar_: varchar_.map(|v| v.map(|v| v.into()).collect()), - bytea_: bytea_.map(|v| v.map(|v| v.into()).collect()), - timestamp_: timestamp_.map(|v| v.map(|v| v).collect()), - timestamp_without_time_zone_: timestamp_without_time_zone_ - .map(|v| v.map(|v| v).collect()), - timestamptz_: timestamptz_.map(|v| v.map(|v| v).collect()), - timestamp_with_time_zone_: timestamp_with_time_zone_ - .map(|v| v.map(|v| v).collect()), - date_: date_.map(|v| v.map(|v| v).collect()), - time_: time_.map(|v| v.map(|v| v).collect()), - json_: json_.map(|v| { - v.map(|v| serde_json::from_str(v.0.get()).unwrap()) - .collect() - }), - jsonb_: jsonb_.map(|v| { - v.map(|v| serde_json::from_str(v.0.get()).unwrap()) - .collect() - }), - uuid_: uuid_.map(|v| v.map(|v| v).collect()), - inet_: inet_.map(|v| v.map(|v| v).collect()), - macaddr_: macaddr_.map(|v| v.map(|v| v).collect()), - numeric_: numeric_.map(|v| v.map(|v| v).collect()), - } - } - } - pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct EverythingQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::EverythingBorrowed, - mapper: fn(super::EverythingBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> EverythingQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::EverythingBorrowed) -> R, - ) -> EverythingQuery<'a, C, R, N> { - EverythingQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct EverythingNullQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::EverythingNullBorrowed, - mapper: fn(super::EverythingNullBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> EverythingNullQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::EverythingNullBorrowed) -> R, - ) -> EverythingNullQuery<'a, C, R, N> { - EverythingNullQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct EverythingArrayQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::EverythingArrayBorrowed, - mapper: fn(super::EverythingArrayBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> EverythingArrayQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::EverythingArrayBorrowed) -> R, - ) -> EverythingArrayQuery<'a, C, R, N> { - EverythingArrayQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct EverythingArrayNullQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::EverythingArrayNullBorrowed, - mapper: fn(super::EverythingArrayNullBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> EverythingArrayNullQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::EverythingArrayNullBorrowed) -> R, - ) -> EverythingArrayNullQuery<'a, C, R, N> { - EverythingArrayNullQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct PublicNightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn( - &postgres::Row, - ) - -> super::super::super::types::public::NightmareCompositeBorrowed, - mapper: fn(super::super::super::types::public::NightmareCompositeBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicNightmareCompositeQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::super::types::public::NightmareCompositeBorrowed) -> R, - ) -> PublicNightmareCompositeQuery<'a, C, R, N> { - PublicNightmareCompositeQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn select_everything() -> SelectEverythingStmt { - SelectEverythingStmt(cornucopia_sync::private::Stmt::new( - "SELECT - * -FROM - Everything", - )) - } - pub struct SelectEverythingStmt(cornucopia_sync::private::Stmt); - impl SelectEverythingStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> EverythingQuery<'a, C, super::Everything, 0> { - EverythingQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::EverythingBorrowed { - bool_: row.get(0), - boolean_: row.get(1), - char_: row.get(2), - smallint_: row.get(3), - int2_: row.get(4), - smallserial_: row.get(5), - serial2_: row.get(6), - int_: row.get(7), - int4_: row.get(8), - serial_: row.get(9), - serial4_: row.get(10), - bingint_: row.get(11), - int8_: row.get(12), - bigserial_: row.get(13), - serial8_: row.get(14), - float4_: row.get(15), - real_: row.get(16), - float8_: row.get(17), - double_precision_: row.get(18), - text_: row.get(19), - varchar_: row.get(20), - bytea_: row.get(21), - timestamp_: row.get(22), - timestamp_without_time_zone_: row.get(23), - timestamptz_: row.get(24), - timestamp_with_time_zone_: row.get(25), - date_: row.get(26), - time_: row.get(27), - json_: row.get(28), - jsonb_: row.get(29), - uuid_: row.get(30), - inet_: row.get(31), - macaddr_: row.get(32), - numeric_: row.get(33), - }, - mapper: |it| ::from(it), - } - } - } - pub fn select_everything_null() -> SelectEverythingNullStmt { - SelectEverythingNullStmt(cornucopia_sync::private::Stmt::new( - "SELECT - * -FROM - Everything", - )) - } - pub struct SelectEverythingNullStmt(cornucopia_sync::private::Stmt); - impl SelectEverythingNullStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> EverythingNullQuery<'a, C, super::EverythingNull, 0> { - EverythingNullQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::EverythingNullBorrowed { - bool_: row.get(0), - boolean_: row.get(1), - char_: row.get(2), - smallint_: row.get(3), - int2_: row.get(4), - smallserial_: row.get(5), - serial2_: row.get(6), - int_: row.get(7), - int4_: row.get(8), - serial_: row.get(9), - serial4_: row.get(10), - bingint_: row.get(11), - int8_: row.get(12), - bigserial_: row.get(13), - serial8_: row.get(14), - float4_: row.get(15), - real_: row.get(16), - float8_: row.get(17), - double_precision_: row.get(18), - text_: row.get(19), - varchar_: row.get(20), - bytea_: row.get(21), - timestamp_: row.get(22), - timestamp_without_time_zone_: row.get(23), - timestamptz_: row.get(24), - timestamp_with_time_zone_: row.get(25), - date_: row.get(26), - time_: row.get(27), - json_: row.get(28), - jsonb_: row.get(29), - uuid_: row.get(30), - inet_: row.get(31), - macaddr_: row.get(32), - numeric_: row.get(33), - }, - mapper: |it| ::from(it), - } - } - } - pub fn insert_everything() -> InsertEverythingStmt { - InsertEverythingStmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO Everything (bool_, boolean_, char_, smallint_, int2_, smallserial_, serial2_, int_, int4_, serial_, serial4_, bingint_, int8_, bigserial_, serial8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)")) - } - pub struct InsertEverythingStmt(cornucopia_sync::private::Stmt); - impl InsertEverythingStmt { - pub fn bind< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::StringSql, - T3: cornucopia_sync::BytesSql, - T4: cornucopia_sync::JsonSql, - T5: cornucopia_sync::JsonSql, - >( - &'a mut self, - client: &'a mut C, - bool_: &'a bool, - boolean_: &'a bool, - char_: &'a i8, - smallint_: &'a i16, - int2_: &'a i16, - smallserial_: &'a i16, - serial2_: &'a i16, - int_: &'a i32, - int4_: &'a i32, - serial_: &'a i32, - serial4_: &'a i32, - bingint_: &'a i64, - int8_: &'a i64, - bigserial_: &'a i64, - serial8_: &'a i64, - float4_: &'a f32, - real_: &'a f32, - float8_: &'a f64, - double_precision_: &'a f64, - text_: &'a T1, - varchar_: &'a T2, - bytea_: &'a T3, - timestamp_: &'a time::PrimitiveDateTime, - timestamp_without_time_zone_: &'a time::PrimitiveDateTime, - timestamptz_: &'a time::OffsetDateTime, - timestamp_with_time_zone_: &'a time::OffsetDateTime, - date_: &'a time::Date, - time_: &'a time::Time, - json_: &'a T4, - jsonb_: &'a T5, - uuid_: &'a uuid::Uuid, - inet_: &'a std::net::IpAddr, - macaddr_: &'a eui48::MacAddress, - numeric_: &'a rust_decimal::Decimal, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute( - stmt, - &[ - bool_, - boolean_, - char_, - smallint_, - int2_, - smallserial_, - serial2_, - int_, - int4_, - serial_, - serial4_, - bingint_, - int8_, - bigserial_, - serial8_, - float4_, - real_, - float8_, - double_precision_, - text_, - varchar_, - bytea_, - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_, - jsonb_, - uuid_, - inet_, - macaddr_, - numeric_, - ], - ) - } - } - impl< - 'a, - C: GenericClient, - T1: cornucopia_sync::StringSql, - T2: cornucopia_sync::StringSql, - T3: cornucopia_sync::BytesSql, - T4: cornucopia_sync::JsonSql, - T5: cornucopia_sync::JsonSql, - > - cornucopia_sync::Params< - 'a, - super::EverythingParams, - Result, - C, - > for InsertEverythingStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::EverythingParams, - ) -> Result { - self.bind( - client, - ¶ms.bool_, - ¶ms.boolean_, - ¶ms.char_, - ¶ms.smallint_, - ¶ms.int2_, - ¶ms.smallserial_, - ¶ms.serial2_, - ¶ms.int_, - ¶ms.int4_, - ¶ms.serial_, - ¶ms.serial4_, - ¶ms.bingint_, - ¶ms.int8_, - ¶ms.bigserial_, - ¶ms.serial8_, - ¶ms.float4_, - ¶ms.real_, - ¶ms.float8_, - ¶ms.double_precision_, - ¶ms.text_, - ¶ms.varchar_, - ¶ms.bytea_, - ¶ms.timestamp_, - ¶ms.timestamp_without_time_zone_, - ¶ms.timestamptz_, - ¶ms.timestamp_with_time_zone_, - ¶ms.date_, - ¶ms.time_, - ¶ms.json_, - ¶ms.jsonb_, - ¶ms.uuid_, - ¶ms.inet_, - ¶ms.macaddr_, - ¶ms.numeric_, - ) - } - } - pub fn select_everything_array() -> SelectEverythingArrayStmt { - SelectEverythingArrayStmt(cornucopia_sync::private::Stmt::new( - "SELECT - * -FROM - EverythingArray", - )) - } - pub struct SelectEverythingArrayStmt(cornucopia_sync::private::Stmt); - impl SelectEverythingArrayStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> EverythingArrayQuery<'a, C, super::EverythingArray, 0> { - EverythingArrayQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::EverythingArrayBorrowed { - bool_: row.get(0), - boolean_: row.get(1), - char_: row.get(2), - smallint_: row.get(3), - int2_: row.get(4), - int_: row.get(5), - int4_: row.get(6), - bingint_: row.get(7), - int8_: row.get(8), - float4_: row.get(9), - real_: row.get(10), - float8_: row.get(11), - double_precision_: row.get(12), - text_: row.get(13), - varchar_: row.get(14), - bytea_: row.get(15), - timestamp_: row.get(16), - timestamp_without_time_zone_: row.get(17), - timestamptz_: row.get(18), - timestamp_with_time_zone_: row.get(19), - date_: row.get(20), - time_: row.get(21), - json_: row.get(22), - jsonb_: row.get(23), - uuid_: row.get(24), - inet_: row.get(25), - macaddr_: row.get(26), - numeric_: row.get(27), - }, - mapper: |it| ::from(it), - } - } - } - pub fn select_everything_array_null() -> SelectEverythingArrayNullStmt { - SelectEverythingArrayNullStmt(cornucopia_sync::private::Stmt::new( - "SELECT - * -FROM - EverythingArray", - )) - } - pub struct SelectEverythingArrayNullStmt(cornucopia_sync::private::Stmt); - impl SelectEverythingArrayNullStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> EverythingArrayNullQuery<'a, C, super::EverythingArrayNull, 0> - { - EverythingArrayNullQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::EverythingArrayNullBorrowed { - bool_: row.get(0), - boolean_: row.get(1), - char_: row.get(2), - smallint_: row.get(3), - int2_: row.get(4), - int_: row.get(5), - int4_: row.get(6), - bingint_: row.get(7), - int8_: row.get(8), - float4_: row.get(9), - real_: row.get(10), - float8_: row.get(11), - double_precision_: row.get(12), - text_: row.get(13), - varchar_: row.get(14), - bytea_: row.get(15), - timestamp_: row.get(16), - timestamp_without_time_zone_: row.get(17), - timestamptz_: row.get(18), - timestamp_with_time_zone_: row.get(19), - date_: row.get(20), - time_: row.get(21), - json_: row.get(22), - jsonb_: row.get(23), - uuid_: row.get(24), - inet_: row.get(25), - macaddr_: row.get(26), - numeric_: row.get(27), - }, - mapper: |it| ::from(it), - } - } - } - pub fn insert_everything_array() -> InsertEverythingArrayStmt { - InsertEverythingArrayStmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO EverythingArray (bool_, boolean_, char_, smallint_, int2_, int_, int4_, bingint_, int8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)")) - } - pub struct InsertEverythingArrayStmt(cornucopia_sync::private::Stmt); - impl InsertEverythingArrayStmt { - pub fn bind< - 'a, - C: GenericClient, - T1: cornucopia_sync::ArraySql, - T2: cornucopia_sync::ArraySql, - T3: cornucopia_sync::ArraySql, - T4: cornucopia_sync::ArraySql, - T5: cornucopia_sync::ArraySql, - T6: cornucopia_sync::ArraySql, - T7: cornucopia_sync::ArraySql, - T8: cornucopia_sync::ArraySql, - T9: cornucopia_sync::ArraySql, - T10: cornucopia_sync::ArraySql, - T11: cornucopia_sync::ArraySql, - T12: cornucopia_sync::ArraySql, - T13: cornucopia_sync::ArraySql, - T14: cornucopia_sync::StringSql, - T15: cornucopia_sync::ArraySql, - T16: cornucopia_sync::StringSql, - T17: cornucopia_sync::ArraySql, - T18: cornucopia_sync::BytesSql, - T19: cornucopia_sync::ArraySql, - T20: cornucopia_sync::ArraySql, - T21: cornucopia_sync::ArraySql, - T22: cornucopia_sync::ArraySql, - T23: cornucopia_sync::ArraySql, - T24: cornucopia_sync::ArraySql, - T25: cornucopia_sync::ArraySql, - T26: cornucopia_sync::JsonSql, - T27: cornucopia_sync::ArraySql, - T28: cornucopia_sync::JsonSql, - T29: cornucopia_sync::ArraySql, - T30: cornucopia_sync::ArraySql, - T31: cornucopia_sync::ArraySql, - T32: cornucopia_sync::ArraySql, - T33: cornucopia_sync::ArraySql, - >( - &'a mut self, - client: &'a mut C, - bool_: &'a T1, - boolean_: &'a T2, - char_: &'a T3, - smallint_: &'a T4, - int2_: &'a T5, - int_: &'a T6, - int4_: &'a T7, - bingint_: &'a T8, - int8_: &'a T9, - float4_: &'a T10, - real_: &'a T11, - float8_: &'a T12, - double_precision_: &'a T13, - text_: &'a T15, - varchar_: &'a T17, - bytea_: &'a T19, - timestamp_: &'a T20, - timestamp_without_time_zone_: &'a T21, - timestamptz_: &'a T22, - timestamp_with_time_zone_: &'a T23, - date_: &'a T24, - time_: &'a T25, - json_: &'a T27, - jsonb_: &'a T29, - uuid_: &'a T30, - inet_: &'a T31, - macaddr_: &'a T32, - numeric_: &'a T33, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute( - stmt, - &[ - bool_, - boolean_, - char_, - smallint_, - int2_, - int_, - int4_, - bingint_, - int8_, - float4_, - real_, - float8_, - double_precision_, - text_, - varchar_, - bytea_, - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_, - jsonb_, - uuid_, - inet_, - macaddr_, - numeric_, - ], - ) - } - } - impl< - 'a, - C: GenericClient, - T1: cornucopia_sync::ArraySql, - T2: cornucopia_sync::ArraySql, - T3: cornucopia_sync::ArraySql, - T4: cornucopia_sync::ArraySql, - T5: cornucopia_sync::ArraySql, - T6: cornucopia_sync::ArraySql, - T7: cornucopia_sync::ArraySql, - T8: cornucopia_sync::ArraySql, - T9: cornucopia_sync::ArraySql, - T10: cornucopia_sync::ArraySql, - T11: cornucopia_sync::ArraySql, - T12: cornucopia_sync::ArraySql, - T13: cornucopia_sync::ArraySql, - T14: cornucopia_sync::StringSql, - T15: cornucopia_sync::ArraySql, - T16: cornucopia_sync::StringSql, - T17: cornucopia_sync::ArraySql, - T18: cornucopia_sync::BytesSql, - T19: cornucopia_sync::ArraySql, - T20: cornucopia_sync::ArraySql, - T21: cornucopia_sync::ArraySql, - T22: cornucopia_sync::ArraySql, - T23: cornucopia_sync::ArraySql, - T24: cornucopia_sync::ArraySql, - T25: cornucopia_sync::ArraySql, - T26: cornucopia_sync::JsonSql, - T27: cornucopia_sync::ArraySql, - T28: cornucopia_sync::JsonSql, - T29: cornucopia_sync::ArraySql, - T30: cornucopia_sync::ArraySql, - T31: cornucopia_sync::ArraySql, - T32: cornucopia_sync::ArraySql, - T33: cornucopia_sync::ArraySql, - > - cornucopia_sync::Params< - 'a, - super::EverythingArrayParams< - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30, - T31, - T32, - T33, - >, - Result, - C, - > for InsertEverythingArrayStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::EverythingArrayParams< - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30, - T31, - T32, - T33, - >, - ) -> Result { - self.bind( - client, - ¶ms.bool_, - ¶ms.boolean_, - ¶ms.char_, - ¶ms.smallint_, - ¶ms.int2_, - ¶ms.int_, - ¶ms.int4_, - ¶ms.bingint_, - ¶ms.int8_, - ¶ms.float4_, - ¶ms.real_, - ¶ms.float8_, - ¶ms.double_precision_, - ¶ms.text_, - ¶ms.varchar_, - ¶ms.bytea_, - ¶ms.timestamp_, - ¶ms.timestamp_without_time_zone_, - ¶ms.timestamptz_, - ¶ms.timestamp_with_time_zone_, - ¶ms.date_, - ¶ms.time_, - ¶ms.json_, - ¶ms.jsonb_, - ¶ms.uuid_, - ¶ms.inet_, - ¶ms.macaddr_, - ¶ms.numeric_, - ) - } - } - pub fn select_nightmare() -> SelectNightmareStmt { - SelectNightmareStmt(cornucopia_sync::private::Stmt::new( - "SELECT - * -FROM - nightmare", - )) - } - pub struct SelectNightmareStmt(cornucopia_sync::private::Stmt); - impl SelectNightmareStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> PublicNightmareCompositeQuery< - 'a, - C, - super::super::super::types::public::NightmareComposite, - 0, - > { - PublicNightmareCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn insert_nightmare() -> InsertNightmareStmt { - InsertNightmareStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO nightmare (composite) - VALUES ($1)", - )) - } - pub struct InsertNightmareStmt(cornucopia_sync::private::Stmt); - impl InsertNightmareStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - composite: &'a super::super::super::types::public::NightmareCompositeParams<'a>, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[composite]) - } - } - } - pub mod async_ { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct EverythingQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::EverythingBorrowed, - mapper: fn(super::EverythingBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> EverythingQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::EverythingBorrowed) -> R, - ) -> EverythingQuery<'a, C, R, N> { - EverythingQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct EverythingNullQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::EverythingNullBorrowed, - mapper: fn(super::EverythingNullBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> EverythingNullQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::EverythingNullBorrowed) -> R, - ) -> EverythingNullQuery<'a, C, R, N> { - EverythingNullQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct EverythingArrayQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::EverythingArrayBorrowed, - mapper: fn(super::EverythingArrayBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> EverythingArrayQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::EverythingArrayBorrowed) -> R, - ) -> EverythingArrayQuery<'a, C, R, N> { - EverythingArrayQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct EverythingArrayNullQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::EverythingArrayNullBorrowed, - mapper: fn(super::EverythingArrayNullBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> EverythingArrayNullQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::EverythingArrayNullBorrowed) -> R, - ) -> EverythingArrayNullQuery<'a, C, R, N> { - EverythingArrayNullQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct PublicNightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn( - &tokio_postgres::Row, - ) - -> super::super::super::types::public::NightmareCompositeBorrowed, - mapper: fn(super::super::super::types::public::NightmareCompositeBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicNightmareCompositeQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::super::types::public::NightmareCompositeBorrowed) -> R, - ) -> PublicNightmareCompositeQuery<'a, C, R, N> { - PublicNightmareCompositeQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn select_everything() -> SelectEverythingStmt { - SelectEverythingStmt(cornucopia_async::private::Stmt::new( - "SELECT - * -FROM - Everything", - )) - } - pub struct SelectEverythingStmt(cornucopia_async::private::Stmt); - impl SelectEverythingStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> EverythingQuery<'a, C, super::Everything, 0> { - EverythingQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::EverythingBorrowed { - bool_: row.get(0), - boolean_: row.get(1), - char_: row.get(2), - smallint_: row.get(3), - int2_: row.get(4), - smallserial_: row.get(5), - serial2_: row.get(6), - int_: row.get(7), - int4_: row.get(8), - serial_: row.get(9), - serial4_: row.get(10), - bingint_: row.get(11), - int8_: row.get(12), - bigserial_: row.get(13), - serial8_: row.get(14), - float4_: row.get(15), - real_: row.get(16), - float8_: row.get(17), - double_precision_: row.get(18), - text_: row.get(19), - varchar_: row.get(20), - bytea_: row.get(21), - timestamp_: row.get(22), - timestamp_without_time_zone_: row.get(23), - timestamptz_: row.get(24), - timestamp_with_time_zone_: row.get(25), - date_: row.get(26), - time_: row.get(27), - json_: row.get(28), - jsonb_: row.get(29), - uuid_: row.get(30), - inet_: row.get(31), - macaddr_: row.get(32), - numeric_: row.get(33), - }, - mapper: |it| ::from(it), - } - } - } - pub fn select_everything_null() -> SelectEverythingNullStmt { - SelectEverythingNullStmt(cornucopia_async::private::Stmt::new( - "SELECT - * -FROM - Everything", - )) - } - pub struct SelectEverythingNullStmt(cornucopia_async::private::Stmt); - impl SelectEverythingNullStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> EverythingNullQuery<'a, C, super::EverythingNull, 0> { - EverythingNullQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::EverythingNullBorrowed { - bool_: row.get(0), - boolean_: row.get(1), - char_: row.get(2), - smallint_: row.get(3), - int2_: row.get(4), - smallserial_: row.get(5), - serial2_: row.get(6), - int_: row.get(7), - int4_: row.get(8), - serial_: row.get(9), - serial4_: row.get(10), - bingint_: row.get(11), - int8_: row.get(12), - bigserial_: row.get(13), - serial8_: row.get(14), - float4_: row.get(15), - real_: row.get(16), - float8_: row.get(17), - double_precision_: row.get(18), - text_: row.get(19), - varchar_: row.get(20), - bytea_: row.get(21), - timestamp_: row.get(22), - timestamp_without_time_zone_: row.get(23), - timestamptz_: row.get(24), - timestamp_with_time_zone_: row.get(25), - date_: row.get(26), - time_: row.get(27), - json_: row.get(28), - jsonb_: row.get(29), - uuid_: row.get(30), - inet_: row.get(31), - macaddr_: row.get(32), - numeric_: row.get(33), - }, - mapper: |it| ::from(it), - } - } - } - pub fn insert_everything() -> InsertEverythingStmt { - InsertEverythingStmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO Everything (bool_, boolean_, char_, smallint_, int2_, smallserial_, serial2_, int_, int4_, serial_, serial4_, bingint_, int8_, bigserial_, serial8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)")) - } - pub struct InsertEverythingStmt(cornucopia_async::private::Stmt); - impl InsertEverythingStmt { - pub async fn bind< - 'a, - C: GenericClient, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - T3: cornucopia_async::BytesSql, - T4: cornucopia_async::JsonSql, - T5: cornucopia_async::JsonSql, - >( - &'a mut self, - client: &'a C, - bool_: &'a bool, - boolean_: &'a bool, - char_: &'a i8, - smallint_: &'a i16, - int2_: &'a i16, - smallserial_: &'a i16, - serial2_: &'a i16, - int_: &'a i32, - int4_: &'a i32, - serial_: &'a i32, - serial4_: &'a i32, - bingint_: &'a i64, - int8_: &'a i64, - bigserial_: &'a i64, - serial8_: &'a i64, - float4_: &'a f32, - real_: &'a f32, - float8_: &'a f64, - double_precision_: &'a f64, - text_: &'a T1, - varchar_: &'a T2, - bytea_: &'a T3, - timestamp_: &'a time::PrimitiveDateTime, - timestamp_without_time_zone_: &'a time::PrimitiveDateTime, - timestamptz_: &'a time::OffsetDateTime, - timestamp_with_time_zone_: &'a time::OffsetDateTime, - date_: &'a time::Date, - time_: &'a time::Time, - json_: &'a T4, - jsonb_: &'a T5, - uuid_: &'a uuid::Uuid, - inet_: &'a std::net::IpAddr, - macaddr_: &'a eui48::MacAddress, - numeric_: &'a rust_decimal::Decimal, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client - .execute( - stmt, - &[ - bool_, - boolean_, - char_, - smallint_, - int2_, - smallserial_, - serial2_, - int_, - int4_, - serial_, - serial4_, - bingint_, - int8_, - bigserial_, - serial8_, - float4_, - real_, - float8_, - double_precision_, - text_, - varchar_, - bytea_, - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_, - jsonb_, - uuid_, - inet_, - macaddr_, - numeric_, - ], - ) - .await - } - } - impl< - 'a, - C: GenericClient + Send + Sync, - T1: cornucopia_async::StringSql, - T2: cornucopia_async::StringSql, - T3: cornucopia_async::BytesSql, - T4: cornucopia_async::JsonSql, - T5: cornucopia_async::JsonSql, - > - cornucopia_async::Params< - 'a, - super::EverythingParams, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for InsertEverythingStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::EverythingParams, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind( - client, - ¶ms.bool_, - ¶ms.boolean_, - ¶ms.char_, - ¶ms.smallint_, - ¶ms.int2_, - ¶ms.smallserial_, - ¶ms.serial2_, - ¶ms.int_, - ¶ms.int4_, - ¶ms.serial_, - ¶ms.serial4_, - ¶ms.bingint_, - ¶ms.int8_, - ¶ms.bigserial_, - ¶ms.serial8_, - ¶ms.float4_, - ¶ms.real_, - ¶ms.float8_, - ¶ms.double_precision_, - ¶ms.text_, - ¶ms.varchar_, - ¶ms.bytea_, - ¶ms.timestamp_, - ¶ms.timestamp_without_time_zone_, - ¶ms.timestamptz_, - ¶ms.timestamp_with_time_zone_, - ¶ms.date_, - ¶ms.time_, - ¶ms.json_, - ¶ms.jsonb_, - ¶ms.uuid_, - ¶ms.inet_, - ¶ms.macaddr_, - ¶ms.numeric_, - )) - } - } - pub fn select_everything_array() -> SelectEverythingArrayStmt { - SelectEverythingArrayStmt(cornucopia_async::private::Stmt::new( - "SELECT - * -FROM - EverythingArray", - )) - } - pub struct SelectEverythingArrayStmt(cornucopia_async::private::Stmt); - impl SelectEverythingArrayStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> EverythingArrayQuery<'a, C, super::EverythingArray, 0> { - EverythingArrayQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::EverythingArrayBorrowed { - bool_: row.get(0), - boolean_: row.get(1), - char_: row.get(2), - smallint_: row.get(3), - int2_: row.get(4), - int_: row.get(5), - int4_: row.get(6), - bingint_: row.get(7), - int8_: row.get(8), - float4_: row.get(9), - real_: row.get(10), - float8_: row.get(11), - double_precision_: row.get(12), - text_: row.get(13), - varchar_: row.get(14), - bytea_: row.get(15), - timestamp_: row.get(16), - timestamp_without_time_zone_: row.get(17), - timestamptz_: row.get(18), - timestamp_with_time_zone_: row.get(19), - date_: row.get(20), - time_: row.get(21), - json_: row.get(22), - jsonb_: row.get(23), - uuid_: row.get(24), - inet_: row.get(25), - macaddr_: row.get(26), - numeric_: row.get(27), - }, - mapper: |it| ::from(it), - } - } - } - pub fn select_everything_array_null() -> SelectEverythingArrayNullStmt { - SelectEverythingArrayNullStmt(cornucopia_async::private::Stmt::new( - "SELECT - * -FROM - EverythingArray", - )) - } - pub struct SelectEverythingArrayNullStmt(cornucopia_async::private::Stmt); - impl SelectEverythingArrayNullStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> EverythingArrayNullQuery<'a, C, super::EverythingArrayNull, 0> - { - EverythingArrayNullQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::EverythingArrayNullBorrowed { - bool_: row.get(0), - boolean_: row.get(1), - char_: row.get(2), - smallint_: row.get(3), - int2_: row.get(4), - int_: row.get(5), - int4_: row.get(6), - bingint_: row.get(7), - int8_: row.get(8), - float4_: row.get(9), - real_: row.get(10), - float8_: row.get(11), - double_precision_: row.get(12), - text_: row.get(13), - varchar_: row.get(14), - bytea_: row.get(15), - timestamp_: row.get(16), - timestamp_without_time_zone_: row.get(17), - timestamptz_: row.get(18), - timestamp_with_time_zone_: row.get(19), - date_: row.get(20), - time_: row.get(21), - json_: row.get(22), - jsonb_: row.get(23), - uuid_: row.get(24), - inet_: row.get(25), - macaddr_: row.get(26), - numeric_: row.get(27), - }, - mapper: |it| ::from(it), - } - } - } - pub fn insert_everything_array() -> InsertEverythingArrayStmt { - InsertEverythingArrayStmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO EverythingArray (bool_, boolean_, char_, smallint_, int2_, int_, int4_, bingint_, int8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)")) - } - pub struct InsertEverythingArrayStmt(cornucopia_async::private::Stmt); - impl InsertEverythingArrayStmt { - pub async fn bind< - 'a, - C: GenericClient, - T1: cornucopia_async::ArraySql, - T2: cornucopia_async::ArraySql, - T3: cornucopia_async::ArraySql, - T4: cornucopia_async::ArraySql, - T5: cornucopia_async::ArraySql, - T6: cornucopia_async::ArraySql, - T7: cornucopia_async::ArraySql, - T8: cornucopia_async::ArraySql, - T9: cornucopia_async::ArraySql, - T10: cornucopia_async::ArraySql, - T11: cornucopia_async::ArraySql, - T12: cornucopia_async::ArraySql, - T13: cornucopia_async::ArraySql, - T14: cornucopia_async::StringSql, - T15: cornucopia_async::ArraySql, - T16: cornucopia_async::StringSql, - T17: cornucopia_async::ArraySql, - T18: cornucopia_async::BytesSql, - T19: cornucopia_async::ArraySql, - T20: cornucopia_async::ArraySql, - T21: cornucopia_async::ArraySql, - T22: cornucopia_async::ArraySql, - T23: cornucopia_async::ArraySql, - T24: cornucopia_async::ArraySql, - T25: cornucopia_async::ArraySql, - T26: cornucopia_async::JsonSql, - T27: cornucopia_async::ArraySql, - T28: cornucopia_async::JsonSql, - T29: cornucopia_async::ArraySql, - T30: cornucopia_async::ArraySql, - T31: cornucopia_async::ArraySql, - T32: cornucopia_async::ArraySql, - T33: cornucopia_async::ArraySql, - >( - &'a mut self, - client: &'a C, - bool_: &'a T1, - boolean_: &'a T2, - char_: &'a T3, - smallint_: &'a T4, - int2_: &'a T5, - int_: &'a T6, - int4_: &'a T7, - bingint_: &'a T8, - int8_: &'a T9, - float4_: &'a T10, - real_: &'a T11, - float8_: &'a T12, - double_precision_: &'a T13, - text_: &'a T15, - varchar_: &'a T17, - bytea_: &'a T19, - timestamp_: &'a T20, - timestamp_without_time_zone_: &'a T21, - timestamptz_: &'a T22, - timestamp_with_time_zone_: &'a T23, - date_: &'a T24, - time_: &'a T25, - json_: &'a T27, - jsonb_: &'a T29, - uuid_: &'a T30, - inet_: &'a T31, - macaddr_: &'a T32, - numeric_: &'a T33, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client - .execute( - stmt, - &[ - bool_, - boolean_, - char_, - smallint_, - int2_, - int_, - int4_, - bingint_, - int8_, - float4_, - real_, - float8_, - double_precision_, - text_, - varchar_, - bytea_, - timestamp_, - timestamp_without_time_zone_, - timestamptz_, - timestamp_with_time_zone_, - date_, - time_, - json_, - jsonb_, - uuid_, - inet_, - macaddr_, - numeric_, - ], - ) - .await - } - } - impl< - 'a, - C: GenericClient + Send + Sync, - T1: cornucopia_async::ArraySql, - T2: cornucopia_async::ArraySql, - T3: cornucopia_async::ArraySql, - T4: cornucopia_async::ArraySql, - T5: cornucopia_async::ArraySql, - T6: cornucopia_async::ArraySql, - T7: cornucopia_async::ArraySql, - T8: cornucopia_async::ArraySql, - T9: cornucopia_async::ArraySql, - T10: cornucopia_async::ArraySql, - T11: cornucopia_async::ArraySql, - T12: cornucopia_async::ArraySql, - T13: cornucopia_async::ArraySql, - T14: cornucopia_async::StringSql, - T15: cornucopia_async::ArraySql, - T16: cornucopia_async::StringSql, - T17: cornucopia_async::ArraySql, - T18: cornucopia_async::BytesSql, - T19: cornucopia_async::ArraySql, - T20: cornucopia_async::ArraySql, - T21: cornucopia_async::ArraySql, - T22: cornucopia_async::ArraySql, - T23: cornucopia_async::ArraySql, - T24: cornucopia_async::ArraySql, - T25: cornucopia_async::ArraySql, - T26: cornucopia_async::JsonSql, - T27: cornucopia_async::ArraySql, - T28: cornucopia_async::JsonSql, - T29: cornucopia_async::ArraySql, - T30: cornucopia_async::ArraySql, - T31: cornucopia_async::ArraySql, - T32: cornucopia_async::ArraySql, - T33: cornucopia_async::ArraySql, - > - cornucopia_async::Params< - 'a, - super::EverythingArrayParams< - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30, - T31, - T32, - T33, - >, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for InsertEverythingArrayStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::EverythingArrayParams< - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22, - T23, - T24, - T25, - T26, - T27, - T28, - T29, - T30, - T31, - T32, - T33, - >, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind( - client, - ¶ms.bool_, - ¶ms.boolean_, - ¶ms.char_, - ¶ms.smallint_, - ¶ms.int2_, - ¶ms.int_, - ¶ms.int4_, - ¶ms.bingint_, - ¶ms.int8_, - ¶ms.float4_, - ¶ms.real_, - ¶ms.float8_, - ¶ms.double_precision_, - ¶ms.text_, - ¶ms.varchar_, - ¶ms.bytea_, - ¶ms.timestamp_, - ¶ms.timestamp_without_time_zone_, - ¶ms.timestamptz_, - ¶ms.timestamp_with_time_zone_, - ¶ms.date_, - ¶ms.time_, - ¶ms.json_, - ¶ms.jsonb_, - ¶ms.uuid_, - ¶ms.inet_, - ¶ms.macaddr_, - ¶ms.numeric_, - )) - } - } - pub fn select_nightmare() -> SelectNightmareStmt { - SelectNightmareStmt(cornucopia_async::private::Stmt::new( - "SELECT - * -FROM - nightmare", - )) - } - pub struct SelectNightmareStmt(cornucopia_async::private::Stmt); - impl SelectNightmareStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> PublicNightmareCompositeQuery< - 'a, - C, - super::super::super::types::public::NightmareComposite, - 0, - > { - PublicNightmareCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn insert_nightmare() -> InsertNightmareStmt { - InsertNightmareStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO nightmare (composite) - VALUES ($1)", - )) - } - pub struct InsertNightmareStmt(cornucopia_async::private::Stmt); - impl InsertNightmareStmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - composite: &'a super::super::super::types::public::NightmareCompositeParams<'a>, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[composite]).await - } - } - } - } - pub mod syntax { - #[derive(Debug)] - pub struct ImplicitCompactParams { - pub name: Option, - pub price: Option, - } - #[derive(Debug)] - pub struct ImplicitSpacedParams { - pub name: Option, - pub price: Option, - } - #[derive(Debug)] - pub struct Params { - pub name: T1, - pub price: f64, - } - #[derive(Debug)] - pub struct ParamsSpace { - pub name: T1, - pub price: f64, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySqlParams { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql1Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql2Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql3Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql4Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql6Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql7Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql8Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql9Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(Clone, Copy, Debug)] - pub struct TrickySql10Params { - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq, Copy)] - pub struct Row { - pub id: i32, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq, Copy)] - pub struct RowSpace { - pub id: i32, - } - #[derive(serde::Serialize, Debug, Clone, PartialEq)] - pub struct Typeof { - pub trick_y: String, - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - pub struct TypeofBorrowed<'a> { - pub trick_y: &'a str, - pub r#async: super::super::types::public::SyntaxComposite, - pub r#enum: super::super::types::public::SyntaxEnum, - } - impl<'a> From> for Typeof { - fn from( - TypeofBorrowed { - trick_y, - r#async, - r#enum, - }: TypeofBorrowed<'a>, - ) -> Self { - Self { - trick_y: trick_y.into(), - r#async, - r#enum, - } - } - } - pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; - pub struct PublicCloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn( - &postgres::Row, - ) - -> super::super::super::types::public::CloneCompositeBorrowed, - mapper: fn(super::super::super::types::public::CloneCompositeBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicCloneCompositeQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::super::types::public::CloneCompositeBorrowed) -> R, - ) -> PublicCloneCompositeQuery<'a, C, R, N> { - PublicCloneCompositeQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct Optioni32Query<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> Option, - mapper: fn(Option) -> T, - } - impl<'a, C, T: 'a, const N: usize> Optioni32Query<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(Option) -> R) -> Optioni32Query<'a, C, R, N> { - Optioni32Query { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct RowQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::Row, - mapper: fn(super::Row) -> T, - } - impl<'a, C, T: 'a, const N: usize> RowQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(super::Row) -> R) -> RowQuery<'a, C, R, N> { - RowQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct RowSpaceQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::RowSpace, - mapper: fn(super::RowSpace) -> T, - } - impl<'a, C, T: 'a, const N: usize> RowSpaceQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::RowSpace) -> R, - ) -> RowSpaceQuery<'a, C, R, N> { - RowSpaceQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub struct TypeofQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a mut C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, - extractor: fn(&postgres::Row) -> super::TypeofBorrowed, - mapper: fn(super::TypeofBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> TypeofQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::TypeofBorrowed) -> R, - ) -> TypeofQuery<'a, C, R, N> { - TypeofQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub fn all(self) -> Result, postgres::Error> { - self.iter()?.collect() - } - pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub fn iter( - self, - ) -> Result> + 'a, postgres::Error> - { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? - .iterator() - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) - } - } - pub fn select_compact() -> SelectCompactStmt { - SelectCompactStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM clone")) - } - pub struct SelectCompactStmt(cornucopia_sync::private::Stmt); - impl SelectCompactStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> PublicCloneCompositeQuery< - 'a, - C, - super::super::super::types::public::CloneComposite, - 0, - > { - PublicCloneCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn select_spaced() -> SelectSpacedStmt { - SelectSpacedStmt(cornucopia_sync::private::Stmt::new( - " SELECT * FROM clone ", - )) - } - pub struct SelectSpacedStmt(cornucopia_sync::private::Stmt); - impl SelectSpacedStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> PublicCloneCompositeQuery< - 'a, - C, - super::super::super::types::public::CloneComposite, - 0, - > { - PublicCloneCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn implicit_compact() -> ImplicitCompactStmt { - ImplicitCompactStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct ImplicitCompactStmt(cornucopia_sync::private::Stmt); - impl ImplicitCompactStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - name: &'a Option, - price: &'a Option, - ) -> Optioni32Query<'a, C, Option, 2> { - Optioni32Query { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it, - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_sync::StringSql> - cornucopia_sync::Params< - 'a, - super::ImplicitCompactParams, - Optioni32Query<'a, C, Option, 2>, - C, - > for ImplicitCompactStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::ImplicitCompactParams, - ) -> Optioni32Query<'a, C, Option, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn implicit_spaced() -> ImplicitSpacedStmt { - ImplicitSpacedStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct ImplicitSpacedStmt(cornucopia_sync::private::Stmt); - impl ImplicitSpacedStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - name: &'a Option, - price: &'a Option, - ) -> Optioni32Query<'a, C, Option, 2> { - Optioni32Query { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it, - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_sync::StringSql> - cornucopia_sync::Params< - 'a, - super::ImplicitSpacedParams, - Optioni32Query<'a, C, Option, 2>, - C, - > for ImplicitSpacedStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::ImplicitSpacedParams, - ) -> Optioni32Query<'a, C, Option, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn named_compact() -> NamedCompactStmt { - NamedCompactStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct NamedCompactStmt(cornucopia_sync::private::Stmt); - impl NamedCompactStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - name: &'a T1, - price: &'a f64, - ) -> RowQuery<'a, C, super::Row, 2> { - RowQuery { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| super::Row { id: row.get(0) }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_sync::StringSql> - cornucopia_sync::Params<'a, super::Params, RowQuery<'a, C, super::Row, 2>, C> - for NamedCompactStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::Params, - ) -> RowQuery<'a, C, super::Row, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn named_spaced() -> NamedSpacedStmt { - NamedSpacedStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct NamedSpacedStmt(cornucopia_sync::private::Stmt); - impl NamedSpacedStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, - client: &'a mut C, - name: &'a T1, - price: &'a f64, - ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { - RowSpaceQuery { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| super::RowSpace { id: row.get(0) }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_sync::StringSql> - cornucopia_sync::Params< - 'a, - super::ParamsSpace, - RowSpaceQuery<'a, C, super::RowSpace, 2>, - C, - > for NamedSpacedStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::ParamsSpace, - ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn tricky_sql() -> TrickySqlStmt { - TrickySqlStmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a bind_param\', $1, $2)")) - } - pub struct TrickySqlStmt(cornucopia_sync::private::Stmt); - impl TrickySqlStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params<'a, super::TrickySqlParams, Result, C> - for TrickySqlStmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySqlParams, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql1() -> TrickySql1Stmt { - TrickySql1Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a :bind_param', $1, $2)")) - } - pub struct TrickySql1Stmt(cornucopia_sync::private::Stmt); - impl TrickySql1Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql1Params, - Result, - C, - > for TrickySql1Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql1Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql2() -> TrickySql2Stmt { - TrickySql2Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a '':bind_param''', $1, $2)")) - } - pub struct TrickySql2Stmt(cornucopia_sync::private::Stmt); - impl TrickySql2Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql2Params, - Result, - C, - > for TrickySql2Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql2Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql3() -> TrickySql3Stmt { - TrickySql3Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($$this is not a :bind_param$$, $1, $2)")) - } - pub struct TrickySql3Stmt(cornucopia_sync::private::Stmt); - impl TrickySql3Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql3Params, - Result, - C, - > for TrickySql3Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql3Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql4() -> TrickySql4Stmt { - TrickySql4Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($tag$this is not a :bind_param$tag$, $1, $2)")) - } - pub struct TrickySql4Stmt(cornucopia_sync::private::Stmt); - impl TrickySql4Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql4Params, - Result, - C, - > for TrickySql4Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql4Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql6() -> TrickySql6Stmt { - TrickySql6Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is not a '':bind_param''', $1, $2)")) - } - pub struct TrickySql6Stmt(cornucopia_sync::private::Stmt); - impl TrickySql6Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql6Params, - Result, - C, - > for TrickySql6Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql6Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql7() -> TrickySql7Stmt { - TrickySql7Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is not a \':bind_param\'', $1, $2)")) - } - pub struct TrickySql7Stmt(cornucopia_sync::private::Stmt); - impl TrickySql7Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql7Params, - Result, - C, - > for TrickySql7Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql7Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql8() -> TrickySql8Stmt { - TrickySql8Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is ''not'' a \':bind_param\'', $1, $2)")) - } - pub struct TrickySql8Stmt(cornucopia_sync::private::Stmt); - impl TrickySql8Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql8Params, - Result, - C, - > for TrickySql8Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql8Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql9() -> TrickySql9Stmt { - TrickySql9Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is \'not\' a \':bind_param\'', $1, $2)")) - } - pub struct TrickySql9Stmt(cornucopia_sync::private::Stmt); - impl TrickySql9Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql9Params, - Result, - C, - > for TrickySql9Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql9Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn tricky_sql10() -> TrickySql10Stmt { - TrickySql10Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is just a cast'::text, $1, $2)")) - } - pub struct TrickySql10Stmt(cornucopia_sync::private::Stmt); - impl TrickySql10Stmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) - } - } - impl<'a, C: GenericClient> - cornucopia_sync::Params< - 'a, - super::TrickySql10Params, - Result, - C, - > for TrickySql10Stmt - { - fn params( - &'a mut self, - client: &'a mut C, - params: &'a super::TrickySql10Params, - ) -> Result { - self.bind(client, ¶ms.r#async, ¶ms.r#enum) - } - } - pub fn r#typeof() -> RTypeofStmt { - RTypeofStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM syntax")) - } - pub struct RTypeofStmt(cornucopia_sync::private::Stmt); - impl RTypeofStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a mut C, - ) -> TypeofQuery<'a, C, super::Typeof, 0> { - TypeofQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::TypeofBorrowed { - trick_y: row.get(0), - r#async: row.get(1), - r#enum: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - } - pub mod async_ { - use cornucopia_async::GenericClient; - use futures; - use futures::{StreamExt, TryStreamExt}; - pub struct PublicCloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn( - &tokio_postgres::Row, - ) - -> super::super::super::types::public::CloneCompositeBorrowed, - mapper: fn(super::super::super::types::public::CloneCompositeBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> PublicCloneCompositeQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::super::super::types::public::CloneCompositeBorrowed) -> R, - ) -> PublicCloneCompositeQuery<'a, C, R, N> { - PublicCloneCompositeQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct Optioni32Query<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> Option, - mapper: fn(Option) -> T, - } - impl<'a, C, T: 'a, const N: usize> Optioni32Query<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(Option) -> R) -> Optioni32Query<'a, C, R, N> { - Optioni32Query { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct RowQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::Row, - mapper: fn(super::Row) -> T, - } - impl<'a, C, T: 'a, const N: usize> RowQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map(self, mapper: fn(super::Row) -> R) -> RowQuery<'a, C, R, N> { - RowQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct RowSpaceQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::RowSpace, - mapper: fn(super::RowSpace) -> T, - } - impl<'a, C, T: 'a, const N: usize> RowSpaceQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::RowSpace) -> R, - ) -> RowSpaceQuery<'a, C, R, N> { - RowSpaceQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub struct TypeofQuery<'a, C: GenericClient, T, const N: usize> { - client: &'a C, - params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, - extractor: fn(&tokio_postgres::Row) -> super::TypeofBorrowed, - mapper: fn(super::TypeofBorrowed) -> T, - } - impl<'a, C, T: 'a, const N: usize> TypeofQuery<'a, C, T, N> - where - C: GenericClient, - { - pub fn map( - self, - mapper: fn(super::TypeofBorrowed) -> R, - ) -> TypeofQuery<'a, C, R, N> { - TypeofQuery { - client: self.client, - params: self.params, - stmt: self.stmt, - extractor: self.extractor, - mapper, - } - } - pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; - Ok((self.mapper)((self.extractor)(&row))) - } - pub async fn all(self) -> Result, tokio_postgres::Error> { - self.iter().await?.try_collect().await - } - pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) - } - pub async fn iter( - self, - ) -> Result< - impl futures::Stream> + 'a, - tokio_postgres::Error, - > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? - .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) - .into_stream(); - Ok(it) - } - } - pub fn select_compact() -> SelectCompactStmt { - SelectCompactStmt(cornucopia_async::private::Stmt::new("SELECT * FROM clone")) - } - pub struct SelectCompactStmt(cornucopia_async::private::Stmt); - impl SelectCompactStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> PublicCloneCompositeQuery< - 'a, - C, - super::super::super::types::public::CloneComposite, - 0, - > { - PublicCloneCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn select_spaced() -> SelectSpacedStmt { - SelectSpacedStmt(cornucopia_async::private::Stmt::new( - " SELECT * FROM clone ", - )) - } - pub struct SelectSpacedStmt(cornucopia_async::private::Stmt); - impl SelectSpacedStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> PublicCloneCompositeQuery< - 'a, - C, - super::super::super::types::public::CloneComposite, - 0, - > { - PublicCloneCompositeQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it.into(), - } - } - } - pub fn implicit_compact() -> ImplicitCompactStmt { - ImplicitCompactStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct ImplicitCompactStmt(cornucopia_async::private::Stmt); - impl ImplicitCompactStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - name: &'a Option, - price: &'a Option, - ) -> Optioni32Query<'a, C, Option, 2> { - Optioni32Query { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it, - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_async::StringSql> - cornucopia_async::Params< - 'a, - super::ImplicitCompactParams, - Optioni32Query<'a, C, Option, 2>, - C, - > for ImplicitCompactStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::ImplicitCompactParams, - ) -> Optioni32Query<'a, C, Option, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn implicit_spaced() -> ImplicitSpacedStmt { - ImplicitSpacedStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct ImplicitSpacedStmt(cornucopia_async::private::Stmt); - impl ImplicitSpacedStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - name: &'a Option, - price: &'a Option, - ) -> Optioni32Query<'a, C, Option, 2> { - Optioni32Query { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| row.get(0), - mapper: |it| it, - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_async::StringSql> - cornucopia_async::Params< - 'a, - super::ImplicitSpacedParams, - Optioni32Query<'a, C, Option, 2>, - C, - > for ImplicitSpacedStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::ImplicitSpacedParams, - ) -> Optioni32Query<'a, C, Option, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn named_compact() -> NamedCompactStmt { - NamedCompactStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct NamedCompactStmt(cornucopia_async::private::Stmt); - impl NamedCompactStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - name: &'a T1, - price: &'a f64, - ) -> RowQuery<'a, C, super::Row, 2> { - RowQuery { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| super::Row { id: row.get(0) }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_async::StringSql> - cornucopia_async::Params<'a, super::Params, RowQuery<'a, C, super::Row, 2>, C> - for NamedCompactStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::Params, - ) -> RowQuery<'a, C, super::Row, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn named_spaced() -> NamedSpacedStmt { - NamedSpacedStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) - } - pub struct NamedSpacedStmt(cornucopia_async::private::Stmt); - impl NamedSpacedStmt { - pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, - client: &'a C, - name: &'a T1, - price: &'a f64, - ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { - RowSpaceQuery { - client, - params: [name, price], - stmt: &mut self.0, - extractor: |row| super::RowSpace { id: row.get(0) }, - mapper: |it| ::from(it), - } - } - } - impl<'a, C: GenericClient, T1: cornucopia_async::StringSql> - cornucopia_async::Params< - 'a, - super::ParamsSpace, - RowSpaceQuery<'a, C, super::RowSpace, 2>, - C, - > for NamedSpacedStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::ParamsSpace, - ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { - self.bind(client, ¶ms.name, ¶ms.price) - } - } - pub fn tricky_sql() -> TrickySqlStmt { - TrickySqlStmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a bind_param\', $1, $2)")) - } - pub struct TrickySqlStmt(cornucopia_async::private::Stmt); - impl TrickySqlStmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySqlParams, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySqlStmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySqlParams, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql1() -> TrickySql1Stmt { - TrickySql1Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a :bind_param', $1, $2)")) - } - pub struct TrickySql1Stmt(cornucopia_async::private::Stmt); - impl TrickySql1Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql1Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql1Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql1Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql2() -> TrickySql2Stmt { - TrickySql2Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a '':bind_param''', $1, $2)")) - } - pub struct TrickySql2Stmt(cornucopia_async::private::Stmt); - impl TrickySql2Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql2Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql2Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql2Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql3() -> TrickySql3Stmt { - TrickySql3Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($$this is not a :bind_param$$, $1, $2)")) - } - pub struct TrickySql3Stmt(cornucopia_async::private::Stmt); - impl TrickySql3Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql3Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql3Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql3Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql4() -> TrickySql4Stmt { - TrickySql4Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($tag$this is not a :bind_param$tag$, $1, $2)")) - } - pub struct TrickySql4Stmt(cornucopia_async::private::Stmt); - impl TrickySql4Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql4Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql4Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql4Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql6() -> TrickySql6Stmt { - TrickySql6Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is not a '':bind_param''', $1, $2)")) - } - pub struct TrickySql6Stmt(cornucopia_async::private::Stmt); - impl TrickySql6Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql6Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql6Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql6Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql7() -> TrickySql7Stmt { - TrickySql7Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is not a \':bind_param\'', $1, $2)")) - } - pub struct TrickySql7Stmt(cornucopia_async::private::Stmt); - impl TrickySql7Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql7Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql7Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql7Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql8() -> TrickySql8Stmt { - TrickySql8Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is ''not'' a \':bind_param\'', $1, $2)")) - } - pub struct TrickySql8Stmt(cornucopia_async::private::Stmt); - impl TrickySql8Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql8Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql8Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql8Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql9() -> TrickySql9Stmt { - TrickySql9Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is \'not\' a \':bind_param\'', $1, $2)")) - } - pub struct TrickySql9Stmt(cornucopia_async::private::Stmt); - impl TrickySql9Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql9Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql9Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql9Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn tricky_sql10() -> TrickySql10Stmt { - TrickySql10Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is just a cast'::text, $1, $2)")) - } - pub struct TrickySql10Stmt(cornucopia_async::private::Stmt); - impl TrickySql10Stmt { - pub async fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - r#async: &'a super::super::super::types::public::SyntaxComposite, - r#enum: &'a super::super::super::types::public::SyntaxEnum, - ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await - } - } - impl<'a, C: GenericClient + Send + Sync> - cornucopia_async::Params< - 'a, - super::TrickySql10Params, - std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - >, - C, - > for TrickySql10Stmt - { - fn params( - &'a mut self, - client: &'a C, - params: &'a super::TrickySql10Params, - ) -> std::pin::Pin< - Box< - dyn futures::Future> - + Send - + 'a, - >, - > { - Box::pin(self.bind(client, ¶ms.r#async, ¶ms.r#enum)) - } - } - pub fn r#typeof() -> RTypeofStmt { - RTypeofStmt(cornucopia_async::private::Stmt::new("SELECT * FROM syntax")) - } - pub struct RTypeofStmt(cornucopia_async::private::Stmt); - impl RTypeofStmt { - pub fn bind<'a, C: GenericClient>( - &'a mut self, - client: &'a C, - ) -> TypeofQuery<'a, C, super::Typeof, 0> { - TypeofQuery { - client, - params: [], - stmt: &mut self.0, - extractor: |row| super::TypeofBorrowed { - trick_y: row.get(0), - r#async: row.get(1), - r#enum: row.get(2), - }, - mapper: |it| ::from(it), - } - } - } - } - } -} diff --git a/test_codegen/src/main.rs b/test_codegen/src/main.rs index 86d7427f..a533bc7f 100644 --- a/test_codegen/src/main.rs +++ b/test_codegen/src/main.rs @@ -1,7 +1,3 @@ -mod cornucopia; - -use ::cornucopia_sync::IterSql; - use eui48::MacAddress; use postgres::{Client, Config, NoTls}; use rust_decimal::Decimal; @@ -14,7 +10,8 @@ use std::{ use time::{OffsetDateTime, PrimitiveDateTime}; use uuid::Uuid; -use crate::cornucopia::{ +use codegen::{ + client::sync::Params, queries::{ copy::sync::{insert_clone, insert_copy, select_copy}, domain::{ @@ -37,8 +34,9 @@ use crate::cornucopia::{ }, stress::{ sync::{ - insert_everything, insert_everything_array, insert_nightmare, select_everything, - select_everything_array, select_nightmare, + insert_everything, insert_everything_array, insert_nightmare, + insert_schema_nightmare, select_everything, select_everything_array, + select_nightmare, select_schema_nightmare, }, Everything, EverythingArray, EverythingArrayParams, EverythingParams, }, @@ -47,15 +45,15 @@ use crate::cornucopia::{ TrickySql10Params, }, }, - types::public::{ - CloneCompositeBorrowed, CopyComposite, CustomComposite, CustomCompositeBorrowed, + types::{ + schema, CloneCompositeBorrowed, CopyComposite, CustomComposite, CustomCompositeBorrowed, DomainComposite, DomainCompositeParams, EnumWithDot, NamedComposite, NamedCompositeBorrowed, NamedCompositeWithDot, NightmareComposite, NightmareCompositeParams, NullityComposite, NullityCompositeParams, SpongebobCharacter, SyntaxComposite, SyntaxEnum, }, + IterSql, }; -use cornucopia_sync::Params; pub fn main() { let client = &mut Config::new() @@ -559,6 +557,30 @@ pub fn test_stress(client: &mut Client) { assert_eq!(1, insert_nightmare().bind(client, ¶ms).unwrap()); let actual = select_nightmare().bind(client).one().unwrap(); assert_eq!(expected, actual); + + // In a named schema + let expected = schema::NightmareComposite { + custom: vec![CustomComposite { + wow: "Bob".to_string(), + such_cool: 42, + nice: SpongebobCharacter::Squidward, + }], + spongebob: vec![SpongebobCharacter::Bob, SpongebobCharacter::Patrick], + domain: "Hello".to_string(), + }; + let params = schema::NightmareCompositeParams { + custom: &[CustomCompositeBorrowed { + wow: "Bob", + such_cool: 42, + nice: SpongebobCharacter::Squidward, + }], + spongebob: &[SpongebobCharacter::Bob, SpongebobCharacter::Patrick], + domain: "Hello", + }; + + assert_eq!(1, insert_schema_nightmare().bind(client, ¶ms).unwrap()); + let actual = select_schema_nightmare().bind(client).one().unwrap(); + assert_eq!(expected, actual); } // Test keyword escaping diff --git a/test_integration/Cargo.toml b/test_integration/Cargo.toml index cd2e8fd4..9afe13d2 100644 --- a/test_integration/Cargo.toml +++ b/test_integration/Cargo.toml @@ -10,19 +10,22 @@ edition = "2021" cornucopia = { path = "../crates/cornucopia" } # Create temporary projects for error tests. -tempfile = "3.3.0" +tempfile = "3.5.0" + +# Compare directories +dir-diff = "0.3.2" # Colored output -owo-colors = "3.5.0" +owo-colors = "4.0.0" # CLI handling -clap = { version = "4.0.29", features = ["derive"] } +clap = { version = "4.3.5", features = ["derive"] } # Postgres interaction -postgres = { version = "0.19.4" } +postgres = "0.19.5" # serde ## Test fixtures ser/de -serde = { version = "1.0.148", features = ["derive"] } +serde = { version = "1.0.163", features = ["derive"] } ## Read/write fixture files toml = "0.8.2" diff --git a/test_integration/fixtures/codegen/benchmarks.toml b/test_integration/fixtures/codegen/benchmarks.toml index d68f075d..2f3c77e2 100644 --- a/test_integration/fixtures/codegen/benchmarks.toml +++ b/test_integration/fixtures/codegen/benchmarks.toml @@ -1,6 +1,6 @@ [[test]] name = "Execution benchmark" -base_path = "benches/execution/cornucopia_benches" -destination = "generated.rs" +base_path = "benches" +destination = "generated" sync = true async = true diff --git a/test_integration/fixtures/codegen/examples.toml b/test_integration/fixtures/codegen/examples.toml index aed93e25..9e192de1 100644 --- a/test_integration/fixtures/codegen/examples.toml +++ b/test_integration/fixtures/codegen/examples.toml @@ -1,17 +1,20 @@ [[test]] name = "Auto build" base_path = "examples/auto_build" +destination = "auto_build_codegen" async = true run = true [[test]] name = "Basic sync" base_path = "examples/basic_sync" +destination = "basic_sync_codegen" sync = true run = true [[test]] name = "Basic async" base_path = "examples/basic_async" +destination = "basic_async_codegen" async = true run = true diff --git a/test_integration/fixtures/codegen/test_codegen.toml b/test_integration/fixtures/codegen/test_codegen.toml index 9544709b..c8cd578f 100644 --- a/test_integration/fixtures/codegen/test_codegen.toml +++ b/test_integration/fixtures/codegen/test_codegen.toml @@ -1,7 +1,7 @@ [[test]] name = "Codegen" base_path = "test_codegen" -destination = "src/cornucopia.rs" +destination = "codegen" sync = true async = true derive_ser = true diff --git a/test_integration/fixtures/errors/codegen.toml b/test_integration/fixtures/errors/codegen.toml index 1213663f..0399846e 100644 --- a/test_integration/fixtures/errors/codegen.toml +++ b/test_integration/fixtures/errors/codegen.toml @@ -8,7 +8,7 @@ SELECT * FROM author; """ error = """ × `SelectBorrowed` is used multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --! select · ───┬── · ╰── previous definition as borrowed row here @@ -30,7 +30,7 @@ SELECT * FROM author; """ error = """ × `NewAuthorParams` is used multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --! new_author · ─────┬──── · ╰── previous definition as params here @@ -52,7 +52,7 @@ SELECT * FROM author; """ error = """ × `SelectQuery` is used multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --! select · ───┬── · ╰── previous definition as query here @@ -73,7 +73,7 @@ INSERT INTO Author (id, name) VALUES (:id, :name) RETURNING *; """ error = """ × `AuthorParams` is used multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:2:5] 1 │ --: AuthorParams() 2 │ --! author: AuthorParams · ───┬── ──────┬───── @@ -91,7 +91,7 @@ INSERT INTO Author (id, name) VALUES (:id, :name) RETURNING *; """ error = """ × `Author` is used multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:12] 1 │ --! author Author(): Author() · ───┬── ───┬── · │ ╰── redefined as row here @@ -108,7 +108,7 @@ INSERT INTO Author (id, name) VALUES (:id, :name) RETURNING *; """ error = """ × `AuthorParams` is used multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --! author: AuthorParams(id?) · ───┬── ──────┬───── · │ ╰── redefined as row here diff --git a/test_integration/fixtures/errors/prepare.toml b/test_integration/fixtures/errors/prepare.toml index 4fe1a617..12cb47af 100644 --- a/test_integration/fixtures/errors/prepare.toml +++ b/test_integration/fixtures/errors/prepare.toml @@ -6,7 +6,7 @@ SELECT id, name AS id FROM author; """ error = """ × column `id` appear multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --! authors · ───┬─── · ╰── query returns one or more columns with the same name @@ -22,7 +22,7 @@ INSERT INTO Author (id, name) VALUES (:name, :name); """ error = """ × Couldn't prepare query: inconsistent types deduced for parameter $1 - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:2:43] 1 │ --! insert_author 2 │ INSERT INTO Author (id, name) VALUES (:name, :name); · ▲ diff --git a/test_integration/fixtures/errors/schema.toml b/test_integration/fixtures/errors/schema.toml index e595ebc7..e5fb28cc 100644 --- a/test_integration/fixtures/errors/schema.toml +++ b/test_integration/fixtures/errors/schema.toml @@ -5,7 +5,7 @@ CREATE TABLE syntax {}; """ error = """ × Could not execute schema: syntax error at or near \"{\" - ╭─[schema.sql:1:1] + ╭─[schema.sql:2:22] 1 │ CREATE TABLE author (id SERIAL, name TEXT); 2 │ CREATE TABLE syntax {}; · ▲ diff --git a/test_integration/fixtures/errors/validation.toml b/test_integration/fixtures/errors/validation.toml index 8eaa72af..3002deba 100644 --- a/test_integration/fixtures/errors/validation.toml +++ b/test_integration/fixtures/errors/validation.toml @@ -6,7 +6,7 @@ INSERT INTO Author (id, name) VALUES (:id, :id); """ error = """ × the field `id` is declared null multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:16] 1 │ --! new_author(id?, id?) · ─┬ ─┬ · │ ╰── redeclared here @@ -23,7 +23,7 @@ SELECT * FROM author; """ error = """ × the field `id` is declared null multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:14] 1 │ --! author: (id?, name?, id?) · ─┬ ─┬ · │ ╰── redeclared here @@ -40,7 +40,7 @@ SELECT * FROM author; """ error = """ × unknown field - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:14] 1 │ --! author: (age?) · ─┬─ · ╰── no field with this name was found @@ -56,7 +56,7 @@ INSERT INTO Author (id, name) VALUES (:id, :name); """ error = """ × unknown field - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:17] 1 │ --! new_author (age?) · ─┬─ · ╰── no field with this name was found @@ -74,7 +74,7 @@ SELECT id FROM Author; """ error = """ × the query `author_id` is defined multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --! author_id · ────┬──── · ╰── previous definition here @@ -94,7 +94,7 @@ query = """ """ error = """ × the type `Row` is defined multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --: Row() · ─┬─ · ╰── previous definition here @@ -115,7 +115,7 @@ SELECT name FROM Author; """ error = """ × the row `Row` is defined multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --: Row() · ─┬─ · ╰── previous definition here @@ -137,7 +137,7 @@ INSERT INTO Author (id, name) VALUES (:id, :name); """ error = """ × the param `Param` is defined multiple time - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --: Param() · ──┬── · ╰── previous definition here @@ -156,7 +156,7 @@ SELECT * FROM author; """ error = """ × reference to an unknown named row `Author` - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:13] 1 │ --! author: Author · ───┬── · ╰── unknown named row @@ -172,7 +172,7 @@ INSERT INTO Author (id, name) VALUES (:id, :name); """ error = """ × reference to an unknown named param `Param` - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:16] 1 │ --! new_author Param · ──┬── · ╰── unknown named param @@ -191,7 +191,7 @@ SELECT id FROM Author; """ error = """ × conflicting uses of named type `Row` - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:2:19] 1 │ --: Row() 2 │ --! author_names: Row · ─┬─ @@ -215,7 +215,7 @@ SELECT name, id FROM Author; """ error = """ × conflicting uses of named type `Row` - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:2:19] 1 │ --: Row() 2 │ --! author_names: Row · ─┬─ @@ -239,7 +239,7 @@ SELECT id as name FROM Author; """ error = """ × conflicting uses of named type `Row` - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:2:19] 1 │ --: Row() 2 │ --! author_names: Row · ─┬─ @@ -260,7 +260,7 @@ DELETE FROM author; """ error = """ × the query `delete` declare a row but return nothing - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:13] 1 │ --! delete: (name?) · ───┬─── · ╰── row declared here @@ -278,7 +278,7 @@ DELETE FROM author; """ error = """ × the query `delete` declare a row but return nothing - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:13] 1 │ --! delete: Row() · ──┬── · ╰── row declared here @@ -296,7 +296,7 @@ DELETE FROM author; """ error = """ × the query `delete` declares a parameter but has no binding - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:12] 1 │ --! delete Param() · ───┬─── · ╰── parameter declared here @@ -314,7 +314,7 @@ SELECT * FROM author; """ error = """ × `crate` is a reserved rust keyword that cannot be escaped - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --! crate · ──┬── · ╰── reserved rust keyword @@ -330,7 +330,7 @@ SELECT * FROM author; """ error = """ × `Self` is a reserved rust keyword that cannot be escaped - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:13] 1 │ --! select: Self() · ──┬─ · ╰── reserved rust keyword @@ -346,7 +346,7 @@ SELECT id, name as _ FROM author; """ error = """ × `_` is a reserved rust keyword that cannot be escaped - ╭─[queries/test.sql:1:1] + ╭─[queries/test.sql:1:5] 1 │ --! query · ──┬── · ╰── from row declared here diff --git a/test_integration/src/codegen.rs b/test_integration/src/codegen.rs index 9d465407..7cf2290c 100644 --- a/test_integration/src/codegen.rs +++ b/test_integration/src/codegen.rs @@ -1,11 +1,12 @@ use crate::{ fixtures::{CodegenTest, TestSuite}, - utils::{reset_db, rustfmt_file, rustfmt_string}, + utils::{reset_db, rustfmt_lib}, }; use cornucopia::{CodegenSettings, Error}; use owo_colors::OwoColorize; use std::{env::set_current_dir, process::Command}; +use tempfile::tempdir; // Run codegen test, return true if all test are successful pub(crate) fn run_codegen_test( @@ -17,6 +18,7 @@ pub(crate) fn run_codegen_test( let fixture_path = "fixtures/codegen"; let test_suites = TestSuite::::read(fixture_path); + let tmp_dir = tempdir()?; for suite in test_suites { println!("{}", format!("[codegen] {}", suite.name).magenta()); for test in suite.tests { @@ -33,32 +35,36 @@ pub(crate) fn run_codegen_test( // Otherwise, it is only checked. if apply { // Generate - cornucopia::generate_live( + cornucopia::gen_live( client, &test.queries_path, - Some(&test.destination), + &test.destination, CodegenSettings::from(&test), ) .map_err(Error::report)?; - // Format the generated file - rustfmt_file(&test.destination); + // Format the generated crate + rustfmt_lib(&test.destination); } else { - // Get currently checked-in generate file - let old_codegen = std::fs::read_to_string(&test.destination).unwrap(); - // Generate new file - let new_codegen = cornucopia::generate_live( + let tmp_path = tmp_dir.path().join( + test.destination + .file_name() + .unwrap_or("cornucopia".as_ref()), + ); + std::fs::create_dir(&tmp_path)?; + // Generate + cornucopia::gen_live( client, &test.queries_path, - None, + &tmp_path, CodegenSettings::from(&test), ) .map_err(Error::report)?; - // Format the generated code string by piping to rustfmt - let new_codegen_formatted = rustfmt_string(&new_codegen); + // Format the generated crate + rustfmt_lib(&tmp_path); - // If the newly generated file differs from + // If the newly generated crate differs from // the currently checked in one, return an error. - if old_codegen != new_codegen_formatted { + if dir_diff::is_different(&test.destination, &tmp_path).unwrap() { Err(format!( "\"{}\" is outdated", test.destination.to_str().unwrap() diff --git a/test_integration/src/errors.rs b/test_integration/src/errors.rs index d5531a1a..be61cadd 100644 --- a/test_integration/src/errors.rs +++ b/test_integration/src/errors.rs @@ -12,8 +12,9 @@ pub(crate) fn run_errors_test( apply: bool, ) -> Result> { let mut successful = true; - let original_pwd = std::env::current_dir().unwrap(); + let original_pwd = std::env::current_dir()?; let test_suites = TestSuite::::read("fixtures/errors"); + let tmp = tempfile::tempdir()?; for mut suite in test_suites { println!("{} {}", "[error]".magenta(), suite.name.magenta()); @@ -48,10 +49,10 @@ pub(crate) fn run_errors_test( let result = cornucopia::load_schema(client, &["schema.sql"]) .map_err(Error::from) .and_then(|_| { - cornucopia::generate_live( + cornucopia::gen_live( client, - "queries", - None, + "queries".as_ref(), + tmp.path(), CodegenSettings::from(&*test), ) }); diff --git a/test_integration/src/fixtures.rs b/test_integration/src/fixtures.rs index 308c81c2..0d851590 100644 --- a/test_integration/src/fixtures.rs +++ b/test_integration/src/fixtures.rs @@ -51,7 +51,6 @@ pub(crate) struct CodegenTest { pub(crate) base_path: String, #[serde(default = "default_queries_path")] pub(crate) queries_path: PathBuf, - #[serde(default = "default_destination_path")] pub(crate) destination: PathBuf, #[serde(default)] pub(crate) sync: bool, @@ -67,10 +66,6 @@ fn default_queries_path() -> PathBuf { PathBuf::from("queries/") } -fn default_destination_path() -> PathBuf { - PathBuf::from("src/cornucopia.rs") -} - impl From<&CodegenTest> for CodegenSettings { fn from(codegen_test: &CodegenTest) -> Self { Self { diff --git a/test_integration/src/utils.rs b/test_integration/src/utils.rs index 1ba234b1..4134c1b7 100644 --- a/test_integration/src/utils.rs +++ b/test_integration/src/utils.rs @@ -1,35 +1,18 @@ -use std::{ - io::Write, - path::Path, - process::{Command, Stdio}, -}; +use std::{path::Path, process::Command}; /// Reset the current database pub(crate) fn reset_db(client: &mut postgres::Client) -> Result<(), postgres::Error> { client.batch_execute("DROP SCHEMA public CASCADE;CREATE SCHEMA public;") } -pub(crate) fn rustfmt_file(path: &Path) { - Command::new("rustfmt") - .args(["--edition", "2021"]) - .arg(path) - .output() - .unwrap(); -} - -pub(crate) fn rustfmt_string(string: &str) -> String { - // Format the generated code string by piping to rustfmt - let mut rustfmt = Command::new("rustfmt") - .args(["--edition", "2021"]) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap(); - rustfmt - .stdin - .as_mut() +pub(crate) fn rustfmt_lib(path: &Path) { + assert!(Command::new("rustfmt") + .args([ + "--edition", + "2021", + path.join("src/lib.rs").to_str().unwrap(), + ]) + .status() .unwrap() - .write_all(string.as_bytes()) - .unwrap(); - String::from_utf8(rustfmt.wait_with_output().unwrap().stdout).unwrap() + .success()); }