forked from projectmoon/tenebrous-dicebot
Initial SQLx implementation (variables). not yet wired up to bot.
- Adds migrations for the necessary tables. - Implements the user variables database functions. - Adds sqlx metadata for 'offline' use so we can build without a database.
This commit is contained in:
parent
b1972e2850
commit
6b6e59da2e
|
@ -0,0 +1,2 @@
|
||||||
|
DATABASE_URL="sqlite://test-db/dicebot.sqlite"
|
||||||
|
SQLX_OFFLINE="true"
|
|
@ -10,3 +10,4 @@ bot-db*
|
||||||
# We store a disabled async test in this file
|
# We store a disabled async test in this file
|
||||||
bigboy
|
bigboy
|
||||||
.#*
|
.#*
|
||||||
|
*.sqlite
|
||||||
|
|
|
@ -66,6 +66,23 @@ dependencies = [
|
||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "796540673305a66d127804eef19ad696f1f204b8c1025aaca4958c17eab32877"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.2",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.18"
|
version = "0.7.18"
|
||||||
|
@ -98,6 +115,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"
|
||||||
|
@ -138,6 +164,12 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "barrel"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d67c978b1322c8031145b1f6c236fc371292f52c565bc96018b2971afcbffe1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base-x"
|
name = "base-x"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
|
@ -165,6 +197,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.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
|
||||||
|
dependencies = [
|
||||||
|
"funty",
|
||||||
|
"radium",
|
||||||
|
"tap",
|
||||||
|
"wyz",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -174,6 +218,12 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "build_const"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.6.1"
|
version = "3.6.1"
|
||||||
|
@ -227,6 +277,19 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
"time 0.1.43",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cipher"
|
name = "cipher"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
|
@ -292,6 +355,15 @@ 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]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -301,6 +373,16 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
@ -314,6 +396,16 @@ dependencies = [
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f6cb3c7f5b8e51bc3ebb73a2327ad4abdbd119dc13223f14f961d2f38486756"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
|
@ -389,11 +481,20 @@ 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"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
|
@ -417,6 +518,18 @@ dependencies = [
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-iterator"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-streaming-iterator"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -458,6 +571,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "funty"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futf"
|
name = "futf"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
@ -671,6 +790,27 @@ 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]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
|
@ -681,6 +821,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
|
@ -901,6 +1047,17 @@ version = "0.2.94"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libsqlite3-sys"
|
||||||
|
version = "0.20.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64d31059f22935e6c31830db5249ba2b7ecd54fd73a9909286f0a67aa55c2fbd"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
@ -1136,6 +1293,19 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "6.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
|
||||||
|
dependencies = [
|
||||||
|
"bitvec",
|
||||||
|
"funty",
|
||||||
|
"lexical-core",
|
||||||
|
"memchr",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ntapi"
|
name = "ntapi"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
|
@ -1145,6 +1315,25 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
@ -1433,6 +1622,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radium"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
|
@ -1543,6 +1738,50 @@ dependencies = [
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "refinery"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e29bd9c881127d714f4b5b9fdd9ea7651f3dd254922e959a10f6ada620e841da"
|
||||||
|
dependencies = [
|
||||||
|
"refinery-core",
|
||||||
|
"refinery-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "refinery-core"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53260bc01535ea10c553ce0fc410609ba2dc0a9f4c9b4503e0af842dd4a6f89d"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"cfg-if",
|
||||||
|
"chrono",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"rusqlite",
|
||||||
|
"serde",
|
||||||
|
"siphasher",
|
||||||
|
"thiserror",
|
||||||
|
"toml",
|
||||||
|
"url",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "refinery-macros"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a79ff62c9b674b62c06a09cc8becf06cbafba9952afa1d8174e7e15f2c4ed43"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"refinery-core",
|
||||||
|
"regex",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.4"
|
version = "1.5.4"
|
||||||
|
@ -1775,6 +2014,21 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusqlite"
|
||||||
|
version = "0.24.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d5f38ee71cbab2c827ec0ac24e76f82eca723cee92c509a65f67dee393c25112"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"fallible-iterator",
|
||||||
|
"fallible-streaming-iterator",
|
||||||
|
"hashlink",
|
||||||
|
"libsqlite3-sys",
|
||||||
|
"memchr",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -1790,6 +2044,15 @@ version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schannel"
|
name = "schannel"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
@ -1876,6 +2139,7 @@ version = "1.0.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1965,6 +2229,105 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlformat"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d86e3c77ff882a828346ba401a7ef4b8e440df804491c6064fe8295765de71c"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"maplit",
|
||||||
|
"nom 6.1.2",
|
||||||
|
"regex",
|
||||||
|
"unicode_categories",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2739d54a2ae9fdd0f545cb4e4b5574efb95e2ec71b7f921678e246fb20dcaaf"
|
||||||
|
dependencies = [
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-core"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1cad9cae4ca8947eba1a90e8ec7d3c59e7a768e2f120dc9013b669c34a90711"
|
||||||
|
dependencies = [
|
||||||
|
"ahash 0.6.3",
|
||||||
|
"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",
|
||||||
|
"serde",
|
||||||
|
"sha2",
|
||||||
|
"smallvec",
|
||||||
|
"sqlformat",
|
||||||
|
"sqlx-rt",
|
||||||
|
"stringprep",
|
||||||
|
"thiserror",
|
||||||
|
"tokio-stream",
|
||||||
|
"url",
|
||||||
|
"whoami",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-macros"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "01caee2b3935b4efe152f3262afbe51546ce3b1fc27ad61014e1b3cf5f55366e"
|
||||||
|
dependencies = [
|
||||||
|
"dotenv",
|
||||||
|
"either",
|
||||||
|
"futures",
|
||||||
|
"heck",
|
||||||
|
"hex",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-rt",
|
||||||
|
"syn",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-rt"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ce2e16b6774c671cc183e1d202386fdf9cde1e8468c1894a7f2a63eb671c4f4"
|
||||||
|
dependencies = [
|
||||||
|
"native-tls",
|
||||||
|
"once_cell",
|
||||||
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "standback"
|
name = "standback"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
@ -2054,6 +2417,16 @@ dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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 = "subtle"
|
name = "subtle"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
|
@ -2083,6 +2456,12 @@ dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tap"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.2.0"
|
version = "3.2.0"
|
||||||
|
@ -2113,6 +2492,7 @@ name = "tenebrous-dicebot"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"barrel",
|
||||||
"bincode",
|
"bincode",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"combine",
|
"combine",
|
||||||
|
@ -2125,11 +2505,13 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"matrix-sdk",
|
"matrix-sdk",
|
||||||
"memmem",
|
"memmem",
|
||||||
"nom",
|
"nom 5.1.2",
|
||||||
"phf",
|
"phf",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
|
"refinery",
|
||||||
"serde",
|
"serde",
|
||||||
"sled",
|
"sled",
|
||||||
|
"sqlx",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
|
@ -2270,6 +2652,17 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-stream"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8864d706fdb3cc0843a49647ac892720dac98a6eeb818b77190592cf4994066"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.6.7"
|
version = "0.6.7"
|
||||||
|
@ -2371,6 +2764,12 @@ dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
|
@ -2383,6 +2782,12 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode_categories"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unindent"
|
name = "unindent"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
@ -2439,6 +2844,17 @@ version = "0.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||||
|
dependencies = [
|
||||||
|
"same-file",
|
||||||
|
"winapi",
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "want"
|
name = "want"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -2539,6 +2955,16 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "whoami"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4abacf325c958dfeaf1046931d37f2a901b6dfe0968ee965a29e94c6766b2af6"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wildmatch"
|
name = "wildmatch"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
@ -2585,6 +3011,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wyz"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xml5ever"
|
name = "xml5ever"
|
||||||
version = "0.16.1"
|
version = "0.16.1"
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -10,6 +10,10 @@ repository = 'https://git.agnos.is/projectmoon/matrix-dicebot'
|
||||||
keywords = ["games", "dice", "matrix", "bot"]
|
keywords = ["games", "dice", "matrix", "bot"]
|
||||||
categories = ["games"]
|
categories = ["games"]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "dicebot-migrate"
|
||||||
|
path = "src/migrate_cli.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
|
@ -32,6 +36,12 @@ bincode = "1.3"
|
||||||
html2text = "0.2"
|
html2text = "0.2"
|
||||||
phf = { version = "0.8", features = ["macros"] }
|
phf = { version = "0.8", features = ["macros"] }
|
||||||
matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk", branch = "master" }
|
matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk", branch = "master" }
|
||||||
|
refinery = { version = "0.5", features = ["rusqlite"]}
|
||||||
|
barrel = { version = "0.6", features = ["sqlite3"] }
|
||||||
|
|
||||||
|
[dependencies.sqlx]
|
||||||
|
version = "0.5"
|
||||||
|
features = [ "offline", "sqlite", "runtime-tokio-native-tls" ]
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1"
|
version = "1"
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"db": "SQLite",
|
||||||
|
"636b1b868eaf04cd234fbf17747d94a66e81f7bc1b060ba14151dbfaf40eeefc": {
|
||||||
|
"query": "SELECT value as \"value: i32\" FROM user_variables\n WHERE user_id = ? AND room_id = ? AND key = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "value: i32",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Int64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 3
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"d6558668b7395b95ded8da71c80963ddde957abdcc3c68b03431f8e904e0d21f": {
|
||||||
|
"query": "SELECT key, value as \"value: i32\" FROM user_variables\n WHERE room_id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "key",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "value: i32",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Int64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ use tenebrous_dicebot::bot::DiceBot;
|
||||||
use tenebrous_dicebot::config::*;
|
use tenebrous_dicebot::config::*;
|
||||||
use tenebrous_dicebot::db::Database;
|
use tenebrous_dicebot::db::Database;
|
||||||
use tenebrous_dicebot::error::BotError;
|
use tenebrous_dicebot::error::BotError;
|
||||||
|
use tenebrous_dicebot::migrator;
|
||||||
use tenebrous_dicebot::state::DiceBotState;
|
use tenebrous_dicebot::state::DiceBotState;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -33,6 +34,9 @@ async fn run() -> Result<(), BotError> {
|
||||||
|
|
||||||
db.migrate(cfg.migration_version())?;
|
db.migrate(cfg.migration_version())?;
|
||||||
|
|
||||||
|
let sqlite_path = format!("{}/dicebot.sqlite", cfg.database_path());
|
||||||
|
migrator::migrate(&sqlite_path).await?;
|
||||||
|
|
||||||
match DiceBot::new(&cfg, &state, &db) {
|
match DiceBot::new(&cfg, &state, &db) {
|
||||||
Ok(bot) => bot.run().await?,
|
Ok(bot) => bot.run().await?,
|
||||||
Err(e) => println!("Error connecting: {:?}", e),
|
Err(e) => println!("Error connecting: {:?}", e),
|
||||||
|
|
|
@ -12,6 +12,7 @@ pub mod errors;
|
||||||
pub mod migrations;
|
pub mod migrations;
|
||||||
pub mod rooms;
|
pub mod rooms;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
|
pub mod sqlite;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod variables;
|
pub mod variables;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
use sled::transaction::{TransactionError, UnabortableTransactionError};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum MigrationError {
|
||||||
|
#[error("cannot downgrade to an older database version")]
|
||||||
|
CannotDowngrade,
|
||||||
|
|
||||||
|
#[error("migration for version {0} not defined")]
|
||||||
|
MigrationNotFound(u32),
|
||||||
|
|
||||||
|
#[error("migration failed: {0}")]
|
||||||
|
MigrationFailed(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO better combining of key and value in certain errors (namely
|
||||||
|
//I32SchemaViolation).
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum DataError {
|
||||||
|
#[error("value does not exist for key: {0}")]
|
||||||
|
KeyDoesNotExist(String),
|
||||||
|
|
||||||
|
#[error("too many entries")]
|
||||||
|
TooManyEntries,
|
||||||
|
|
||||||
|
#[error("expected i32, but i32 schema was violated")]
|
||||||
|
I32SchemaViolation,
|
||||||
|
|
||||||
|
#[error("unexpected or corruptd data bytes")]
|
||||||
|
InvalidValue,
|
||||||
|
|
||||||
|
#[error("expected string ref, but utf8 schema was violated: {0}")]
|
||||||
|
Utf8RefSchemaViolation(#[from] std::str::Utf8Error),
|
||||||
|
|
||||||
|
#[error("expected string, but utf8 schema was violated: {0}")]
|
||||||
|
Utf8SchemaViolation(#[from] std::string::FromUtf8Error),
|
||||||
|
|
||||||
|
#[error("internal database error: {0}")]
|
||||||
|
InternalError(#[from] sled::Error),
|
||||||
|
|
||||||
|
#[error("transaction error: {0}")]
|
||||||
|
TransactionError(#[from] sled::transaction::TransactionError),
|
||||||
|
|
||||||
|
#[error("unabortable transaction error: {0}")]
|
||||||
|
UnabortableTransactionError(#[from] UnabortableTransactionError),
|
||||||
|
|
||||||
|
#[error("data migration error: {0}")]
|
||||||
|
MigrationError(#[from] MigrationError),
|
||||||
|
|
||||||
|
#[error("deserialization error: {0}")]
|
||||||
|
DeserializationError(#[from] bincode::Error),
|
||||||
|
|
||||||
|
#[error("sqlx error: {0}")]
|
||||||
|
SqlxError(#[from] sqlx::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This From implementation is necessary to deal with the recursive
|
||||||
|
/// error type in the error enum. We defined a transaction error, but
|
||||||
|
/// the only place we use it is when converting from
|
||||||
|
/// sled::transaction::TransactionError<DataError>. This converter
|
||||||
|
/// extracts the inner data error from transaction aborted errors, and
|
||||||
|
/// forwards anything else onward as-is, but wrapped in DataError.
|
||||||
|
impl From<TransactionError<DataError>> for DataError {
|
||||||
|
fn from(error: TransactionError<DataError>) -> Self {
|
||||||
|
match error {
|
||||||
|
TransactionError::Abort(data_err) => data_err,
|
||||||
|
TransactionError::Storage(storage_err) => {
|
||||||
|
DataError::TransactionError(TransactionError::Storage(storage_err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Automatically aborts transactions that hit a DataError by using
|
||||||
|
/// the try (question mark) operator when this trait implementation is
|
||||||
|
/// in scope.
|
||||||
|
impl From<DataError> for sled::transaction::ConflictableTransactionError<DataError> {
|
||||||
|
fn from(error: DataError) -> Self {
|
||||||
|
sled::transaction::ConflictableTransactionError::Abort(error)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use errors::DataError;
|
||||||
|
use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions};
|
||||||
|
use sqlx::ConnectOptions;
|
||||||
|
use sqlx::Connection;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
pub mod errors;
|
||||||
|
pub mod variables;
|
||||||
|
|
||||||
|
// TODO move this up to the top once we delete sled. Traits will be the
|
||||||
|
// main API, then we can have different impls for different DBs.
|
||||||
|
#[async_trait]
|
||||||
|
pub(crate) trait Variables {
|
||||||
|
async fn get_user_variables(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
room_id: &str,
|
||||||
|
) -> Result<HashMap<String, i32>, DataError>;
|
||||||
|
|
||||||
|
async fn get_variable_count(&self, user: &str, room_id: &str) -> Result<i32, DataError>;
|
||||||
|
|
||||||
|
async fn get_user_variable(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
room_id: &str,
|
||||||
|
variable_name: &str,
|
||||||
|
) -> Result<i32, DataError>;
|
||||||
|
|
||||||
|
async fn set_user_variable(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
room_id: &str,
|
||||||
|
variable_name: &str,
|
||||||
|
value: i32,
|
||||||
|
) -> Result<(), DataError>;
|
||||||
|
|
||||||
|
async fn delete_user_variable(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
room_id: &str,
|
||||||
|
variable_name: &str,
|
||||||
|
) -> Result<(), DataError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Database {
|
||||||
|
conn: SqlitePool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Database {
|
||||||
|
fn new_db(conn: SqlitePool) -> Result<Database, DataError> {
|
||||||
|
let database = Database { conn: conn.clone() };
|
||||||
|
|
||||||
|
Ok(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn new(path: &str) -> Result<Database, DataError> {
|
||||||
|
//Create database if missing.
|
||||||
|
let conn = SqliteConnectOptions::from_str(path)?
|
||||||
|
.create_if_missing(true)
|
||||||
|
.connect()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
drop(conn);
|
||||||
|
|
||||||
|
//Return actual conncetion pool.
|
||||||
|
let conn = SqlitePoolOptions::new()
|
||||||
|
.max_connections(5)
|
||||||
|
.connect(path)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Self::new_db(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn new_temp() -> Result<Database, DataError> {
|
||||||
|
Self::new("sqlite::memory:").await
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
use super::errors::DataError;
|
||||||
|
use super::{Database, Variables};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
struct UserVariableRow {
|
||||||
|
key: String,
|
||||||
|
value: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Variables for Database {
|
||||||
|
async fn get_user_variables(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
room_id: &str,
|
||||||
|
) -> Result<HashMap<String, i32>, DataError> {
|
||||||
|
let rows = sqlx::query!(
|
||||||
|
r#"SELECT key, value as "value: i32" FROM user_variables
|
||||||
|
WHERE room_id = ?"#,
|
||||||
|
room_id,
|
||||||
|
)
|
||||||
|
.fetch_all(&self.conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(rows.into_iter().map(|row| (row.key, row.value)).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_variable_count(&self, user: &str, room_id: &str) -> Result<i32, DataError> {
|
||||||
|
Ok(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_user_variable(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
room_id: &str,
|
||||||
|
variable_name: &str,
|
||||||
|
) -> Result<i32, DataError> {
|
||||||
|
let row = sqlx::query!(
|
||||||
|
r#"SELECT value as "value: i32" FROM user_variables
|
||||||
|
WHERE user_id = ? AND room_id = ? AND key = ?"#,
|
||||||
|
user,
|
||||||
|
room_id,
|
||||||
|
variable_name
|
||||||
|
)
|
||||||
|
.fetch_one(&self.conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(row.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_user_variable(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
room_id: &str,
|
||||||
|
variable_name: &str,
|
||||||
|
value: i32,
|
||||||
|
) -> Result<(), DataError> {
|
||||||
|
sqlx::query(
|
||||||
|
"INSERT INTO user_variables
|
||||||
|
(user_id, room_id, variable_name, value)
|
||||||
|
values (?, ?, ?, ?)",
|
||||||
|
)
|
||||||
|
.bind(user)
|
||||||
|
.bind(room_id)
|
||||||
|
.bind(variable_name)
|
||||||
|
.bind(value)
|
||||||
|
.execute(&self.conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn delete_user_variable(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
room_id: &str,
|
||||||
|
variable_name: &str,
|
||||||
|
) -> Result<(), DataError> {
|
||||||
|
sqlx::query(
|
||||||
|
"DELETE FROM user_variables
|
||||||
|
WHERE user_id = ? AND room_id = ? AND variable_name = ?",
|
||||||
|
)
|
||||||
|
.bind(user)
|
||||||
|
.bind(room_id)
|
||||||
|
.bind(variable_name)
|
||||||
|
.execute(&self.conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::commands::CommandError;
|
|
||||||
use crate::config::ConfigError;
|
use crate::config::ConfigError;
|
||||||
use crate::db::errors::DataError;
|
use crate::db::errors::DataError;
|
||||||
|
use crate::{commands::CommandError, migrator::migrations};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
|
@ -73,6 +73,9 @@ pub enum BotError {
|
||||||
#[error("database error")]
|
#[error("database error")]
|
||||||
DatabaseError(#[from] sled::Error),
|
DatabaseError(#[from] sled::Error),
|
||||||
|
|
||||||
|
#[error("database migration error: {0}")]
|
||||||
|
SqliteError(#[from] crate::migrator::MigrationError),
|
||||||
|
|
||||||
#[error("too many commands or message was too large")]
|
#[error("too many commands or message was too large")]
|
||||||
MessageTooLarge,
|
MessageTooLarge,
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ pub mod error;
|
||||||
mod help;
|
mod help;
|
||||||
pub mod logic;
|
pub mod logic;
|
||||||
pub mod matrix;
|
pub mod matrix;
|
||||||
|
pub mod migrator;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
mod parser;
|
mod parser;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
pub mod migrator;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), migrator::MigrationError> {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let db_path: &str = match &args[..] {
|
||||||
|
[_, path] => path.as_ref(),
|
||||||
|
[_, _, ..] => panic!("Expected exactly 0 or 1 argument"),
|
||||||
|
_ => "dicebot.sqlite",
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Using database: {}", db_path);
|
||||||
|
|
||||||
|
migrator::migrate(db_path).await
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
use log::info;
|
||||||
|
use refinery::config::{Config, ConfigDbType};
|
||||||
|
use sqlx::sqlite::SqliteConnectOptions;
|
||||||
|
use sqlx::ConnectOptions;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
pub mod migrations;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum MigrationError {
|
||||||
|
#[error("sqlite connection error: {0}")]
|
||||||
|
SqlxError(#[from] sqlx::Error),
|
||||||
|
|
||||||
|
#[error("refinery migration error: {0}")]
|
||||||
|
RefineryError(#[from] refinery::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run database migrations against the sqlite database.
|
||||||
|
pub async fn migrate(db_path: &str) -> Result<(), MigrationError> {
|
||||||
|
//Create database if missing.
|
||||||
|
let conn = SqliteConnectOptions::from_str(&format!("sqlite://{}", db_path))?
|
||||||
|
.create_if_missing(true)
|
||||||
|
.connect()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
drop(conn);
|
||||||
|
|
||||||
|
let mut conn = Config::new(ConfigDbType::Sqlite).set_db_path(db_path);
|
||||||
|
info!("Running migrations");
|
||||||
|
migrations::runner().run(&mut conn)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
use barrel::backend::Sqlite;
|
||||||
|
use barrel::{types, Migration};
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
pub fn migration() -> String {
|
||||||
|
let mut m = Migration::new();
|
||||||
|
info!("Applying migration: {}", file!());
|
||||||
|
|
||||||
|
m.create_table("user_variables", |t| {
|
||||||
|
t.add_column("id", types::primary());
|
||||||
|
t.add_column("room_id", types::text());
|
||||||
|
t.add_column("user_id", types::text());
|
||||||
|
t.add_column("key", types::text());
|
||||||
|
t.add_column("value", types::integer());
|
||||||
|
});
|
||||||
|
|
||||||
|
m.make::<Sqlite>()
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
use barrel::backend::Sqlite;
|
||||||
|
use barrel::{types, Migration};
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
pub fn migration() -> String {
|
||||||
|
let mut m = Migration::new();
|
||||||
|
info!("Applying migration: {}", file!());
|
||||||
|
|
||||||
|
//Table for basic room information: room ID, room name
|
||||||
|
m.create_table("room_info", move |t| {
|
||||||
|
t.add_column("id", types::primary());
|
||||||
|
t.add_column("room_id", types::text());
|
||||||
|
t.add_column("room_name", types::text());
|
||||||
|
});
|
||||||
|
|
||||||
|
//Table of users in rooms.
|
||||||
|
m.create_table("room_users", move |t| {
|
||||||
|
t.add_column("id", types::primary());
|
||||||
|
t.add_column("room_id", types::text());
|
||||||
|
t.add_column("username", types::text());
|
||||||
|
});
|
||||||
|
|
||||||
|
//Table of room ID, event ID, event timestamp
|
||||||
|
m.create_table("room_events", move |t| {
|
||||||
|
t.add_column("id", types::primary());
|
||||||
|
t.add_column("room_id", types::text());
|
||||||
|
t.add_column("event_id", types::text());
|
||||||
|
t.add_column("event_timestamp", types::integer());
|
||||||
|
});
|
||||||
|
m.make::<Sqlite>()
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
use refinery::include_migration_mods;
|
||||||
|
include_migration_mods!("src/migrator/migrations");
|
Loading…
Reference in New Issue