Attempt to migrate to sqlx 0.4.0-beta.1
There's still a ton of stuff broken. It's honestly too much to deal with right now so I'm abandoning it until it's released officially.
This commit is contained in:
parent
e0bba0254c
commit
e73d5d5f88
210
Cargo.lock
generated
210
Cargo.lock
generated
@ -15,6 +15,12 @@ dependencies = [
|
|||||||
"const-random",
|
"const-random",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.13"
|
version = "0.7.13"
|
||||||
@ -74,39 +80,6 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-native-tls"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33"
|
|
||||||
dependencies = [
|
|
||||||
"native-tls",
|
|
||||||
"thiserror",
|
|
||||||
"tokio",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-stream"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5"
|
|
||||||
dependencies = [
|
|
||||||
"async-stream-impl",
|
|
||||||
"futures-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-stream-impl"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.36"
|
version = "0.1.36"
|
||||||
@ -118,6 +91,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atoi"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c897df197d57c25b37df9d8fa2f93ddbfeee9ebd2264350ac79c8ec4b795885"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
@ -392,6 +374,16 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
"maybe-uninit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-queue"
|
name = "crossbeam-queue"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@ -414,16 +406,6 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crypto-mac"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
|
||||||
dependencies = [
|
|
||||||
"generic-array 0.12.3",
|
|
||||||
"subtle 1.0.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-mac"
|
name = "crypto-mac"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@ -431,7 +413,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
|
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.14.3",
|
"generic-array 0.14.3",
|
||||||
"subtle 2.2.3",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -464,6 +446,12 @@ version = "0.4.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
|
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fake-simd"
|
name = "fake-simd"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@ -681,7 +669,7 @@ version = "0.6.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
|
checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.2.18",
|
||||||
"autocfg 0.1.7",
|
"autocfg 0.1.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -691,6 +679,7 @@ version = "0.8.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb"
|
checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ahash 0.3.8",
|
||||||
"autocfg 1.0.0",
|
"autocfg 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -743,23 +732,13 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hmac"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
|
|
||||||
dependencies = [
|
|
||||||
"crypto-mac 0.7.0",
|
|
||||||
"digest 0.8.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840"
|
checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crypto-mac 0.8.0",
|
"crypto-mac",
|
||||||
"digest 0.9.0",
|
"digest 0.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -873,9 +852,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnetwork"
|
name = "ipnetwork"
|
||||||
version = "0.16.0"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8eca9f51da27bc908ef3dd85c21e1bbba794edaf94d7841e37356275b82d31e"
|
checksum = "02c3eaab3ac0ede60ffa41add21970a7df7d91772c03383aac6c2c3d53cc716b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@ -908,6 +887,12 @@ version = "0.2.74"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
|
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "listenfd"
|
name = "listenfd"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@ -946,6 +931,15 @@ dependencies = [
|
|||||||
"hashbrown 0.6.3",
|
"hashbrown 0.6.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru-cache"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maplit"
|
name = "maplit"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@ -975,13 +969,13 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "md-5"
|
name = "md-5"
|
||||||
version = "0.8.0"
|
version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
|
checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer 0.7.3",
|
"block-buffer 0.9.0",
|
||||||
"digest 0.8.1",
|
"digest 0.9.0",
|
||||||
"opaque-debug 0.2.3",
|
"opaque-debug 0.3.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1316,11 +1310,11 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
"hmac 0.8.1",
|
"hmac",
|
||||||
"md5",
|
"md5",
|
||||||
"memchr",
|
"memchr",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"sha2 0.9.1",
|
"sha2",
|
||||||
"stringprep",
|
"stringprep",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1738,6 +1732,7 @@ version = "1.0.57"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
|
checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1780,18 +1775,6 @@ dependencies = [
|
|||||||
"opaque-debug 0.3.0",
|
"opaque-debug 0.3.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sha2"
|
|
||||||
version = "0.8.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
|
||||||
dependencies = [
|
|
||||||
"block-buffer 0.7.3",
|
|
||||||
"digest 0.8.1",
|
|
||||||
"fake-simd",
|
|
||||||
"opaque-debug 0.2.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
@ -1867,9 +1850,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx"
|
name = "sqlx"
|
||||||
version = "0.3.5"
|
version = "0.4.0-beta.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8974cacd80085fbe49e778708d660dec6fb351604dc34c3905b26efb2803b038"
|
checksum = "8cb7b012f28c74075d6b11172ba1874f4376a255509462eaf2ef25068b31729f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sqlx-core",
|
"sqlx-core",
|
||||||
"sqlx-macros",
|
"sqlx-macros",
|
||||||
@ -1877,59 +1860,82 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-core"
|
name = "sqlx-core"
|
||||||
version = "0.3.5"
|
version = "0.4.0-beta.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "88ac5a436f941c42eac509471a730df5c3c58e1450e68cd39afedbd948206273"
|
checksum = "fe2857d90b39b8528948109abc1b8d4c1905d184c87deaf06055f0b21050f13e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-native-tls",
|
"atoi",
|
||||||
"async-stream",
|
|
||||||
"base64",
|
"base64",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"crossbeam-channel",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
|
"either",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"hashbrown 0.8.1",
|
||||||
"hex",
|
"hex",
|
||||||
"hmac 0.7.1",
|
"hmac",
|
||||||
"ipnetwork",
|
"ipnetwork",
|
||||||
|
"itoa",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
"lru-cache",
|
||||||
"md-5",
|
"md-5",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha-1 0.8.2",
|
"sha-1 0.9.1",
|
||||||
"sha2 0.8.2",
|
"sha2",
|
||||||
|
"smallvec",
|
||||||
"sqlformat",
|
"sqlformat",
|
||||||
"tokio",
|
"sqlx-rt",
|
||||||
|
"stringprep",
|
||||||
|
"thiserror",
|
||||||
"url",
|
"url",
|
||||||
"uuid 0.8.1",
|
"uuid 0.8.1",
|
||||||
|
"whoami",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-macros"
|
name = "sqlx-macros"
|
||||||
version = "0.3.5"
|
version = "0.4.0-beta.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de2ae78b783af5922d811b14665a5a3755e531c3087bb805cf24cf71f15e6780"
|
checksum = "6d1bc862e5f4484965156c224f7e4c139f2d3c65b6aa0e3ae8c63461831b8da9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenv",
|
"dotenv",
|
||||||
|
"either",
|
||||||
"futures",
|
"futures",
|
||||||
"heck",
|
"heck",
|
||||||
"lazy_static",
|
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sqlx-core",
|
"sqlx-core",
|
||||||
|
"sqlx-rt",
|
||||||
"syn",
|
"syn",
|
||||||
"tokio",
|
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-rt"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23f9104f6116b568358f315e9839ae66c4ebbc0e974db5580105f0acfeb4863f"
|
||||||
|
dependencies = [
|
||||||
|
"native-tls",
|
||||||
|
"once_cell",
|
||||||
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stringprep"
|
name = "stringprep"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@ -1946,12 +1952,6 @@ version = "0.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "subtle"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.2.3"
|
version = "2.2.3"
|
||||||
@ -2092,6 +2092,16 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-native-tls"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd608593a919a8e05a7d1fc6df885e40f6a88d3a70a3a7eff23ff27964eda069"
|
||||||
|
dependencies = [
|
||||||
|
"native-tls",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-postgres"
|
name = "tokio-postgres"
|
||||||
version = "0.5.5"
|
version = "0.5.5"
|
||||||
@ -2440,6 +2450,12 @@ version = "0.9.0+wasi-snapshot-preview1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "whoami"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7884773ab69074615cb8f8425d0e53f11710786158704fca70f53e71b0e05504"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
|
@ -14,7 +14,7 @@ http-api-problem = { version = "0.17", features = ["with-warp"] }
|
|||||||
hyper = "0.13"
|
hyper = "0.13"
|
||||||
listenfd = "0.3"
|
listenfd = "0.3"
|
||||||
tokio = { version = "0.2", features = ["macros", "rt-threaded", "sync"] }
|
tokio = { version = "0.2", features = ["macros", "rt-threaded", "sync"] }
|
||||||
sqlx = { version = "0.3", default-features = false, features = [ "runtime-tokio", "macros", "postgres", "chrono", "uuid", "ipnetwork", "json" ] }
|
sqlx = { version = "0.4.0-beta.1", default-features = false, features = [ "runtime-tokio", "macros", "postgres", "chrono", "uuid", "ipnetwork", "json" ] }
|
||||||
warp = { version = "0.2", features = ["compression"] }
|
warp = { version = "0.2", features = ["compression"] }
|
||||||
refinery = { version = "0.3.0", features = [ "tokio-postgres", "tokio" ] }
|
refinery = { version = "0.3.0", features = [ "tokio-postgres", "tokio" ] }
|
||||||
barrel = { version = "0.6.5", features = [ "pg" ] }
|
barrel = { version = "0.6.5", features = [ "pg" ] }
|
||||||
@ -22,7 +22,7 @@ clap = "3.0.0-beta.1"
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||||
ipnetwork = "0.16"
|
ipnetwork = "0.17"
|
||||||
url = "2.1"
|
url = "2.1"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
35
migrations/initial_schema.sql
Normal file
35
migrations/initial_schema.sql
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS "owners" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY NOT NULL,
|
||||||
|
"name" VARCHAR(255) NOT NULL,
|
||||||
|
"api_key" UUID NOT NULL UNIQUE,
|
||||||
|
"ip_address" inet,
|
||||||
|
"mod_version" INTEGER NOT NULL,
|
||||||
|
"created_at" timestamp(3) NOT NULL,
|
||||||
|
"updated_at" timestamp(3) NOT NULL
|
||||||
|
);
|
||||||
|
CREATE UNIQUE INDEX "owners_unique_name_and_api_key" ON "owners" ("name", "api_key");
|
||||||
|
CREATE TABLE "shops" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY NOT NULL,
|
||||||
|
"name" VARCHAR(255) NOT NULL,
|
||||||
|
"owner_id" INTEGER REFERENCES "owners"(id) NOT NULL,
|
||||||
|
"description" TEXT,
|
||||||
|
"created_at" timestamp(3) NOT NULL,
|
||||||
|
"updated_at" timestamp(3) NOT NULL
|
||||||
|
);
|
||||||
|
CREATE UNIQUE INDEX "shops_unique_name_and_owner_id" ON "shops" ("name", "owner_id");
|
||||||
|
CREATE TABLE "interior_ref_lists" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY NOT NULL,
|
||||||
|
"shop_id" INTEGER REFERENCES "shops"(id) NOT NULL UNIQUE,
|
||||||
|
"owner_id" INTEGER REFERENCES "owners"(id) NOT NULL,
|
||||||
|
"ref_list" jsonb NOT NULL,
|
||||||
|
"created_at" timestamp(3) NOT NULL,
|
||||||
|
"updated_at" timestamp(3) NOT NULL
|
||||||
|
);
|
||||||
|
CREATE TABLE "merchandise_lists" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY NOT NULL,
|
||||||
|
"shop_id" INTEGER REFERENCES "shops"(id) NOT NULL UNIQUE,
|
||||||
|
"owner_id" INTEGER REFERENCES "owners"(id) NOT NULL,
|
||||||
|
"form_list" jsonb NOT NULL,
|
||||||
|
"created_at" timestamp(3) NOT NULL,
|
||||||
|
"updated_at" timestamp(3) NOT NULL
|
||||||
|
);
|
33
src/main.rs
33
src/main.rs
@ -22,10 +22,10 @@ mod models;
|
|||||||
mod problem;
|
mod problem;
|
||||||
|
|
||||||
use caches::Caches;
|
use caches::Caches;
|
||||||
use models::interior_ref_list::InteriorRefList;
|
use models::interior_ref_list::PostedInteriorRefList;
|
||||||
use models::merchandise_list::{MerchandiseList, MerchandiseParams};
|
use models::merchandise_list::{MerchandiseParams, PostedMerchandiseList};
|
||||||
use models::owner::Owner;
|
use models::owner::PostedOwner;
|
||||||
use models::shop::Shop;
|
use models::shop::PostedShop;
|
||||||
use models::ListParams;
|
use models::ListParams;
|
||||||
|
|
||||||
#[derive(Clap)]
|
#[derive(Clap)]
|
||||||
@ -45,10 +45,7 @@ pub struct Environment {
|
|||||||
impl Environment {
|
impl Environment {
|
||||||
async fn new(api_url: Url) -> Result<Environment> {
|
async fn new(api_url: Url) -> Result<Environment> {
|
||||||
Ok(Environment {
|
Ok(Environment {
|
||||||
db: PgPool::builder()
|
db: PgPool::connect(&env::var("DATABASE_URL")?).await?,
|
||||||
.max_size(5)
|
|
||||||
.build(&env::var("DATABASE_URL")?)
|
|
||||||
.await?,
|
|
||||||
caches: Caches::initialize(),
|
caches: Caches::initialize(),
|
||||||
api_url,
|
api_url,
|
||||||
})
|
})
|
||||||
@ -108,7 +105,7 @@ async fn main() -> Result<()> {
|
|||||||
let create_owner_handler = warp::path("owners").and(
|
let create_owner_handler = warp::path("owners").and(
|
||||||
warp::path::end()
|
warp::path::end()
|
||||||
.and(warp::post())
|
.and(warp::post())
|
||||||
.and(json_body::<Owner>())
|
.and(json_body::<PostedOwner>())
|
||||||
.and(warp::addr::remote())
|
.and(warp::addr::remote())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(warp::header::optional("x-real-ip"))
|
.and(warp::header::optional("x-real-ip"))
|
||||||
@ -127,7 +124,7 @@ async fn main() -> Result<()> {
|
|||||||
warp::path::param()
|
warp::path::param()
|
||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(warp::patch())
|
.and(warp::patch())
|
||||||
.and(json_body::<Owner>())
|
.and(json_body::<PostedOwner>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::update_owner),
|
.and_then(handlers::update_owner),
|
||||||
@ -149,7 +146,7 @@ async fn main() -> Result<()> {
|
|||||||
let create_shop_handler = warp::path("shops").and(
|
let create_shop_handler = warp::path("shops").and(
|
||||||
warp::path::end()
|
warp::path::end()
|
||||||
.and(warp::post())
|
.and(warp::post())
|
||||||
.and(json_body::<Shop>())
|
.and(json_body::<PostedShop>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::create_shop),
|
.and_then(handlers::create_shop),
|
||||||
@ -166,7 +163,7 @@ async fn main() -> Result<()> {
|
|||||||
warp::path::param()
|
warp::path::param()
|
||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(warp::patch())
|
.and(warp::patch())
|
||||||
.and(json_body::<Shop>())
|
.and(json_body::<PostedShop>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::update_shop),
|
.and_then(handlers::update_shop),
|
||||||
@ -188,7 +185,7 @@ async fn main() -> Result<()> {
|
|||||||
let create_interior_ref_list_handler = warp::path("interior_ref_lists").and(
|
let create_interior_ref_list_handler = warp::path("interior_ref_lists").and(
|
||||||
warp::path::end()
|
warp::path::end()
|
||||||
.and(warp::post())
|
.and(warp::post())
|
||||||
.and(json_body::<InteriorRefList>())
|
.and(json_body::<PostedInteriorRefList>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::create_interior_ref_list),
|
.and_then(handlers::create_interior_ref_list),
|
||||||
@ -205,7 +202,7 @@ async fn main() -> Result<()> {
|
|||||||
warp::path::param()
|
warp::path::param()
|
||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(warp::patch())
|
.and(warp::patch())
|
||||||
.and(json_body::<InteriorRefList>())
|
.and(json_body::<PostedInteriorRefList>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::update_interior_ref_list),
|
.and_then(handlers::update_interior_ref_list),
|
||||||
@ -215,7 +212,7 @@ async fn main() -> Result<()> {
|
|||||||
.and(warp::path("interior_ref_list"))
|
.and(warp::path("interior_ref_list"))
|
||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(warp::patch())
|
.and(warp::patch())
|
||||||
.and(json_body::<InteriorRefList>())
|
.and(json_body::<PostedInteriorRefList>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::update_interior_ref_list_by_shop_id),
|
.and_then(handlers::update_interior_ref_list_by_shop_id),
|
||||||
@ -245,7 +242,7 @@ async fn main() -> Result<()> {
|
|||||||
let create_merchandise_list_handler = warp::path("merchandise_lists").and(
|
let create_merchandise_list_handler = warp::path("merchandise_lists").and(
|
||||||
warp::path::end()
|
warp::path::end()
|
||||||
.and(warp::post())
|
.and(warp::post())
|
||||||
.and(json_body::<MerchandiseList>())
|
.and(json_body::<PostedMerchandiseList>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::create_merchandise_list),
|
.and_then(handlers::create_merchandise_list),
|
||||||
@ -262,7 +259,7 @@ async fn main() -> Result<()> {
|
|||||||
warp::path::param()
|
warp::path::param()
|
||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(warp::patch())
|
.and(warp::patch())
|
||||||
.and(json_body::<MerchandiseList>())
|
.and(json_body::<PostedMerchandiseList>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::update_merchandise_list),
|
.and_then(handlers::update_merchandise_list),
|
||||||
@ -272,7 +269,7 @@ async fn main() -> Result<()> {
|
|||||||
.and(warp::path("merchandise_list"))
|
.and(warp::path("merchandise_list"))
|
||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(warp::patch())
|
.and(warp::patch())
|
||||||
.and(json_body::<MerchandiseList>())
|
.and(json_body::<PostedMerchandiseList>())
|
||||||
.and(warp::header::optional("api-key"))
|
.and(warp::header::optional("api-key"))
|
||||||
.and(with_env(env.clone()))
|
.and(with_env(env.clone()))
|
||||||
.and_then(handlers::update_merchandise_list_by_shop_id),
|
.and_then(handlers::update_merchandise_list_by_shop_id),
|
||||||
|
@ -7,7 +7,7 @@ use sqlx::types::Json;
|
|||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use super::ListParams;
|
use super::ListParams;
|
||||||
use super::{Model, UpdateableModel};
|
use super::{Model, PostedModel, UpdateableModel};
|
||||||
use crate::problem::forbidden_permission;
|
use crate::problem::forbidden_permission;
|
||||||
|
|
||||||
// sqlx queries for this model need to be `query_as_unchecked!` because `query_as!` does not
|
// sqlx queries for this model need to be `query_as_unchecked!` because `query_as!` does not
|
||||||
@ -32,21 +32,30 @@ pub struct InteriorRef {
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct InteriorRefList {
|
pub struct InteriorRefList {
|
||||||
pub id: Option<i32>,
|
pub id: i32,
|
||||||
|
pub shop_id: i32,
|
||||||
|
pub owner_id: i32,
|
||||||
|
pub ref_list: Json<Vec<InteriorRef>>,
|
||||||
|
pub created_at: NaiveDateTime,
|
||||||
|
pub updated_at: NaiveDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct PostedInteriorRefList {
|
||||||
pub shop_id: i32,
|
pub shop_id: i32,
|
||||||
pub owner_id: Option<i32>,
|
pub owner_id: Option<i32>,
|
||||||
pub ref_list: Json<Vec<InteriorRef>>,
|
pub ref_list: Json<Vec<InteriorRef>>,
|
||||||
pub created_at: Option<NaiveDateTime>,
|
|
||||||
pub updated_at: Option<NaiveDateTime>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PostedModel for PostedInteriorRefList {}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Model for InteriorRefList {
|
impl Model for InteriorRefList {
|
||||||
fn resource_name() -> &'static str {
|
fn resource_name() -> &'static str {
|
||||||
"interior_ref_list"
|
"interior_ref_list"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pk(&self) -> Option<i32> {
|
fn pk(&self) -> i32 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +68,8 @@ impl Model for InteriorRefList {
|
|||||||
.map_err(Error::new)
|
.map_err(Error::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
async fn create(self, db: &PgPool) -> Result<Self> {
|
async fn create(posted: PostedInteriorRefList, db: &PgPool) -> Result<Self> {
|
||||||
// TODO:
|
// TODO:
|
||||||
// * Decide if I'll need to make the same changes to merchandise and transactions
|
// * Decide if I'll need to make the same changes to merchandise and transactions
|
||||||
// - answer depends on how many rows of each I expect to insert in one go
|
// - answer depends on how many rows of each I expect to insert in one go
|
||||||
@ -71,9 +80,9 @@ impl Model for InteriorRefList {
|
|||||||
(shop_id, owner_id, ref_list, created_at, updated_at)
|
(shop_id, owner_id, ref_list, created_at, updated_at)
|
||||||
VALUES ($1, $2, $3, now(), now())
|
VALUES ($1, $2, $3, now(), now())
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
self.shop_id,
|
posted.shop_id,
|
||||||
self.owner_id,
|
posted.owner_id,
|
||||||
self.ref_list,
|
posted.ref_list,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
@ -129,8 +138,13 @@ impl Model for InteriorRefList {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UpdateableModel for InteriorRefList {
|
impl UpdateableModel for InteriorRefList {
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
async fn update(self, db: &PgPool, owner_id: i32, id: i32) -> Result<Self> {
|
async fn update(
|
||||||
|
posted: PostedInteriorRefList,
|
||||||
|
db: &PgPool,
|
||||||
|
owner_id: i32,
|
||||||
|
id: i32,
|
||||||
|
) -> Result<Self> {
|
||||||
let interior_ref_list =
|
let interior_ref_list =
|
||||||
sqlx::query!("SELECT owner_id FROM interior_ref_lists WHERE id = $1", id)
|
sqlx::query!("SELECT owner_id FROM interior_ref_lists WHERE id = $1", id)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
@ -144,7 +158,7 @@ impl UpdateableModel for InteriorRefList {
|
|||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
id,
|
id,
|
||||||
self.ref_list,
|
posted.ref_list,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
@ -168,8 +182,13 @@ impl InteriorRefList {
|
|||||||
.map_err(Error::new)
|
.map_err(Error::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
pub async fn update_by_shop_id(self, db: &PgPool, owner_id: i32, shop_id: i32) -> Result<Self> {
|
pub async fn update_by_shop_id(
|
||||||
|
posted: PostedInteriorRefList,
|
||||||
|
db: &PgPool,
|
||||||
|
owner_id: i32,
|
||||||
|
shop_id: i32,
|
||||||
|
) -> Result<Self> {
|
||||||
let interior_ref_list = sqlx::query!(
|
let interior_ref_list = sqlx::query!(
|
||||||
"SELECT owner_id FROM interior_ref_lists WHERE shop_id = $1",
|
"SELECT owner_id FROM interior_ref_lists WHERE shop_id = $1",
|
||||||
shop_id
|
shop_id
|
||||||
@ -185,7 +204,7 @@ impl InteriorRefList {
|
|||||||
WHERE shop_id = $1
|
WHERE shop_id = $1
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
shop_id,
|
shop_id,
|
||||||
self.ref_list,
|
posted.ref_list,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
|
@ -8,7 +8,7 @@ use sqlx::types::Json;
|
|||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use super::ListParams;
|
use super::ListParams;
|
||||||
use super::{Model, UpdateableModel};
|
use super::{Model, PostedModel, UpdateableModel};
|
||||||
use crate::problem::forbidden_permission;
|
use crate::problem::forbidden_permission;
|
||||||
|
|
||||||
// sqlx queries for this model need to be `query_as_unchecked!` because `query_as!` does not
|
// sqlx queries for this model need to be `query_as_unchecked!` because `query_as!` does not
|
||||||
@ -29,14 +29,23 @@ pub struct Merchandise {
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct MerchandiseList {
|
pub struct MerchandiseList {
|
||||||
pub id: Option<i32>,
|
pub id: i32,
|
||||||
|
pub shop_id: i32,
|
||||||
|
pub owner_id: i32,
|
||||||
|
pub form_list: Json<Vec<Merchandise>>,
|
||||||
|
pub created_at: NaiveDateTime,
|
||||||
|
pub updated_at: NaiveDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct PostedMerchandiseList {
|
||||||
pub shop_id: i32,
|
pub shop_id: i32,
|
||||||
pub owner_id: Option<i32>,
|
pub owner_id: Option<i32>,
|
||||||
pub form_list: Json<Vec<Merchandise>>,
|
pub form_list: Json<Vec<Merchandise>>,
|
||||||
pub created_at: Option<NaiveDateTime>,
|
|
||||||
pub updated_at: Option<NaiveDateTime>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PostedModel for PostedMerchandiseList {}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone, Deserialize)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone, Deserialize)]
|
||||||
pub struct MerchandiseParams {
|
pub struct MerchandiseParams {
|
||||||
pub mod_name: String,
|
pub mod_name: String,
|
||||||
@ -50,7 +59,7 @@ impl Model for MerchandiseList {
|
|||||||
"merchandise_list"
|
"merchandise_list"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pk(&self) -> Option<i32> {
|
fn pk(&self) -> i32 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,17 +72,17 @@ impl Model for MerchandiseList {
|
|||||||
.map_err(Error::new)
|
.map_err(Error::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
async fn create(self, db: &PgPool) -> Result<Self> {
|
async fn create(posted: PostedMerchandiseList, db: &PgPool) -> Result<Self> {
|
||||||
Ok(sqlx::query_as_unchecked!(
|
Ok(sqlx::query_as_unchecked!(
|
||||||
Self,
|
Self,
|
||||||
"INSERT INTO merchandise_lists
|
"INSERT INTO merchandise_lists
|
||||||
(shop_id, owner_id, form_list, created_at, updated_at)
|
(shop_id, owner_id, form_list, created_at, updated_at)
|
||||||
VALUES ($1, $2, $3, now(), now())
|
VALUES ($1, $2, $3, now(), now())
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
self.shop_id,
|
posted.shop_id,
|
||||||
self.owner_id,
|
posted.owner_id,
|
||||||
self.form_list,
|
posted.form_list,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
@ -129,8 +138,13 @@ impl Model for MerchandiseList {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UpdateableModel for MerchandiseList {
|
impl UpdateableModel for MerchandiseList {
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
async fn update(self, db: &PgPool, owner_id: i32, id: i32) -> Result<Self> {
|
async fn update(
|
||||||
|
posted: PostedMerchandiseList,
|
||||||
|
db: &PgPool,
|
||||||
|
owner_id: i32,
|
||||||
|
id: i32,
|
||||||
|
) -> Result<Self> {
|
||||||
let merchandise_list =
|
let merchandise_list =
|
||||||
sqlx::query!("SELECT owner_id FROM merchandise_lists WHERE id = $1", id)
|
sqlx::query!("SELECT owner_id FROM merchandise_lists WHERE id = $1", id)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
@ -144,7 +158,7 @@ impl UpdateableModel for MerchandiseList {
|
|||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
id,
|
id,
|
||||||
self.form_list,
|
posted.form_list,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
@ -168,8 +182,13 @@ impl MerchandiseList {
|
|||||||
.map_err(Error::new)
|
.map_err(Error::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
pub async fn update_by_shop_id(self, db: &PgPool, owner_id: i32, shop_id: i32) -> Result<Self> {
|
pub async fn update_by_shop_id(
|
||||||
|
posted: PostedMerchandiseList,
|
||||||
|
db: &PgPool,
|
||||||
|
owner_id: i32,
|
||||||
|
shop_id: i32,
|
||||||
|
) -> Result<Self> {
|
||||||
let merchandise_list = sqlx::query!(
|
let merchandise_list = sqlx::query!(
|
||||||
"SELECT owner_id FROM merchandise_lists WHERE shop_id = $1",
|
"SELECT owner_id FROM merchandise_lists WHERE shop_id = $1",
|
||||||
shop_id
|
shop_id
|
||||||
@ -185,7 +204,7 @@ impl MerchandiseList {
|
|||||||
WHERE shop_id = $1
|
WHERE shop_id = $1
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
shop_id,
|
shop_id,
|
||||||
self.form_list,
|
posted.form_list,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
|
@ -10,7 +10,7 @@ pub mod shop;
|
|||||||
|
|
||||||
pub use interior_ref_list::InteriorRefList;
|
pub use interior_ref_list::InteriorRefList;
|
||||||
pub use merchandise_list::{MerchandiseList, MerchandiseParams};
|
pub use merchandise_list::{MerchandiseList, MerchandiseParams};
|
||||||
pub use model::{Model, UpdateableModel};
|
pub use model::{Model, PostedModel, UpdateableModel};
|
||||||
pub use owner::Owner;
|
pub use owner::Owner;
|
||||||
pub use shop::Shop;
|
pub use shop::Shop;
|
||||||
|
|
||||||
|
@ -5,25 +5,20 @@ use url::Url;
|
|||||||
|
|
||||||
use super::ListParams;
|
use super::ListParams;
|
||||||
|
|
||||||
|
pub trait PostedModel {}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Model
|
pub trait Model
|
||||||
where
|
where
|
||||||
Self: std::marker::Sized,
|
Self: std::marker::Sized,
|
||||||
{
|
{
|
||||||
fn resource_name() -> &'static str;
|
fn resource_name() -> &'static str;
|
||||||
fn pk(&self) -> Option<i32>;
|
fn pk(&self) -> i32;
|
||||||
fn url(&self, api_url: &Url) -> Result<Url> {
|
fn url(&self, api_url: &Url) -> Result<Url> {
|
||||||
if let Some(pk) = self.pk() {
|
Ok(api_url.join(&format!("{}s/{}", Self::resource_name(), self.pk()))?)
|
||||||
Ok(api_url.join(&format!("{}s/{}", Self::resource_name(), pk))?)
|
|
||||||
} else {
|
|
||||||
Err(anyhow!(
|
|
||||||
"Cannot get URL for {} with no primary key",
|
|
||||||
Self::resource_name()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
async fn get(db: &PgPool, id: i32) -> Result<Self>;
|
async fn get(db: &PgPool, id: i32) -> Result<Self>;
|
||||||
async fn create(self, db: &PgPool) -> Result<Self>;
|
async fn create(posted: dyn PostedModel, db: &PgPool) -> Result<Self>;
|
||||||
async fn delete(db: &PgPool, owner_id: i32, id: i32) -> Result<u64>;
|
async fn delete(db: &PgPool, owner_id: i32, id: i32) -> Result<u64>;
|
||||||
async fn list(db: &PgPool, list_params: &ListParams) -> Result<Vec<Self>>;
|
async fn list(db: &PgPool, list_params: &ListParams) -> Result<Vec<Self>>;
|
||||||
}
|
}
|
||||||
@ -33,5 +28,5 @@ pub trait UpdateableModel
|
|||||||
where
|
where
|
||||||
Self: std::marker::Sized,
|
Self: std::marker::Sized,
|
||||||
{
|
{
|
||||||
async fn update(self, db: &PgPool, owner_id: i32, id: i32) -> Result<Self>;
|
async fn update(posted: dyn PostedModel, db: &PgPool, owner_id: i32, id: i32) -> Result<Self>;
|
||||||
}
|
}
|
@ -8,29 +8,43 @@ use tracing::instrument;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::ListParams;
|
use super::ListParams;
|
||||||
use super::{Model, UpdateableModel};
|
use super::{Model, PostedModel, UpdateableModel};
|
||||||
use crate::problem::forbidden_permission;
|
use crate::problem::forbidden_permission;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Owner {
|
pub struct Owner {
|
||||||
pub id: Option<i32>,
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub api_key: Uuid,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub ip_address: Option<IpNetwork>,
|
||||||
|
pub mod_version: i32,
|
||||||
|
pub created_at: NaiveDateTime,
|
||||||
|
pub updated_at: NaiveDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct PostedOwner {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub api_key: Option<Uuid>,
|
pub api_key: Option<Uuid>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub ip_address: Option<IpNetwork>,
|
pub ip_address: Option<IpNetwork>,
|
||||||
pub mod_version: i32,
|
pub mod_version: i32,
|
||||||
pub created_at: Option<NaiveDateTime>,
|
pub created_at: NaiveDateTime,
|
||||||
pub updated_at: Option<NaiveDateTime>,
|
pub updated_at: NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PostedModel for PostedOwner {}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Model for Owner {
|
impl Model for Owner {
|
||||||
fn resource_name() -> &'static str {
|
fn resource_name() -> &'static str {
|
||||||
"owner"
|
"owner"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pk(&self) -> Option<i32> {
|
fn pk(&self) -> i32 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,18 +56,18 @@ impl Model for Owner {
|
|||||||
.map_err(Error::new)
|
.map_err(Error::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
async fn create(self, db: &PgPool) -> Result<Self> {
|
async fn create(posted: PostedOwner, db: &PgPool) -> Result<Self> {
|
||||||
Ok(sqlx::query_as!(
|
Ok(sqlx::query_as!(
|
||||||
Self,
|
Self,
|
||||||
"INSERT INTO owners
|
"INSERT INTO owners
|
||||||
(name, api_key, ip_address, mod_version, created_at, updated_at)
|
(name, api_key, ip_address, mod_version, created_at, updated_at)
|
||||||
VALUES ($1, $2, $3, $4, now(), now())
|
VALUES ($1, $2, $3, $4, now(), now())
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
self.name,
|
posted.name,
|
||||||
self.api_key,
|
posted.api_key,
|
||||||
self.ip_address,
|
posted.ip_address,
|
||||||
self.mod_version,
|
posted.mod_version,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
@ -106,8 +120,8 @@ impl Model for Owner {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UpdateableModel for Owner {
|
impl UpdateableModel for Owner {
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
async fn update(self, db: &PgPool, owner_id: i32, id: i32) -> Result<Self> {
|
async fn update(posted: PostedOwner, db: &PgPool, owner_id: i32, id: i32) -> Result<Self> {
|
||||||
let owner = sqlx::query!("SELECT id FROM owners WHERE id = $1", id)
|
let owner = sqlx::query!("SELECT id FROM owners WHERE id = $1", id)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?;
|
.await?;
|
||||||
@ -121,8 +135,8 @@ impl UpdateableModel for Owner {
|
|||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
id,
|
id,
|
||||||
self.name,
|
posted.name,
|
||||||
self.mod_version,
|
posted.mod_version,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
|
@ -6,31 +6,40 @@ use sqlx::postgres::PgPool;
|
|||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use super::ListParams;
|
use super::ListParams;
|
||||||
use super::{Model, UpdateableModel};
|
use super::{Model, PostedModel, UpdateableModel};
|
||||||
use crate::problem::forbidden_permission;
|
use crate::problem::forbidden_permission;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Shop {
|
pub struct Shop {
|
||||||
pub id: Option<i32>,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub owner_id: Option<i32>,
|
pub owner_id: i32,
|
||||||
pub description: String,
|
pub description: Option<String>,
|
||||||
// removing these until I figure out the plan for buying and selling
|
// removing these until I figure out the plan for buying and selling
|
||||||
// pub is_not_sell_buy: bool,
|
// pub is_not_sell_buy: bool,
|
||||||
// pub sell_buy_list_id: i32,
|
// pub sell_buy_list_id: i32,
|
||||||
// pub vendor_id: i32,
|
// pub vendor_id: i32,
|
||||||
// pub vendor_gold: i32,
|
// pub vendor_gold: i32,
|
||||||
pub created_at: Option<NaiveDateTime>,
|
pub created_at: NaiveDateTime,
|
||||||
pub updated_at: Option<NaiveDateTime>,
|
pub updated_at: NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct PostedShop {
|
||||||
|
pub name: String,
|
||||||
|
pub owner_id: Option<i32>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PostedModel for PostedShop {}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Model for Shop {
|
impl Model for Shop {
|
||||||
fn resource_name() -> &'static str {
|
fn resource_name() -> &'static str {
|
||||||
"shop"
|
"shop"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pk(&self) -> Option<i32> {
|
fn pk(&self) -> i32 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,17 +51,17 @@ impl Model for Shop {
|
|||||||
.map_err(Error::new)
|
.map_err(Error::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
async fn create(self, db: &PgPool) -> Result<Self> {
|
async fn create(posted: PostedShop, db: &PgPool) -> Result<Self> {
|
||||||
Ok(sqlx::query_as!(
|
Ok(sqlx::query_as!(
|
||||||
Self,
|
Self,
|
||||||
"INSERT INTO shops
|
"INSERT INTO shops
|
||||||
(name, owner_id, description, created_at, updated_at)
|
(name, owner_id, description, created_at, updated_at)
|
||||||
VALUES ($1, $2, $3, now(), now())
|
VALUES ($1, $2, $3, now(), now())
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
self.name,
|
posted.name,
|
||||||
self.owner_id,
|
posted.owner_id,
|
||||||
self.description,
|
posted.description,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
@ -105,8 +114,8 @@ impl Model for Shop {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UpdateableModel for Shop {
|
impl UpdateableModel for Shop {
|
||||||
#[instrument(level = "debug", skip(self, db))]
|
#[instrument(level = "debug", skip(posted, db))]
|
||||||
async fn update(self, db: &PgPool, owner_id: i32, id: i32) -> Result<Self> {
|
async fn update(posted: PostedShop, db: &PgPool, owner_id: i32, id: i32) -> Result<Self> {
|
||||||
let shop = sqlx::query!("SELECT owner_id FROM shops WHERE id = $1", id)
|
let shop = sqlx::query!("SELECT owner_id FROM shops WHERE id = $1", id)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?;
|
.await?;
|
||||||
@ -121,9 +130,9 @@ impl UpdateableModel for Shop {
|
|||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING *",
|
RETURNING *",
|
||||||
id,
|
id,
|
||||||
self.name,
|
posted.name,
|
||||||
self.owner_id,
|
posted.owner_id,
|
||||||
self.description,
|
posted.description,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await?)
|
.await?)
|
||||||
|
@ -37,15 +37,16 @@ pub fn from_anyhow(error: anyhow::Error) -> HttpApiProblem {
|
|||||||
return HttpApiProblem::with_title_and_type_from_status(StatusCode::NOT_FOUND)
|
return HttpApiProblem::with_title_and_type_from_status(StatusCode::NOT_FOUND)
|
||||||
}
|
}
|
||||||
sqlx::error::Error::Database(db_error) => {
|
sqlx::error::Error::Database(db_error) => {
|
||||||
|
let pg_error = db_error.downcast_ref::<sqlx::postgres::PgDatabaseError>();
|
||||||
error!(
|
error!(
|
||||||
"Database error: {}. {}",
|
"Database error: {}. {}",
|
||||||
db_error.message(),
|
pg_error.message(),
|
||||||
db_error.details().unwrap_or("")
|
pg_error.detail().unwrap_or("")
|
||||||
);
|
);
|
||||||
dbg!(&db_error);
|
dbg!(&pg_error);
|
||||||
if let Some(code) = db_error.code() {
|
let code = pg_error.code();
|
||||||
dbg!(&code);
|
dbg!(&code);
|
||||||
if let Some(constraint) = db_error.constraint_name() {
|
if let Some(constraint) = pg_error.constraint() {
|
||||||
dbg!(&constraint);
|
dbg!(&constraint);
|
||||||
if code == "23503" && constraint == "shops_owner_id_fkey" {
|
if code == "23503" && constraint == "shops_owner_id_fkey" {
|
||||||
// foreign_key_violation
|
// foreign_key_violation
|
||||||
@ -59,15 +60,13 @@ pub fn from_anyhow(error: anyhow::Error) -> HttpApiProblem {
|
|||||||
StatusCode::BAD_REQUEST,
|
StatusCode::BAD_REQUEST,
|
||||||
)
|
)
|
||||||
.set_detail("Owner with Api-Key already exists");
|
.set_detail("Owner with Api-Key already exists");
|
||||||
} else if code == "23505" && constraint == "owners_unique_name_and_api_key"
|
} else if code == "23505" && constraint == "owners_unique_name_and_api_key" {
|
||||||
{
|
|
||||||
// unique_violation
|
// unique_violation
|
||||||
return HttpApiProblem::with_title_and_type_from_status(
|
return HttpApiProblem::with_title_and_type_from_status(
|
||||||
StatusCode::BAD_REQUEST,
|
StatusCode::BAD_REQUEST,
|
||||||
)
|
)
|
||||||
.set_detail("Duplicate owner with same name and Api-Key exists");
|
.set_detail("Duplicate owner with same name and Api-Key exists");
|
||||||
} else if code == "23505" && constraint == "shops_unique_name_and_owner_id"
|
} else if code == "23505" && constraint == "shops_unique_name_and_owner_id" {
|
||||||
{
|
|
||||||
// unique_violation
|
// unique_violation
|
||||||
return HttpApiProblem::with_title_and_type_from_status(
|
return HttpApiProblem::with_title_and_type_from_status(
|
||||||
StatusCode::BAD_REQUEST,
|
StatusCode::BAD_REQUEST,
|
||||||
@ -76,7 +75,6 @@ pub fn from_anyhow(error: anyhow::Error) -> HttpApiProblem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user