Switch to diesel with postgres for the database
Signed-off-by: trivernis <trivernis@protonmail.com>pull/2/head
parent
62d9664b35
commit
6d75b840b4
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CsvFileAttributes">
|
||||
<option name="attributeMap">
|
||||
<map>
|
||||
<entry key="/src/commands/minecraft/mod.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value=":" />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/commands/music/current.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value=":" />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/commands/music/mod.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value=":" />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/commands/music/play.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value=":" />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/commands/music/play_next.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value=":" />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/commands/music/utils.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value=":" />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/database/guild.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value="," />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/database/scripts/update_tables.sql">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value="," />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/main.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value=":" />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/src/providers/ytdl/mod.rs">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value=":" />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="bot.db" uuid="4d1d7a8d-098d-4916-b51c-e7bde2613eda">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:bot.db</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
@ -1,10 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<Languages>
|
||||
<language minSize="60" name="Rust" />
|
||||
</Languages>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/tobi-rs.iml" filepath="$PROJECT_DIR$/.idea/tobi-rs.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="file://$PROJECT_DIR$/src/database/scripts/create_tables.sql" dialect="GenericSQL" />
|
||||
<file url="file://$PROJECT_DIR$/src/database/scripts/update_tables.sql" dialect="SQLite" />
|
||||
<file url="PROJECT" dialect="SQLite" />
|
||||
</component>
|
||||
</project>
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="CPP_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,2 @@
|
||||
target
|
||||
.env
|
@ -0,0 +1,340 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[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",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "database"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"diesel",
|
||||
"diesel_migrations",
|
||||
"dotenv",
|
||||
"log",
|
||||
"r2d2",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel"
|
||||
version = "1.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "047bfc4d5c3bd2ef6ca6f981941046113524b9a9f9a7cbdfdd7ff40f58e6f542"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"diesel_derives",
|
||||
"pq-sys",
|
||||
"r2d2",
|
||||
]
|
||||
|
||||
[[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]]
|
||||
name = "diesel_migrations"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c"
|
||||
dependencies = [
|
||||
"migrations_internals",
|
||||
"migrations_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dotenv"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migrations_internals"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860"
|
||||
dependencies = [
|
||||
"diesel",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migrations_macros"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c"
|
||||
dependencies = [
|
||||
"migrations_internals",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[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]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pq-sys"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda"
|
||||
dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r2d2"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f"
|
||||
dependencies = [
|
||||
"log",
|
||||
"parking_lot",
|
||||
"scheduled-thread-pool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scheduled-thread-pool"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "database"
|
||||
version = "0.1.0"
|
||||
authors = ["trivernis <trivernis@protonmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
dotenv = "0.15.0"
|
||||
chrono = "0.4.19"
|
||||
thiserror = "1.0.24"
|
||||
diesel = {version="1.4.6", features=["postgres", "r2d2", "chrono"]}
|
||||
log = "0.4.14"
|
||||
diesel_migrations = "1.4.0"
|
||||
r2d2 = "0.8.9"
|
@ -0,0 +1,5 @@
|
||||
# For documentation on how to configure this file,
|
||||
# see diesel.rs/guides/configuring-diesel-cli
|
||||
|
||||
[print_schema]
|
||||
file = "src/schema.rs"
|
@ -0,0 +1,6 @@
|
||||
-- This file was automatically created by Diesel to setup helper functions
|
||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||
-- changes will be added to existing projects as new migrations.
|
||||
|
||||
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
@ -0,0 +1,36 @@
|
||||
-- This file was automatically created by Diesel to setup helper functions
|
||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||
-- changes will be added to existing projects as new migrations.
|
||||
|
||||
|
||||
|
||||
|
||||
-- Sets up a trigger for the given table to automatically set a column called
|
||||
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
||||
-- in the modified columns)
|
||||
--
|
||||
-- # Example
|
||||
--
|
||||
-- ```sql
|
||||
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
||||
--
|
||||
-- SELECT diesel_manage_updated_at('users');
|
||||
-- ```
|
||||
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
||||
BEGIN
|
||||
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
||||
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF (
|
||||
NEW IS DISTINCT FROM OLD AND
|
||||
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
||||
) THEN
|
||||
NEW.updated_at := current_timestamp;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
@ -0,0 +1,2 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE guild_settings;
|
@ -0,0 +1,6 @@
|
||||
CREATE TABLE guild_settings (
|
||||
guild_id BIGINT NOT NULL,
|
||||
key VARCHAR(255) NOT NULL,
|
||||
value VARCHAR(1024),
|
||||
PRIMARY KEY (guild_id, key)
|
||||
);
|
@ -0,0 +1,81 @@
|
||||
use crate::error::DatabaseResult;
|
||||
use crate::models::*;
|
||||
use crate::schema::*;
|
||||
use crate::PoolConnection;
|
||||
use diesel::insert_into;
|
||||
use diesel::prelude::*;
|
||||
use std::any;
|
||||
use std::fmt::Debug;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Database {
|
||||
pool: PoolConnection,
|
||||
}
|
||||
|
||||
unsafe impl Send for Database {}
|
||||
unsafe impl Sync for Database {}
|
||||
|
||||
impl Database {
|
||||
pub fn new(pool: PoolConnection) -> Self {
|
||||
Self { pool }
|
||||
}
|
||||
|
||||
/// Returns a guild setting from the database
|
||||
pub fn get_guild_setting<T: 'static>(
|
||||
&self,
|
||||
guild_id: u64,
|
||||
key: &str,
|
||||
) -> DatabaseResult<Option<T>>
|
||||
where
|
||||
T: FromStr,
|
||||
{
|
||||
use guild_settings::dsl;
|
||||
log::debug!("Retrieving setting '{}' for guild {}", key, guild_id);
|
||||
let connection = self.pool.get()?;
|
||||
|
||||
let entries: Vec<GuildSetting> = dsl::guild_settings
|
||||
.filter(dsl::guild_id.eq(guild_id as i64))
|
||||
.filter(dsl::key.eq(key))
|
||||
.load::<GuildSetting>(&connection)?;
|
||||
log::trace!("Result is {:?}", entries);
|
||||
|
||||
if let Some(first) = entries.first() {
|
||||
if any::TypeId::of::<T>() == any::TypeId::of::<bool>() {
|
||||
Ok(first
|
||||
.value
|
||||
.clone()
|
||||
.unwrap_or("false".to_string())
|
||||
.parse::<T>()
|
||||
.ok())
|
||||
} else {
|
||||
Ok(first.value.clone().and_then(|v| v.parse::<T>().ok()))
|
||||
}
|
||||
} else {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
/// Upserting a guild setting
|
||||
pub fn set_guild_setting<T>(&self, guild_id: u64, key: &str, value: T) -> DatabaseResult<()>
|
||||
where
|
||||
T: ToString + Debug,
|
||||
{
|
||||
use guild_settings::dsl;
|
||||
log::debug!("Setting '{}' to '{:?}' for guild {}", key, value, guild_id);
|
||||
let connection = self.pool.get()?;
|
||||
|
||||
insert_into(dsl::guild_settings)
|
||||
.values(&GuildSettingInsert {
|
||||
guild_id: guild_id as i64,
|
||||
key: key.to_string(),
|
||||
value: value.to_string(),
|
||||
})
|
||||
.on_conflict((dsl::guild_id, dsl::key))
|
||||
.do_update()
|
||||
.set(dsl::value.eq(value.to_string()))
|
||||
.execute(&connection)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
use thiserror::Error;
|
||||
|
||||
pub type DatabaseResult<T> = Result<T, DatabaseError>;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum DatabaseError {
|
||||
#[error("DotEnv Error: {0}")]
|
||||
DotEnv(#[from] dotenv::Error),
|
||||
|
||||
#[error("Connection Error: {0}")]
|
||||
ConnectionError(#[from] diesel::prelude::ConnectionError),
|
||||
|
||||
#[error("Pool Connection Error: {0}")]
|
||||
PoolConnectionError(#[from] r2d2::Error),
|
||||
|
||||
#[error("Migration Error: {0}")]
|
||||
MigrationError(#[from] diesel_migrations::RunMigrationsError),
|
||||
|
||||
#[error("Result Error: {0}")]
|
||||
ResultError(#[from] diesel::result::Error),
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
#[macro_use]
|
||||
extern crate diesel;
|
||||
|
||||
#[macro_use]
|
||||
extern crate diesel_migrations;
|
||||
|
||||
use crate::error::DatabaseResult;
|
||||
use diesel::prelude::*;
|
||||
use diesel::r2d2::{ConnectionManager, Pool};
|
||||
use std::env;
|
||||
|
||||
pub mod database;
|
||||
pub mod error;
|
||||
pub mod models;
|
||||
pub mod schema;
|
||||
|
||||
pub use database::Database;
|
||||
|
||||
type PoolConnection = Pool<ConnectionManager<PgConnection>>;
|
||||
|
||||
embed_migrations!("../database/migrations");
|
||||
|
||||
fn get_connection() -> DatabaseResult<PoolConnection> {
|
||||
dotenv::dotenv()?;
|
||||
let database_url = env::var("DATABASE_URL").expect("No DATABASE_URL in path");
|
||||
log::debug!("Establishing database connection...");
|
||||
let manager = ConnectionManager::<PgConnection>::new(database_url);
|
||||
let pool = Pool::builder().max_size(16).build(manager)?;
|
||||
let connection = pool.get()?;
|
||||
log::debug!("Running migrations...");
|
||||
embedded_migrations::run(&connection)?;
|
||||
log::debug!("Migrations finished");
|
||||
log::info!("Database connection initialized");
|
||||
|
||||
Ok(pool)
|
||||
}
|
||||
|
||||
pub fn get_database() -> DatabaseResult<Database> {
|
||||
let conn = get_connection()?;
|
||||
Ok(Database::new(conn))
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
use crate::schema::*;
|
||||
|
||||
#[derive(Queryable, Debug)]
|
||||
pub struct GuildSetting {
|
||||
pub guild_id: i64,
|
||||
pub key: String,
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "guild_settings"]
|
||||
pub struct GuildSettingInsert {
|
||||
pub guild_id: i64,
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
table! {
|
||||
guild_settings (guild_id, key) {
|
||||
guild_id -> Int8,
|
||||
key -> Varchar,
|
||||
value -> Nullable<Varchar>,
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub struct Guild {
|
||||
guild_id: i32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub struct GuildSettings {
|
||||
pub guild_id: String,
|
||||
pub setting_key: String,
|
||||
pub setting_value: String,
|
||||
}
|
||||
|
||||
pub static SETTING_AUTOSHUFFLE: &str = "music.autoshuffle";
|
||||
pub static GUILD_SETTINGS: &[&str] = &[SETTING_AUTOSHUFFLE];
|
@ -1,103 +0,0 @@
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rusqlite::{params, Connection, NO_PARAMS};
|
||||
use serenity::client::Context;
|
||||
use serenity::model::id::GuildId;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::database::guild::GuildSettings;
|
||||
use crate::database::scripts::{CREATE_SCRIPT, UPDATE_SCRIPT};
|
||||
use crate::utils::error::{BotError, BotResult};
|
||||
use crate::utils::store::Store;
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub mod guild;
|
||||
pub mod scripts;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Database {
|
||||
connection: Connection,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub fn new(connection: Connection) -> Self {
|
||||
Self { connection }
|
||||
}
|
||||
|
||||
/// Initializes the database
|
||||
pub fn init(&self) -> BotResult<()> {
|
||||
self.connection.execute(CREATE_SCRIPT, NO_PARAMS)?;
|
||||
self.connection.execute(UPDATE_SCRIPT, NO_PARAMS)?;
|
||||
log::info!("Database initialized");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns a guild setting
|
||||
pub fn get_guild_setting<T>(&self, guild_id: &GuildId, key: &str) -> BotResult<T>
|
||||
where
|
||||
T: Clone + FromStr + Debug,
|
||||
{
|
||||
log::trace!(
|
||||
"Fetching value of guild setting '{}' for guild {}",
|
||||
key,
|
||||
guild_id
|
||||
);
|
||||
self.connection
|
||||
.query_row(
|
||||
"SELECT guild_id, setting_key, setting_value FROM guild_settings WHERE guild_id = ?1 AND setting_key = ?2",
|
||||
params![guild_id.to_string(), key],
|
||||
|r| Ok(serde_rusqlite::from_row::<GuildSettings>(r).unwrap()),
|
||||
)
|
||||
.map_err(BotError::from)
|
||||
.and_then(|s| {
|
||||
s.setting_value
|
||||
.parse::<T>()
|
||||
.map_err(|_| BotError::from("Failed to parse Setting"))
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets a guild setting and overrides it if it already exists
|
||||
pub fn set_guild_setting<T>(&self, guild_id: &GuildId, key: &str, value: T) -> BotResult<()>
|
||||
where
|
||||
T: ToString + FromStr + Clone + Debug,
|
||||
{
|
||||
if self.get_guild_setting::<T>(guild_id, key).is_ok() {
|
||||
log::trace!("Clearing previous guild setting");
|
||||
self.connection.execute(
|
||||
"DELETE FROM guild_settings WHERE guild_id = ?1 AND setting_key = ?2",
|
||||
params![guild_id.to_string(), key],
|
||||
)?;
|
||||
}
|
||||
self.connection.execute(
|
||||
"INSERT INTO guild_settings (guild_id, setting_key, setting_value) VALUES (?1, ?2, ?3)",
|
||||
params![guild_id.to_string(), key, value.to_string()],
|
||||
)?;
|
||||
log::debug!(
|
||||
"Setting '{}' set to '{:?}' for guild {}",
|
||||
key,
|
||||
value,
|
||||
guild_id
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_database() -> BotResult<Database> {
|
||||
let filename = dotenv::var("DB_NAME").unwrap_or("bot.db".to_string());
|
||||
let connection = rusqlite::Connection::open(filename)?;
|
||||
let database = Database::new(connection);
|
||||
database.init()?;
|
||||
|
||||
Ok(database)
|
||||
}
|
||||
|
||||
/// Returns a reference to a guilds music queue
|
||||
pub(crate) async fn get_database_from_context(ctx: &Context) -> Arc<Mutex<Database>> {
|
||||
let data = ctx.data.read().await;
|
||||
let store = data.get::<Store>().unwrap();
|
||||
|
||||
Arc::clone(&store.database)
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS guild_settings
|
||||
(
|
||||
guild_id TEXT NOT NULL,
|
||||
setting_key TEXT NOT NULL,
|
||||
setting_value TEXT NOT NULL
|
||||
);
|
@ -1,2 +0,0 @@
|
||||
pub static CREATE_SCRIPT: &str = include_str!("create_tables.sql");
|
||||
pub static UPDATE_SCRIPT: &str = include_str!("update_tables.sql");
|
@ -1,2 +0,0 @@
|
||||
PRAGMA foreign_keys = false;
|
||||
DROP TABLE IF EXISTS guilds;
|
@ -0,0 +1,2 @@
|
||||
pub const SETTING_AUTOSHUFFLE: &str = "music.autoshuffle";
|
||||
pub const GUILD_SETTINGS: &[&str] = &[SETTING_AUTOSHUFFLE];
|
@ -1 +1,2 @@
|
||||
pub(crate) mod constants;
|
||||
pub(crate) mod music;
|
||||
|
Loading…
Reference in New Issue