Use Julids for DbId.
First phase just does a typedef of "DbId = Julid", and confirms the plugin will load into sqlite. All tests pass. Next phase removes client-side generation of IDs.
This commit is contained in:
parent
8a23272cfe
commit
7aefedf993
10 changed files with 277 additions and 259 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/target
|
||||
/libjulid.so
|
||||
|
|
289
Cargo.lock
generated
289
Cargo.lock
generated
|
@ -234,6 +234,17 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "auto-future"
|
||||
version = "1.0.0"
|
||||
|
@ -439,6 +450,29 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.60.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"clap 3.2.25",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -520,6 +554,15 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
|
@ -545,6 +588,32 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags 1.3.2",
|
||||
"clap_lex 0.2.4",
|
||||
"indexmap 1.9.3",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.3.19"
|
||||
|
@ -564,7 +633,7 @@ checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1"
|
|||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"clap_lex 0.5.0",
|
||||
"strsim",
|
||||
"unicase",
|
||||
"unicode-width",
|
||||
|
@ -582,6 +651,15 @@ dependencies = [
|
|||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.5.0"
|
||||
|
@ -754,6 +832,19 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
|
@ -958,6 +1049,18 @@ version = "0.27.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.0"
|
||||
|
@ -974,7 +1077,7 @@ version = "0.8.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1011,6 +1114,15 @@ dependencies = [
|
|||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.2"
|
||||
|
@ -1109,6 +1221,12 @@ dependencies = [
|
|||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.27"
|
||||
|
@ -1165,6 +1283,16 @@ dependencies = [
|
|||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.0.0"
|
||||
|
@ -1172,7 +1300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1181,7 +1309,7 @@ version = "0.4.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.3.2",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
@ -1210,6 +1338,16 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "julid-rs"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"serde",
|
||||
"sqlite-loadable",
|
||||
"sqlx",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "justerror"
|
||||
version = "1.1.0"
|
||||
|
@ -1230,12 +1368,28 @@ dependencies = [
|
|||
"spin 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.7"
|
||||
|
@ -1421,7 +1575,7 @@ version = "1.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
|
@ -1454,6 +1608,12 @@ dependencies = [
|
|||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
|
@ -1500,6 +1660,12 @@ version = "1.0.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
|
@ -1743,6 +1909,12 @@ version = "0.1.23"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.4"
|
||||
|
@ -1825,18 +1997,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.175"
|
||||
version = "1.0.176"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b"
|
||||
checksum = "76dc28c9523c5d70816e393136b86d48909cfb27cecaa902d338c19ed47164dc"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.175"
|
||||
version = "1.0.176"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4"
|
||||
checksum = "a4e7b8c5dc823e3b90651ff1d3808419cd14e5ad76de04feaf37da114e7a306f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1929,6 +2101,12 @@ dependencies = [
|
|||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
|
@ -2009,6 +2187,40 @@ dependencies = [
|
|||
"unicode_categories",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlite-loadable"
|
||||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a916b7bb8738eef189dea88731b619b80bf3f62b3acf05138fa43fbf8621cc94"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlite-loadable-macros",
|
||||
"sqlite3ext-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlite-loadable-macros"
|
||||
version = "0.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98bc75a8d6fd24f6a2cfea34f28758780fa17279d3051eec926efa381971e48"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlite3ext-sys"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3afdc2b3dc08f16d6eecf8aa07d19975a268603ab1cca67d3f9b4172c507cf16"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx"
|
||||
version = "0.7.1"
|
||||
|
@ -2032,7 +2244,6 @@ dependencies = [
|
|||
"atoi",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"crc",
|
||||
"crossbeam-queue",
|
||||
"dotenvy",
|
||||
|
@ -2045,7 +2256,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"hashlink",
|
||||
"hex",
|
||||
"indexmap",
|
||||
"indexmap 2.0.0",
|
||||
"log",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
|
@ -2059,7 +2270,6 @@ dependencies = [
|
|||
"smallvec",
|
||||
"sqlformat",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tracing",
|
||||
|
@ -2098,7 +2308,6 @@ dependencies = [
|
|||
"sha2 0.10.7",
|
||||
"sqlx-core",
|
||||
"sqlx-mysql",
|
||||
"sqlx-postgres",
|
||||
"sqlx-sqlite",
|
||||
"syn 1.0.109",
|
||||
"tempfile",
|
||||
|
@ -2117,7 +2326,6 @@ dependencies = [
|
|||
"bitflags 2.3.3",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"crc",
|
||||
"digest 0.10.7",
|
||||
"dotenvy",
|
||||
|
@ -2145,7 +2353,6 @@ dependencies = [
|
|||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing",
|
||||
"whoami",
|
||||
]
|
||||
|
@ -2160,7 +2367,6 @@ dependencies = [
|
|||
"base64 0.21.2",
|
||||
"bitflags 2.3.3",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"crc",
|
||||
"dotenvy",
|
||||
"etcetera",
|
||||
|
@ -2186,7 +2392,6 @@ dependencies = [
|
|||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing",
|
||||
"whoami",
|
||||
]
|
||||
|
@ -2198,7 +2403,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"chrono",
|
||||
"flume",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -2210,7 +2414,6 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"serde",
|
||||
"sqlx-core",
|
||||
"time",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
@ -2278,6 +2481,21 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.44"
|
||||
|
@ -2528,15 +2746,6 @@ version = "1.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "ulid"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13a3aaa69b04e5b66cc27309710a569ea23593612387d67daaf102e73aa974fd"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
|
@ -2727,7 +2936,8 @@ dependencies = [
|
|||
"axum-macros",
|
||||
"axum-test",
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap 4.3.19",
|
||||
"julid-rs",
|
||||
"justerror",
|
||||
"optional_optional_user",
|
||||
"password-hash",
|
||||
|
@ -2744,10 +2954,20 @@ dependencies = [
|
|||
"tower-http",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"ulid",
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
|
||||
dependencies = [
|
||||
"either",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.4.1"
|
||||
|
@ -2770,6 +2990,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
|
|
@ -18,11 +18,13 @@ axum-login = { git = "https://github.com/nebkor/axum-login", branch = "sqlx-0.7"
|
|||
axum-macros = "0.3"
|
||||
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
|
||||
clap = { version = "4", features = ["derive", "env", "unicode", "suggestions", "usage"] }
|
||||
julid-rs = { path = "../julid" }
|
||||
justerror = "1"
|
||||
password-hash = { version = "0.5", features = ["std", "getrandom"] }
|
||||
rand = "0.8"
|
||||
rand_distr = "0.4"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
sqlx = { version = "0.7", default-features = false, features = ["runtime-tokio-rustls", "sqlite", "chrono", "time"] }
|
||||
sqlx = { version = "0.7", default-features = false, features = ["runtime-tokio-rustls", "sqlite"] }
|
||||
thiserror = "1"
|
||||
tokio = { version = "1", features = ["full", "tracing"], default-features = false }
|
||||
tokio-retry = "0.3"
|
||||
|
@ -31,9 +33,7 @@ tower = { version = "0.4", features = ["util", "timeout"], default-features = fa
|
|||
tower-http = { version = "0.4", features = ["add-extension", "trace"] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
ulid = { version = "1", features = ["rand"] }
|
||||
unicode-segmentation = "1"
|
||||
rand_distr = "0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
axum-test = "9"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
-- users
|
||||
create table if not exists users (
|
||||
id blob not null primary key,
|
||||
id blob not null primary key default (julid_new()),
|
||||
username text not null unique,
|
||||
displayname text,
|
||||
email text,
|
||||
|
@ -16,7 +16,7 @@ create table if not exists users (
|
|||
|
||||
-- table of things to watch
|
||||
create table if not exists watches (
|
||||
id blob not null primary key,
|
||||
id blob not null primary key default (julid_new()),
|
||||
kind int not null, -- enum for movie or tv show or whatev
|
||||
title text not null,
|
||||
metadata_url text, -- possible url for imdb or other metadata-esque site to show the user
|
||||
|
@ -52,7 +52,7 @@ create table if not exists follows (
|
|||
);
|
||||
|
||||
create table if not exists watch_notes (
|
||||
id blob not null primary key, -- a user can have multiple notes about the same thing
|
||||
id blob not null primary key default (julid_new()), -- a user can have multiple notes about the same thing
|
||||
user blob not null,
|
||||
watch blob not null,
|
||||
note blob,
|
||||
|
|
|
@ -12,7 +12,7 @@ use sqlx::{
|
|||
SqlitePool,
|
||||
};
|
||||
|
||||
use crate::{db_id::DbId, User};
|
||||
use crate::{DbId, User};
|
||||
|
||||
const MAX_CONNS: u32 = 200;
|
||||
const MIN_CONNS: u32 = 5;
|
||||
|
@ -49,6 +49,9 @@ pub fn get_db_pool() -> SqlitePool {
|
|||
.journal_mode(SqliteJournalMode::Wal)
|
||||
.synchronous(sqlx::sqlite::SqliteSynchronous::Normal)
|
||||
.filename(&db_filename)
|
||||
// need to build this out of band and put it in the project root; see instructions at
|
||||
// https://gitlab.com/nebkor/julid
|
||||
.extension("./libjulid")
|
||||
.busy_timeout(Duration::from_secs(TIMEOUT))
|
||||
.create_if_missing(true);
|
||||
|
||||
|
|
214
src/db_id.rs
214
src/db_id.rs
|
@ -1,214 +0,0 @@
|
|||
use std::{
|
||||
borrow::Cow,
|
||||
fmt::{Debug, Display},
|
||||
};
|
||||
|
||||
use chrono::Utc;
|
||||
use serde::{de::Visitor, Deserialize, Serialize};
|
||||
use sqlx::{
|
||||
encode::IsNull,
|
||||
sqlite::{SqliteArgumentValue, SqliteValueRef},
|
||||
Decode, Encode, Sqlite,
|
||||
};
|
||||
use ulid::Ulid;
|
||||
|
||||
#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct DbId(pub Ulid);
|
||||
|
||||
impl DbId {
|
||||
pub fn bytes(&self) -> [u8; 16] {
|
||||
self.to_be_bytes()
|
||||
}
|
||||
|
||||
pub fn to_be_bytes(self) -> [u8; 16] {
|
||||
self.0 .0.to_be_bytes()
|
||||
}
|
||||
|
||||
pub fn is_nil(&self) -> bool {
|
||||
self.0.is_nil()
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self(Ulid::new())
|
||||
}
|
||||
|
||||
pub fn from_string(s: &str) -> Result<Self, ulid::DecodeError> {
|
||||
let id = Ulid::from_string(s)?;
|
||||
Ok(id.into())
|
||||
}
|
||||
|
||||
pub fn as_string(&self) -> String {
|
||||
self.0.to_string()
|
||||
}
|
||||
|
||||
pub fn created_at(&self) -> chrono::DateTime<Utc> {
|
||||
self.0.datetime().into()
|
||||
}
|
||||
}
|
||||
|
||||
//-************************************************************************
|
||||
// standard trait impls
|
||||
//-************************************************************************
|
||||
|
||||
impl Display for DbId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for DbId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("DbId").field(&self.as_string()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ulid> for DbId {
|
||||
fn from(value: Ulid) -> Self {
|
||||
DbId(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for DbId {
|
||||
fn from(value: u128) -> Self {
|
||||
DbId(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
//-************************************************************************
|
||||
// sqlx traits for going in and out of the db
|
||||
//-************************************************************************
|
||||
|
||||
impl sqlx::Type<sqlx::Sqlite> for DbId {
|
||||
fn type_info() -> <sqlx::Sqlite as sqlx::Database>::TypeInfo {
|
||||
<&[u8] as sqlx::Type<sqlx::Sqlite>>::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for DbId {
|
||||
fn encode_by_ref(&self, args: &mut Vec<SqliteArgumentValue<'q>>) -> IsNull {
|
||||
args.push(SqliteArgumentValue::Blob(Cow::Owned(self.bytes().to_vec())));
|
||||
IsNull::No
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode<'_, Sqlite> for DbId {
|
||||
fn decode(value: SqliteValueRef<'_>) -> Result<Self, sqlx::error::BoxDynError> {
|
||||
let bytes = <&[u8] as Decode<Sqlite>>::decode(value)?;
|
||||
let bytes: [u8; 16] = bytes.try_into().unwrap_or_default();
|
||||
Ok(u128::from_be_bytes(bytes).into())
|
||||
}
|
||||
}
|
||||
|
||||
//-************************************************************************
|
||||
// serde traits
|
||||
//-************************************************************************
|
||||
impl Serialize for DbId {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_bytes(&self.bytes())
|
||||
}
|
||||
}
|
||||
|
||||
struct DbIdVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for DbIdVisitor {
|
||||
type Value = DbId;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("16 bytes")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match std::convert::TryInto::<[u8; 16]>::try_into(v) {
|
||||
Ok(v) => Ok(u128::from_be_bytes(v).into()),
|
||||
Err(_) => Err(serde::de::Error::invalid_length(v.len(), &self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
DbId::from_string(&v)
|
||||
.map_err(|_| serde::de::Error::invalid_value(serde::de::Unexpected::Str(&v), &self))
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
DbId::from_string(v)
|
||||
.map_err(|_| serde::de::Error::invalid_value(serde::de::Unexpected::Str(v), &self))
|
||||
}
|
||||
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
let len = v.len();
|
||||
match std::convert::TryInto::<[u8; 16]>::try_into(v) {
|
||||
Ok(v) => Ok(u128::from_be_bytes(v).into()),
|
||||
Err(_) => Err(serde::de::Error::invalid_length(len, &self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let mut raw_bytes_from_db = [0u8; 16];
|
||||
let size = seq.size_hint().unwrap_or(0);
|
||||
let mut count = 0;
|
||||
while let Some(val) = seq.next_element()? {
|
||||
if count > 15 {
|
||||
break;
|
||||
}
|
||||
raw_bytes_from_db[count] = val;
|
||||
count += 1;
|
||||
}
|
||||
if count != 16 || size > 16 {
|
||||
let sz = if count < 16 { count } else { size };
|
||||
Err(serde::de::Error::invalid_length(sz, &self))
|
||||
} else {
|
||||
Ok(u128::from_be_bytes(raw_bytes_from_db).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for DbId {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_bytes(DbIdVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
//-************************************************************************
|
||||
// serialization tests
|
||||
//-************************************************************************
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use serde_test::{assert_tokens, Token};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_ser_de() {
|
||||
let bytes: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
||||
let id: DbId = u128::from_be_bytes(bytes).into();
|
||||
|
||||
assert_tokens(
|
||||
&id,
|
||||
&[Token::Bytes(&[
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
])],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use sqlx::{query_scalar, SqlitePool};
|
||||
|
||||
use crate::{db_id::DbId, util::year_to_epoch, ShowKind, User, Watch, WatchQuest};
|
||||
use crate::{util::year_to_epoch, DbId, ShowKind, User, Watch, WatchQuest};
|
||||
|
||||
const USER_EXISTS_QUERY: &str = "select count(*) from users where id = $1";
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ pub mod test_utils;
|
|||
/// Some public interfaces for interacting with the database outside of the web
|
||||
/// app
|
||||
pub use db::get_db_pool;
|
||||
pub use db_id::DbId;
|
||||
pub mod import_utils;
|
||||
pub use users::User;
|
||||
pub use watches::{ShowKind, Watch, WatchQuest};
|
||||
|
@ -18,7 +17,6 @@ pub type WWRouter = axum::Router<SqlitePool>;
|
|||
|
||||
// everything else is private to the crate
|
||||
mod db;
|
||||
mod db_id;
|
||||
mod generic_handlers;
|
||||
mod login;
|
||||
mod signup;
|
||||
|
@ -32,6 +30,7 @@ use optional_optional_user::OptionalOptionalUser;
|
|||
use templates::*;
|
||||
use watches::templates::*;
|
||||
|
||||
pub type DbId = julid::Julid;
|
||||
type AuthContext = axum_login::extractors::AuthContext<DbId, User, axum_login::SqliteStore<User>>;
|
||||
|
||||
/// Returns the router to be used as a service or test object, you do you.
|
||||
|
|
|
@ -110,7 +110,7 @@ pub async fn post_create_user(
|
|||
let id = DbId::new();
|
||||
|
||||
let user = create_user(username, &displayname, &email, password, &pool, id).await?;
|
||||
let now = user.id.created_at();
|
||||
let now = user.id.timestamp();
|
||||
tracing::debug!("created {user:?} at {now:?}");
|
||||
let id = user.id.as_string();
|
||||
let location = format!("/signup_success/{id}");
|
||||
|
@ -137,7 +137,7 @@ pub async fn get_signup_success(
|
|||
|
||||
let mut resp = SignupSuccessPage(user.clone()).into_response();
|
||||
|
||||
if user.username.is_empty() || id.is_nil() {
|
||||
if user.username.is_empty() || id.is_alpha() {
|
||||
// redirect to front page if we got here without a valid user ID
|
||||
*resp.status_mut() = StatusCode::SEE_OTHER;
|
||||
resp.headers_mut().insert("Location", "/".parse().unwrap());
|
||||
|
@ -267,7 +267,8 @@ mod test {
|
|||
let server = server_with_pool(&pool).await;
|
||||
|
||||
let user = get_test_user();
|
||||
let id = user.id.0.to_string();
|
||||
let id = user.id.to_string();
|
||||
dbg!(&id);
|
||||
|
||||
let path = format!("/signup_success/{id}");
|
||||
|
||||
|
|
|
@ -8,9 +8,8 @@ use sqlx::{query, query_as, SqlitePool};
|
|||
|
||||
use super::templates::{AddNewWatchPage, GetWatchPage, SearchWatchesPage};
|
||||
use crate::{
|
||||
db_id::DbId,
|
||||
util::{empty_string_as_none, year_to_epoch},
|
||||
AuthContext, MyWatchesPage, ShowKind, Watch, WatchQuest,
|
||||
AuthContext, DbId, MyWatchesPage, ShowKind, Watch, WatchQuest,
|
||||
};
|
||||
|
||||
//-************************************************************************
|
||||
|
|
Loading…
Reference in a new issue