Rip out Diesel in favor of SQLx.

The primary benefit of this is to avoid Rocket's database integration,
which has become problematic in this codebase with the update to the
new async style. Because the async database API is actually
synchronous under the hood, this introduces some annoying lifetime
requirements that basically force us to use owned data everywhere.

The original pattern was to have a separate data layer that could
invoke queries from `self` (the db connection). By using a true async
database driver, we can get this back, because the lifetimes are once
again flexible instead of the ones forced by Rocket.
This commit is contained in:
jeff 2020-12-29 23:06:41 +00:00
parent cd4afbafe2
commit 7f4efb8122
14 changed files with 673 additions and 242 deletions

606
Cargo.lock generated
View File

@ -54,6 +54,23 @@ dependencies = [
"opaque-debug 0.3.0", "opaque-debug 0.3.0",
] ]
[[package]]
name = "ahash"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
[[package]]
name = "ahash"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75b7e6a93ecd6dbd2c225154d0fa7f86205574ecaa6c87429fb5f66ee677c44"
dependencies = [
"getrandom 0.2.0",
"lazy_static",
"version_check",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.15" version = "0.7.15"
@ -92,6 +109,15 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "atoi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "atomic" name = "atomic"
version = "0.5.0" version = "0.5.0"
@ -142,6 +168,18 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bitvec"
version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]] [[package]]
name = "blake2b_simd" name = "blake2b_simd"
version = "0.5.11" version = "0.5.11"
@ -201,6 +239,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.4.0" version = "3.4.0"
@ -225,6 +269,24 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "cargo_metadata"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83f95cf4bf0dda0ac2e65371ae7215d0dce3c187613a9dbf23aaa9374186f97a"
dependencies = [
"semver 0.11.0",
"semver-parser 0.10.0",
"serde",
"serde_json",
]
[[package]]
name = "cc"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
@ -297,6 +359,22 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "core-foundation"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
[[package]] [[package]]
name = "cpuid-bool" name = "cpuid-bool"
version = "0.1.2" version = "0.1.2"
@ -309,6 +387,35 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba"
[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
dependencies = [
"build_const",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f6cb3c7f5b8e51bc3ebb73a2327ad4abdbd119dc13223f14f961d2f38486756"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.1" version = "0.8.1"
@ -366,41 +473,6 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "diesel"
version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2de9deab977a153492a1468d1b1c0662c1cf39e5ea87d0c060ecd59ef18d8c"
dependencies = [
"byteorder",
"diesel_derives",
"libsqlite3-sys",
"r2d2",
]
[[package]]
name = "diesel-derive-enum"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "703e71c268ea2d8da9c0ab0b40d8b217179ee622209c170875d24443193a0dfb"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "diesel_derives"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.8.1" version = "0.8.1"
@ -425,6 +497,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]] [[package]]
name = "either" name = "either"
version = "1.6.1" version = "1.6.1"
@ -483,6 +561,31 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
dependencies = [
"matches",
"percent-encoding",
]
[[package]] [[package]]
name = "fsevent" name = "fsevent"
version = "0.4.0" version = "0.4.0"
@ -518,6 +621,12 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "funty"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.8" version = "0.3.8"
@ -643,6 +752,17 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1", "wasi 0.9.0+wasi-snapshot-preview1",
] ]
[[package]]
name = "getrandom"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4"
dependencies = [
"cfg-if 0.1.10",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]] [[package]]
name = "ghash" name = "ghash"
version = "0.3.0" version = "0.3.0"
@ -707,6 +827,18 @@ name = "hashbrown"
version = "0.9.1" 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 = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
dependencies = [
"ahash 0.4.7",
]
[[package]]
name = "hashlink"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d99cf782f0dc4372d26846bec3de7804ceb5df083c2d4462c0b8d2330e894fa8"
dependencies = [
"hashbrown",
]
[[package]] [[package]]
name = "heck" name = "heck"
@ -726,6 +858,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hex"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
[[package]] [[package]]
name = "hkdf" name = "hkdf"
version = "0.9.0" version = "0.9.0"
@ -809,6 +947,17 @@ dependencies = [
"want", "want",
] ]
[[package]]
name = "idna"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]] [[package]]
name = "ignore" name = "ignore"
version = "0.4.17" version = "0.4.17"
@ -896,6 +1045,15 @@ 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 = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]]
name = "js-sys"
version = "0.3.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3d7383929f7c9c7c2d0fa596f325832df98c3704f2c60553080f7127a58175"
dependencies = [
"wasm-bindgen",
]
[[package]] [[package]]
name = "kernel32-sys" name = "kernel32-sys"
version = "0.2.2" version = "0.2.2"
@ -918,6 +1076,19 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lexical-core"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if 0.1.10",
"ryu",
"static_assertions",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.80" version = "0.2.80"
@ -926,10 +1097,11 @@ checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
[[package]] [[package]]
name = "libsqlite3-sys" name = "libsqlite3-sys"
version = "0.18.0" version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e704a02bcaecd4a08b93a23f6be59d0bd79cd161e0963e9499165a0a35df7bd" checksum = "64d31059f22935e6c31830db5249ba2b7ecd54fd73a9909286f0a67aa55c2fbd"
dependencies = [ dependencies = [
"cc",
"pkg-config", "pkg-config",
"vcpkg", "vcpkg",
] ]
@ -958,6 +1130,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.3.4" version = "2.3.4"
@ -1030,6 +1208,24 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333" checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333"
[[package]]
name = "native-tls"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fcc7939b5edc4e4f86b1b4a04bb1498afaaf871b1a6691838ed06fcb48d3a3f"
dependencies = [
"lazy_static",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]] [[package]]
name = "net2" name = "net2"
version = "0.2.36" version = "0.2.36"
@ -1041,6 +1237,18 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "nom"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0"
dependencies = [
"bitvec",
"lexical-core",
"memchr",
"version_check",
]
[[package]] [[package]]
name = "notify" name = "notify"
version = "4.0.15" version = "4.0.15"
@ -1106,6 +1314,39 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl"
version = "0.10.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70"
dependencies = [
"bitflags",
"cfg-if 1.0.0",
"foreign-types",
"lazy_static",
"libc",
"openssl-sys",
]
[[package]]
name = "openssl-probe"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
[[package]]
name = "openssl-sys"
version = "0.9.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6"
dependencies = [
"autocfg",
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.11.1" version = "0.11.1"
@ -1398,15 +1639,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "r2d2" name = "radium"
version = "0.8.9" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
dependencies = [
"log",
"parking_lot",
"scheduled-thread-pool",
]
[[package]] [[package]]
name = "rand" name = "rand"
@ -1414,7 +1650,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.1.15",
"libc", "libc",
"rand_chacha", "rand_chacha",
"rand_core", "rand_core",
@ -1437,7 +1673,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.1.15",
] ]
[[package]] [[package]]
@ -1548,26 +1784,13 @@ name = "rocket_contrib"
version = "0.5.0-dev" version = "0.5.0-dev"
source = "git+https://github.com/SergioBenitez/Rocket#1f1f44f336e5a172361fc1860461bb03667b1ed2" source = "git+https://github.com/SergioBenitez/Rocket#1f1f44f336e5a172361fc1860461bb03667b1ed2"
dependencies = [ dependencies = [
"diesel",
"glob", "glob",
"log", "log",
"notify", "notify",
"r2d2",
"rocket", "rocket",
"rocket_contrib_codegen",
"serde", "serde",
"serde_json", "serde_json",
"tera", "tera",
"tokio",
]
[[package]]
name = "rocket_contrib_codegen"
version = "0.5.0-dev"
source = "git+https://github.com/SergioBenitez/Rocket#1f1f44f336e5a172361fc1860461bb03667b1ed2"
dependencies = [
"devise",
"quote",
] ]
[[package]] [[package]]
@ -1613,7 +1836,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [ dependencies = [
"semver", "semver 0.9.0",
] ]
[[package]] [[package]]
@ -1632,12 +1855,13 @@ dependencies = [
] ]
[[package]] [[package]]
name = "scheduled-thread-pool" name = "schannel"
version = "0.2.5" version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
dependencies = [ dependencies = [
"parking_lot", "lazy_static",
"winapi 0.3.9",
] ]
[[package]] [[package]]
@ -1646,13 +1870,46 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "security-framework"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "semver" name = "semver"
version = "0.9.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [ dependencies = [
"semver-parser", "semver-parser 0.7.0",
]
[[package]]
name = "semver"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser 0.10.0",
"serde",
] ]
[[package]] [[package]]
@ -1661,6 +1918,16 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "semver-parser"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e012c6c5380fb91897ba7b9261a0f565e624e869d42fe1a1d03fa0d68a083d5"
dependencies = [
"pest",
"pest_derive",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.117" version = "1.0.117"
@ -1765,6 +2032,101 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "sqlformat"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74c70f0235b9925cbb106c52af1a28b5ea4885a8b851e328b8562e257a389c2d"
dependencies = [
"lazy_static",
"maplit",
"nom",
"regex",
"unicode_categories",
]
[[package]]
name = "sqlx"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1a98f9bf17b690f026b6fec565293a995b46dfbd6293debcb654dcffd2d1b34"
dependencies = [
"sqlx-core",
"sqlx-macros",
]
[[package]]
name = "sqlx-core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36bb6a2ca3345a86493bc3b71eabc2c6c16a8bb1aa476cf5303bee27f67627d7"
dependencies = [
"ahash 0.6.2",
"atoi",
"bitflags",
"byteorder",
"bytes",
"crc",
"crossbeam-channel",
"crossbeam-queue",
"crossbeam-utils",
"either",
"futures-channel",
"futures-core",
"futures-util",
"hashlink",
"hex",
"itoa",
"libc",
"libsqlite3-sys",
"log",
"memchr",
"once_cell",
"parking_lot",
"percent-encoding",
"sha2",
"smallvec",
"sqlformat",
"sqlx-rt",
"stringprep",
"thiserror",
"url",
"whoami",
]
[[package]]
name = "sqlx-macros"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b5ada8b3b565331275ce913368565a273a74faf2a34da58c4dc010ce3286844"
dependencies = [
"cargo_metadata",
"dotenv",
"either",
"futures",
"heck",
"lazy_static",
"proc-macro2",
"quote",
"sha2",
"sqlx-core",
"sqlx-rt",
"syn",
"url",
]
[[package]]
name = "sqlx-rt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63fc5454c9dd7aaea3a0eeeb65ca40d06d0d8e7413a8184f7c3a3ffa5056190b"
dependencies = [
"native-tls",
"once_cell",
"tokio",
"tokio-native-tls",
]
[[package]] [[package]]
name = "standback" name = "standback"
version = "0.2.13" version = "0.2.13"
@ -1780,6 +2142,12 @@ 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 = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483" checksum = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "stdweb" name = "stdweb"
version = "0.4.20" version = "0.4.20"
@ -1829,6 +2197,16 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
[[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]] [[package]]
name = "strum" name = "strum"
version = "0.20.0" version = "0.20.0"
@ -1867,6 +2245,12 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "tap"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.1.0" version = "3.1.0"
@ -1885,8 +2269,6 @@ dependencies = [
name = "tenebrous-sheets" name = "tenebrous-sheets"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"diesel",
"diesel-derive-enum",
"erased-serde", "erased-serde",
"futures", "futures",
"log", "log",
@ -1899,6 +2281,7 @@ dependencies = [
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"sqlx",
"strum", "strum",
"thiserror", "thiserror",
] ]
@ -2003,6 +2386,21 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tinyvec"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "0.2.24" version = "0.2.24"
@ -2037,6 +2435,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-util" name = "tokio-util"
version = "0.3.1" version = "0.3.1"
@ -2183,6 +2591,24 @@ dependencies = [
"unic-common", "unic-common",
] ]
[[package]]
name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
dependencies = [
"matches",
]
[[package]]
name = "unicode-normalization"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606"
dependencies = [
"tinyvec",
]
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.7.1" version = "1.7.1"
@ -2195,6 +2621,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "unicode_categories"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]] [[package]]
name = "universal-hash" name = "universal-hash"
version = "0.4.0" version = "0.4.0"
@ -2205,6 +2637,18 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "url"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
dependencies = [
"form_urlencoded",
"idna",
"matches",
"percent-encoding",
]
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.10" version = "0.2.10"
@ -2304,6 +2748,16 @@ version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158" checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158"
[[package]]
name = "web-sys"
version = "0.3.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "222b1ef9334f92a21d3fb53dc3fd80f30836959a90f9274a626d7e06315ba3c3"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "which" name = "which"
version = "3.1.1" version = "3.1.1"
@ -2313,6 +2767,16 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "whoami"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e35495e7faf4c657051a8e9725d9c37ac57879e915be3ed55bb401af84382035"
dependencies = [
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.2.8" version = "0.2.8"
@ -2366,6 +2830,12 @@ dependencies = [
"winapi-build", "winapi-build",
] ]
[[package]]
name = "wyz"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
[[package]] [[package]]
name = "yansi" name = "yansi"
version = "0.5.0" version = "0.5.0"

View File

@ -14,14 +14,13 @@ serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "1.0" serde_json = "1.0"
erased-serde = "0.3" erased-serde = "0.3"
diesel = "1.4"
diesel-derive-enum = { version = "1", features = ["sqlite"] }
thiserror = "1.0" thiserror = "1.0"
rust-argon2 = "0.8" rust-argon2 = "0.8"
log = "0.4" log = "0.4"
rand = "0.7" rand = "0.7"
futures = "0.3" futures = "0.3"
strum = { version = "0.20", features = ["derive"] } strum = { version = "0.20", features = ["derive"] }
sqlx = { version = "0.4.2", features = [ "sqlite", "runtime-tokio-native-tls" ] }
[dependencies.rocket] [dependencies.rocket]
git = "https://github.com/SergioBenitez/Rocket" git = "https://github.com/SergioBenitez/Rocket"
@ -32,4 +31,4 @@ features = ["secrets"]
git = "https://github.com/SergioBenitez/Rocket" git = "https://github.com/SergioBenitez/Rocket"
branch = "master" branch = "master"
default-features = false default-features = false
features = [ "tera_templates", "diesel_sqlite_pool", "serve" ] features = [ "tera_templates", "serve" ]

175
src/db.rs
View File

@ -1,120 +1,119 @@
use crate::models::characters::{Character, NewCharacter, StrippedCharacter}; use crate::errors::Error;
use crate::models::characters::{Character, CharacterDataType, NewCharacter, StrippedCharacter};
use crate::models::users::{NewUser, User}; use crate::models::users::{NewUser, User};
use crate::schema::characters; use sqlx::database::HasValueRef;
use diesel::prelude::*; use sqlx::sqlite::{SqlitePool, SqlitePoolOptions};
use rocket_contrib::databases::diesel; use sqlx::Decode;
#[database("tenebrous_db")] pub type TenebrousDbConn<'a> = rocket::State<'a, SqlitePool>;
pub(crate) struct TenebrousDbConn(SqliteConnection);
pub(crate) async fn create_pool() -> Result<SqlitePool, crate::errors::Error> {
SqlitePoolOptions::new()
.max_connections(5)
.connect("tenebrous.sqlite")
.await
.map_err(|e| e.into())
}
#[rocket::async_trait] #[rocket::async_trait]
pub(crate) trait Dao { pub(crate) trait Dao {
async fn load_user_by_id(&self, id: i32) -> QueryResult<Option<User>>; async fn load_user_by_id(&self, id: i32) -> Result<Option<User>, Error>;
async fn load_user(&self, for_username: String) -> QueryResult<Option<User>>; async fn load_user(&self, for_username: &str) -> Result<Option<User>, Error>;
async fn insert_user(&self, new_user: NewUser) -> QueryResult<User>; async fn insert_user(&self, new_user: NewUser<'_>) -> Result<User, Error>;
async fn load_character_list(&self, for_user_id: i32) -> QueryResult<Vec<StrippedCharacter>>; async fn load_character_list(&self, for_user_id: i32) -> Result<Vec<StrippedCharacter>, Error>;
async fn load_character(&self, character_id: i32) -> QueryResult<Option<Character>>; async fn load_character(&self, character_id: i32) -> Result<Option<Character>, Error>;
async fn insert_character(&self, new_character: NewCharacter) -> QueryResult<()>; async fn insert_character(&self, new_character: NewCharacter<'_>) -> Result<(), Error>;
async fn update_character_sheet(&self, character: Character) -> QueryResult<()>; async fn update_character_sheet<'a>(&self, character: &'a Character) -> Result<(), Error>;
} }
type StrippedCharacterColumns = ( //TODO is:
characters::id, // - reimplement all methods
characters::user_id, // - remove owned data
characters::viewable, // - return sqlx result so we don't have .into() calls everywhere
characters::character_name, // - use compile time queries
characters::data_type, // - find replacement for diesel migrations
characters::data_version,
);
const STRIPPED_CHARACTER_COLUMNS: StrippedCharacterColumns = (
characters::id,
characters::user_id,
characters::viewable,
characters::character_name,
characters::data_type,
characters::data_version,
);
#[rocket::async_trait] #[rocket::async_trait]
impl Dao for TenebrousDbConn { impl Dao for SqlitePool {
async fn load_user_by_id(&self, user_id: i32) -> QueryResult<Option<User>> { async fn load_user_by_id(&self, user_id: i32) -> Result<Option<User>, Error> {
use crate::schema::users::dsl::*; sqlx::query_as::<_, User>("SELECT * FROM users WHERE id = ?")
self.run(move |conn| users.filter(id.eq(user_id)).first(conn).optional()) .bind(user_id)
.fetch_optional(self)
.await .await
.map_err(|e| e.into())
} }
async fn load_user(&self, for_username: String) -> QueryResult<Option<User>> { async fn load_user(&self, for_username: &str) -> Result<Option<User>, Error> {
use crate::schema::users::dsl::*; sqlx::query_as::<_, User>("SELECT * FROM users WHERE username = ?")
.bind(for_username)
.fetch_optional(self)
.await
.map_err(|e| e.into())
}
self.run(move |conn| { async fn insert_user(&self, new_user: NewUser<'_>) -> Result<User, Error> {
users sqlx::query("INSERT INTO users (username, password) values (?, ?)")
.filter(username.eq(for_username)) .bind(new_user.username)
.first(conn) .bind(new_user.password)
.optional() .execute(self)
}) .await?;
self.load_user(new_user.username)
.await
.and_then(|user| user.ok_or(Error::NotFound))
}
async fn load_character_list(&self, for_user_id: i32) -> Result<Vec<StrippedCharacter>, Error> {
sqlx::query_as::<_, StrippedCharacter>(
"SELECT id, user_id, viewable, character_name, data_type, data_version
FROM characters WHERE user_id = ?",
)
.bind(for_user_id)
.fetch_all(self)
.await .await
.map_err(|e| e.into())
} }
async fn insert_user(&self, new_user: NewUser) -> QueryResult<User> { async fn load_character(&self, character_id: i32) -> Result<Option<Character>, Error> {
self.run(move |conn| { sqlx::query_as::<_, Character>(
diesel::insert_into(users).values(&new_user).execute(conn)?; "SELECT id, user_id, viewable, character_name, data_type, data_version, data
FROM characters WHERE id = ?",
use crate::schema::users::dsl::*; )
users.filter(username.eq(new_user.username)).first(conn) .bind(character_id)
}) .fetch_optional(self)
.await .await
.map_err(|e| e.into())
} }
async fn load_character_list(&self, for_user_id: i32) -> QueryResult<Vec<StrippedCharacter>> { async fn insert_character(&self, new_character: NewCharacter<'_>) -> Result<(), Error> {
use crate::schema::characters::dsl::*; sqlx::query(
"INSERT INTO characters
self.run(move |conn| { (user_id, viewable, character_name, data_type, data_version, data)
characters values (?, ?, ?, ?, ?, ?)",
.filter(user_id.eq(for_user_id)) )
.select(STRIPPED_CHARACTER_COLUMNS) .bind(new_character.user_id)
.load(conn) .bind(new_character.viewable)
}) .bind(new_character.character_name)
.await .bind(new_character.data_type)
} .bind(new_character.data_version)
.bind(new_character.data)
async fn load_character(&self, character_id: i32) -> QueryResult<Option<Character>> { .execute(self)
use crate::schema::characters::dsl::*;
self.run(move |conn| {
characters
.filter(id.eq(character_id))
.first(conn)
.optional()
})
.await
}
async fn insert_character(&self, new_character: NewCharacter) -> QueryResult<()> {
self.run(|conn| {
diesel::insert_into(characters::table)
.values(new_character)
.execute(conn)
})
.await?; .await?;
Ok(()) Ok(())
} }
async fn update_character_sheet(&self, character: Character) -> QueryResult<()> { async fn update_character_sheet<'a>(&self, character: &'a Character) -> Result<(), Error> {
use crate::schema::characters::dsl::*; sqlx::query("UPDATE characters set data = ? where id = ?")
self.run(move |conn| { .bind(&character.data)
diesel::update(&character) .bind(character.id)
.set(data.eq(&character.data)) .execute(self)
.execute(conn) .await?;
})
.await?;
Ok(()) Ok(())
} }

View File

@ -20,9 +20,6 @@ pub enum Error {
#[error("invalid input")] #[error("invalid input")]
InvalidInput, InvalidInput,
#[error("query error: {0}")]
QueryError(#[from] diesel::result::Error),
#[error("serialization error: {0}")] #[error("serialization error: {0}")]
SerializationError(#[from] prost::EncodeError), SerializationError(#[from] prost::EncodeError),
@ -31,6 +28,12 @@ pub enum Error {
#[error("i/o error: {0}")] #[error("i/o error: {0}")]
IoError(#[from] std::io::Error), IoError(#[from] std::io::Error),
#[error("query error: {0}")]
QueryError(#[from] sqlx::Error),
#[error("rocket error: {0}")]
RocketError(#[from] rocket::error::Error),
} }
impl Error { impl Error {

View File

@ -4,9 +4,6 @@ extern crate rocket;
#[macro_use] #[macro_use]
extern crate rocket_contrib; extern crate rocket_contrib;
#[macro_use]
extern crate diesel;
// Seemingly necessary to get serde::Serialize into scope for Prost // Seemingly necessary to get serde::Serialize into scope for Prost
// code generation. // code generation.
#[macro_use] #[macro_use]
@ -20,10 +17,9 @@ pub mod db;
pub mod errors; pub mod errors;
pub mod models; pub mod models;
pub mod routes; pub mod routes;
pub mod schema;
#[rocket::main] #[rocket::main]
async fn main() -> Result<(), rocket::error::Error> { async fn main() -> Result<(), crate::errors::Error> {
let root_routes: Vec<rocket::Route> = { let root_routes: Vec<rocket::Route> = {
routes::root::routes() routes::root::routes()
.into_iter() .into_iter()
@ -37,7 +33,8 @@ async fn main() -> Result<(), rocket::error::Error> {
rocket::ignite() rocket::ignite()
.attach(Template::fairing()) .attach(Template::fairing())
.attach(db::TenebrousDbConn::fairing()) //.attach(db::TenebrousDbConn::fairing())
.manage(crate::db::create_pool().await?)
.mount("/", root_routes) .mount("/", root_routes)
.mount("/characters", character_routes) .mount("/characters", character_routes)
.mount("/api", api_routes) .mount("/api", api_routes)
@ -52,4 +49,5 @@ async fn main() -> Result<(), rocket::error::Error> {
.register(catchers) .register(catchers)
.launch() .launch()
.await .await
.map_err(|e| e.into())
} }

View File

@ -1,8 +1,6 @@
use crate::errors::Error; use crate::errors::Error;
use crate::models::proto::cofd::*; use crate::models::proto::cofd::*;
use crate::models::users::User; use crate::models::users::User;
use crate::schema::characters;
use diesel_derive_enum::DbEnum;
use prost::bytes::BytesMut; use prost::bytes::BytesMut;
use serde_derive::Serialize; use serde_derive::Serialize;
use strum::{EnumIter, EnumString}; use strum::{EnumIter, EnumString};
@ -41,7 +39,8 @@ pub(crate) trait Visibility {
} }
} }
#[derive(DbEnum, Debug, Serialize, PartialEq, Clone, Copy, EnumIter, EnumString)] #[derive(Debug, Serialize, PartialEq, Clone, Copy, EnumIter, EnumString, sqlx::Type)]
#[sqlx(rename_all = "snake_case")]
pub enum CharacterDataType { pub enum CharacterDataType {
ChroniclesOfDarknessV1, ChroniclesOfDarknessV1,
ChangelingV1, ChangelingV1,
@ -73,7 +72,7 @@ impl CharacterDataType {
/// An entry that appears in a user's character list. Properties are /// An entry that appears in a user's character list. Properties are
/// in order of table columns. /// in order of table columns.
#[derive(Serialize, Debug, Queryable, Identifiable, AsChangeset)] #[derive(Serialize, Debug, sqlx::FromRow)]
pub struct Character { pub struct Character {
pub id: i32, pub id: i32,
pub user_id: i32, pub user_id: i32,
@ -145,7 +144,7 @@ impl Character {
/// Same as regular character type, but without the actual protobuf /// Same as regular character type, but without the actual protobuf
/// data loaded into memory. /// data loaded into memory.
#[derive(Serialize, Debug, Queryable)] #[derive(Serialize, Debug, sqlx::FromRow)]
pub struct StrippedCharacter { pub struct StrippedCharacter {
pub id: i32, pub id: i32,
pub user_id: i32, pub user_id: i32,
@ -167,13 +166,11 @@ impl Visibility for StrippedCharacter {
/// Represents insert of a new character into the database. Property /// Represents insert of a new character into the database. Property
/// names correspond to columns. /// names correspond to columns.
#[derive(Insertable)] pub struct NewCharacter<'a> {
#[table_name = "characters"]
pub struct NewCharacter {
pub user_id: i32, pub user_id: i32,
pub viewable: bool, pub viewable: bool,
pub character_name: String, pub character_name: &'a str,
pub data_type: CharacterDataType, pub data_type: CharacterDataType,
pub data_version: i32, pub data_version: i32,
pub data: Vec<u8>, pub data: &'a [u8],
} }

View File

@ -1,5 +1,4 @@
use crate::db::{Dao, TenebrousDbConn}; use crate::db::{Dao, TenebrousDbConn};
use crate::schema::users;
use argon2::{self, Config, Error as ArgonError}; use argon2::{self, Config, Error as ArgonError};
use rand::Rng; use rand::Rng;
use rocket::outcome::IntoOutcome; use rocket::outcome::IntoOutcome;
@ -12,7 +11,7 @@ pub(crate) fn hash_password(raw_password: &str) -> Result<String, ArgonError> {
argon2::hash_encoded(raw_password.as_bytes(), &salt, &config) argon2::hash_encoded(raw_password.as_bytes(), &salt, &config)
} }
#[derive(Eq, PartialEq, Serialize, Debug, Queryable)] #[derive(Eq, PartialEq, Serialize, Debug, sqlx::FromRow)]
pub struct User { pub struct User {
pub id: i32, pub id: i32,
pub username: String, pub username: String,
@ -25,10 +24,11 @@ impl User {
} }
} }
async fn attempt_load_user<'a>(db: &'a TenebrousDbConn, id: i32) -> Option<User> { async fn attempt_load_user<'a>(db: &'a TenebrousDbConn<'a>, id: i32) -> Option<User> {
db.load_user_by_id(id).await.ok().flatten() db.load_user_by_id(id).await.ok().flatten()
} }
/// Trait implementation to get the logged in user.
#[rocket::async_trait] #[rocket::async_trait]
impl<'a, 'r> FromRequest<'a, 'r> for &'a User { impl<'a, 'r> FromRequest<'a, 'r> for &'a User {
type Error = (); type Error = ();
@ -53,9 +53,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a User {
} }
} }
#[derive(Insertable)] pub struct NewUser<'a> {
#[table_name = "users"] pub username: &'a str,
pub struct NewUser { pub password: &'a str,
pub username: String,
pub password: String,
} }

View File

@ -24,13 +24,13 @@ pub(crate) fn routes() -> Vec<rocket::Route> {
/// logged in, the owner of the character is not found, or the logged /// logged in, the owner of the character is not found, or the logged
/// in user does not have the permission to access this character. /// in user does not have the permission to access this character.
async fn load_character( async fn load_character(
conn: &TenebrousDbConn, conn: &TenebrousDbConn<'_>,
logged_in_user: Option<&User>, logged_in_user: Option<&User>,
owner: String, owner: String,
character_id: i32, character_id: i32,
) -> Result<Character, Error> { ) -> Result<Character, Error> {
let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?; let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?;
let owner = conn.load_user(owner).await?.ok_or(Error::NotFound)?; let owner = conn.load_user(&owner).await?.ok_or(Error::NotFound)?;
let character: Character = conn let character: Character = conn
.load_character(character_id) .load_character(character_id)
.await? .await?
@ -71,7 +71,7 @@ mod cofd {
owner: String, owner: String,
character_id: i32, character_id: i32,
attr_update: Proto<Attribute>, attr_update: Proto<Attribute>,
conn: TenebrousDbConn, conn: TenebrousDbConn<'_>,
logged_in_user: Option<&User>, logged_in_user: Option<&User>,
) -> Result<&'a str, Error> { ) -> Result<&'a str, Error> {
let mut character = load_character(&conn, logged_in_user, owner, character_id).await?; let mut character = load_character(&conn, logged_in_user, owner, character_id).await?;
@ -96,7 +96,7 @@ mod cofd {
); );
character.update_data(sheet)?; character.update_data(sheet)?;
conn.update_character_sheet(character).await?; conn.update_character_sheet(&character).await?;
Ok("lol") Ok("lol")
} }
@ -105,7 +105,7 @@ mod cofd {
owner: String, owner: String,
character_id: i32, character_id: i32,
info: Proto<Skills>, info: Proto<Skills>,
conn: TenebrousDbConn, conn: TenebrousDbConn<'_>,
) -> &'a str { ) -> &'a str {
"lol" "lol"
} }

View File

@ -50,10 +50,10 @@ fn registration_error_redirect<S: AsRef<str>>(message: S) -> Flash<Redirect> {
async fn login( async fn login(
cookies: &CookieJar<'_>, cookies: &CookieJar<'_>,
login: Form<Login>, login: Form<Login>,
conn: TenebrousDbConn, conn: TenebrousDbConn<'_>,
) -> Result<Redirect, Flash<Redirect>> { ) -> Result<Redirect, Flash<Redirect>> {
let user = conn let user = conn
.load_user(login.username.clone()) .load_user(&login.username)
.await .await
.map_err(|e| { .map_err(|e| {
error!("login - error loading user user: {}", e); error!("login - error loading user user: {}", e);
@ -104,15 +104,12 @@ fn register_page(flash: Option<FlashMessage>) -> Template {
async fn register( async fn register(
mut cookies: &CookieJar<'_>, mut cookies: &CookieJar<'_>,
registration: Form<Registration>, registration: Form<Registration>,
conn: TenebrousDbConn, conn: TenebrousDbConn<'_>,
) -> Result<Redirect, Flash<Redirect>> { ) -> Result<Redirect, Flash<Redirect>> {
let existing_user = conn let existing_user = conn.load_user(&registration.username).await.map_err(|e| {
.load_user(registration.username.clone()) error!("registration - error loading existing user: {}", e);
.await registration_error_redirect("There was an error attempting to register.")
.map_err(|e| { })?;
error!("registration - error loading existing user: {}", e);
registration_error_redirect("There was an error attempting to register.")
})?;
if existing_user.is_some() { if existing_user.is_some() {
return Err(registration_error_redirect(format!( return Err(registration_error_redirect(format!(
@ -127,8 +124,8 @@ async fn register(
})?; })?;
let user = NewUser { let user = NewUser {
username: registration.username.clone(), username: &registration.username,
password: hashed_pw, password: &hashed_pw,
}; };
let user = conn.insert_user(user).await.map_err(|e| { let user = conn.insert_user(user).await.map_err(|e| {

View File

@ -50,10 +50,10 @@ fn view_character_template(user: &User, character: Character) -> Result<Template
async fn view_character( async fn view_character(
character_id: i32, character_id: i32,
username: String, username: String,
conn: TenebrousDbConn, conn: TenebrousDbConn<'_>,
logged_in_user: Option<&User>, logged_in_user: Option<&User>,
) -> Result<Template, Error> { ) -> Result<Template, Error> {
let user = &conn.load_user(username).await?.ok_or(Error::NotFound)?; let user = &conn.load_user(&username).await?.ok_or(Error::NotFound)?;
let character = conn let character = conn
.load_character(character_id) .load_character(character_id)

View File

@ -25,9 +25,9 @@ pub(super) async fn edit_character_page(
character_id: i32, character_id: i32,
owner: String, owner: String,
logged_in_user: Option<&User>, logged_in_user: Option<&User>,
conn: TenebrousDbConn, conn: TenebrousDbConn<'_>,
) -> Result<Template, Error> { ) -> Result<Template, Error> {
let owner = conn.load_user(owner).await?.ok_or(Error::NotFound)?; let owner = conn.load_user(&owner).await?.ok_or(Error::NotFound)?;
let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?; let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?;
let character = conn let character = conn

View File

@ -59,7 +59,7 @@ impl NewCharacterContext {
async fn create_new_character( async fn create_new_character(
form: &Form<NewCharacterForm>, form: &Form<NewCharacterForm>,
user_id: i32, user_id: i32,
conn: TenebrousDbConn, conn: TenebrousDbConn<'_>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let system: CharacterDataType = *form.system.as_ref().unwrap(); let system: CharacterDataType = *form.system.as_ref().unwrap();
let sheet: Vec<u8> = system.create_data()?.to_vec(); let sheet: Vec<u8> = system.create_data()?.to_vec();
@ -67,10 +67,10 @@ async fn create_new_character(
let insert = NewCharacter { let insert = NewCharacter {
user_id: user_id, user_id: user_id,
viewable: true, viewable: true,
character_name: form.name.clone(), character_name: &form.name,
data_type: system, data_type: system,
data_version: 1, data_version: 1,
data: sheet, data: &sheet,
}; };
conn.insert_character(insert).await?; conn.insert_character(insert).await?;
@ -97,7 +97,7 @@ pub(super) fn new_character_page(_logged_in_user: &User) -> Result<Template, Err
pub(super) async fn new_character_submit( pub(super) async fn new_character_submit(
form: Form<NewCharacterForm>, form: Form<NewCharacterForm>,
logged_in_user: &User, logged_in_user: &User,
conn: TenebrousDbConn, conn: TenebrousDbConn<'_>,
) -> Result<Redirect, Template> { ) -> Result<Redirect, Template> {
if let Err(e) = &form.system { if let Err(e) = &form.system {
return Err(render_error(&form, e.to_string().clone())); return Err(render_error(&form, e.to_string().clone()));

View File

@ -18,7 +18,7 @@ pub struct UserHomeContext<'a> {
} }
#[get("/")] #[get("/")]
async fn user_index(user: &User, conn: TenebrousDbConn) -> Result<Template, Error> { async fn user_index(user: &User, conn: TenebrousDbConn<'_>) -> Result<Template, Error> {
let characters: Vec<StrippedCharacter> = conn let characters: Vec<StrippedCharacter> = conn
.load_character_list(user.id) .load_character_list(user.id)
.await? .await?

View File

@ -1,30 +0,0 @@
table! {
use diesel::sql_types::*;
use crate::models::characters::*;
characters (id) {
id -> Integer,
user_id -> Integer,
viewable -> Bool,
character_name -> Text,
data_type -> CharacterDataTypeMapping,
data_version -> Integer,
data -> Binary,
}
}
table! {
use diesel::sql_types::*;
use crate::models::characters::*;
users (id) {
id -> Integer,
username -> Text,
password -> Text,
}
}
allow_tables_to_appear_in_same_query!(
characters,
users,
);