Move migrations to refinery + barrel, enable 'offline' sqlx query checking
This commit is contained in:
parent
717ab0677b
commit
f572a9c493
3
.env
3
.env
|
@ -1 +1,2 @@
|
|||
DATABASE_URL="sqlite://./tenebrous.sqlite"
|
||||
DATABASE_URL="sqlite://tenebrous.sqlite"
|
||||
SQLX_OFFLINE="true"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/target
|
||||
todo.org
|
||||
*.sqlite
|
||||
*.sqlite.*
|
||||
|
|
|
@ -144,6 +144,12 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "barrel"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d67c978b1322c8031145b1f6c236fc371292f52c565bc96018b2971afcbffe1"
|
||||
|
||||
[[package]]
|
||||
name = "base-x"
|
||||
version = "0.2.8"
|
||||
|
@ -508,6 +514,9 @@ name = "either"
|
|||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "erased-serde"
|
||||
|
@ -524,6 +533,18 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[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]]
|
||||
name = "figment"
|
||||
version = "0.9.4"
|
||||
|
@ -1711,6 +1732,50 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "refinery"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "432021bd2eb60a8851757fdd145907be1a96c70961da167a3fb362001f2f397c"
|
||||
dependencies = [
|
||||
"refinery-core",
|
||||
"refinery-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "refinery-core"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c8c973af7988f84595fe204529bf04b129fcb33c77a928fdc049980beb24c5b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"cfg-if 0.1.10",
|
||||
"chrono",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"regex",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"siphasher",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"url",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "refinery-macros"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f397c4dfbcf0b298e8b10e5702d69852829636ee121215c42efe421dd16126e1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"refinery-core",
|
||||
"regex",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.2"
|
||||
|
@ -1818,6 +1883,21 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[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]]
|
||||
name = "rust-argon2"
|
||||
version = "0.8.3"
|
||||
|
@ -1954,6 +2034,7 @@ version = "1.0.59"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
|
@ -1999,6 +2080,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.2"
|
||||
|
@ -2084,6 +2171,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"sqlformat",
|
||||
|
@ -2105,9 +2193,12 @@ dependencies = [
|
|||
"either",
|
||||
"futures",
|
||||
"heck",
|
||||
"hex",
|
||||
"lazy_static",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sqlx-core",
|
||||
"sqlx-rt",
|
||||
|
@ -2269,12 +2360,14 @@ dependencies = [
|
|||
name = "tenebrous-sheets"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"barrel",
|
||||
"erased-serde",
|
||||
"futures",
|
||||
"log",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"rand",
|
||||
"refinery",
|
||||
"rocket",
|
||||
"rocket_contrib",
|
||||
"rust-argon2",
|
||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -4,6 +4,15 @@ version = "0.1.0"
|
|||
authors = ["jeff <jeff@agnos.is>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
default-run = "tenebrous"
|
||||
|
||||
[[bin]]
|
||||
name = "migrate"
|
||||
path = "src/migrate.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "tenebrous"
|
||||
path = "src/main.rs"
|
||||
|
||||
[build-dependencies]
|
||||
prost-build = "0.6"
|
||||
|
@ -20,7 +29,9 @@ log = "0.4"
|
|||
rand = "0.7"
|
||||
futures = "0.3"
|
||||
strum = { version = "0.20", features = ["derive"] }
|
||||
sqlx = { version = "0.4.2", features = [ "sqlite", "runtime-tokio-native-tls" ] }
|
||||
sqlx = { version = "0.4.2", features = [ "offline", "sqlite", "runtime-tokio-native-tls" ] }
|
||||
refinery = { version = "0.3", features = ["rusqlite"]}
|
||||
barrel = { version = "0.6", features = ["sqlite3"] }
|
||||
|
||||
[dependencies.rocket]
|
||||
git = "https://github.com/SergioBenitez/Rocket"
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
DROP TABLE characters;
|
|
@ -1,9 +0,0 @@
|
|||
CREATE TABLE characters(
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL,
|
||||
viewable BOOLEAN NOT NULL,
|
||||
character_name TEXT NOT NULL,
|
||||
data_type TEXT CHECK(data_type IN ('chronicles_of_darkness_v1', 'changeling_v1')) NOT NULL,
|
||||
data_version INTEGER NOT NULL,
|
||||
data BLOB NOT NULL
|
||||
);
|
|
@ -1 +0,0 @@
|
|||
DROP TABLE users;
|
|
@ -1,5 +0,0 @@
|
|||
CREATE TABLE users (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL
|
||||
);
|
|
@ -0,0 +1,165 @@
|
|||
{
|
||||
"db": "SQLite",
|
||||
"492e1e087edc6eff4004033227e3f3510f1165c3ec7626e89b695c760bc113d2": {
|
||||
"query": "SELECT id as \"id: _\",\n user_id as \"user_id: _\",\n data_type as \"data_type: _\",\n data_version as \"data_version: _\",\n viewable, character_name\n FROM characters WHERE user_id = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id: _",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "user_id: _",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "data_type: _",
|
||||
"ordinal": 2,
|
||||
"type_info": "Null"
|
||||
},
|
||||
{
|
||||
"name": "data_version: _",
|
||||
"ordinal": 3,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "viewable",
|
||||
"ordinal": 4,
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "character_name",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
}
|
||||
},
|
||||
"7a55ee917cf1ec732b10b2844dd5a3d0089c177b0eb183932fd73e20387a1610": {
|
||||
"query": "SELECT id as \"id: _\", username, password FROM users WHERE username = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id: _",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
}
|
||||
},
|
||||
"d7d1fc9ceff3b7659c8f04fd5b574104d1866cb1ea67d9534b6f3f4064699fb6": {
|
||||
"query": "SELECT id as \"id: _\", username, password FROM users WHERE id = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id: _",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
}
|
||||
},
|
||||
"e3c4b224ce8ce70a4d7709af7abe82a6f53bff834460fa7d32bb0b6daea94565": {
|
||||
"query": "SELECT id as \"id: _\",\n user_id as \"user_id: _\",\n viewable, character_name, data,\n data_type as \"data_type: _\",\n data_version as \"data_version: _\"\n FROM characters WHERE id = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id: _",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "user_id: _",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "viewable",
|
||||
"ordinal": 2,
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "character_name",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"ordinal": 4,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "data_type: _",
|
||||
"ordinal": 5,
|
||||
"type_info": "Null"
|
||||
},
|
||||
{
|
||||
"name": "data_version: _",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
13
src/db.rs
13
src/db.rs
|
@ -1,10 +1,21 @@
|
|||
use crate::models::characters::{Character, NewCharacter, StrippedCharacter};
|
||||
use crate::models::users::{NewUser, User};
|
||||
use sqlx::sqlite::{SqlitePool, SqlitePoolOptions};
|
||||
use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions};
|
||||
use sqlx::ConnectOptions;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub type TenebrousDbConn<'a> = rocket::State<'a, SqlitePool>;
|
||||
|
||||
pub(crate) async fn create_pool() -> Result<SqlitePool, crate::errors::Error> {
|
||||
//Create database if missing.
|
||||
let conn = SqliteConnectOptions::from_str("sqlite://tenebrous.sqlite")?
|
||||
.create_if_missing(true)
|
||||
.connect()
|
||||
.await?;
|
||||
|
||||
drop(conn);
|
||||
|
||||
//Return actual conncetion pool.
|
||||
SqlitePoolOptions::new()
|
||||
.max_connections(5)
|
||||
.connect("tenebrous.sqlite")
|
||||
|
|
|
@ -15,11 +15,14 @@ use rocket_contrib::templates::Template;
|
|||
pub mod catchers;
|
||||
pub mod db;
|
||||
pub mod errors;
|
||||
pub mod migrator;
|
||||
pub mod models;
|
||||
pub mod routes;
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() -> Result<(), crate::errors::Error> {
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
migrator::migrate().await?;
|
||||
|
||||
let root_routes: Vec<rocket::Route> = {
|
||||
routes::root::routes()
|
||||
.into_iter()
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
pub mod migrator;
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
crate::migrator::migrate().await
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
use refinery::config::{Config, ConfigDbType};
|
||||
use sqlx::sqlite::SqliteConnectOptions;
|
||||
use sqlx::ConnectOptions;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub mod migrations;
|
||||
|
||||
pub(crate) async fn migrate() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//Create database if missing.
|
||||
let conn = SqliteConnectOptions::from_str("sqlite://tenebrous.sqlite")?
|
||||
.create_if_missing(true)
|
||||
.connect()
|
||||
.await?;
|
||||
|
||||
drop(conn);
|
||||
|
||||
let mut conn = Config::new(ConfigDbType::Sqlite).set_db_path("tenebrous.sqlite");
|
||||
println!("Running migrations");
|
||||
migrations::runner().run(&mut conn)?;
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
use barrel::backend::Sqlite;
|
||||
use barrel::{types, Migration};
|
||||
|
||||
pub fn migration() -> String {
|
||||
let mut m = Migration::new();
|
||||
println!("Applying: {}", file!());
|
||||
|
||||
m.create_table("users", |t| {
|
||||
t.add_column("id", types::primary());
|
||||
t.add_column("username", types::text());
|
||||
t.add_column("password", types::text());
|
||||
});
|
||||
|
||||
m.make::<Sqlite>()
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
use barrel::backend::Sqlite;
|
||||
use barrel::{types, Migration};
|
||||
|
||||
pub fn migration() -> String {
|
||||
let mut m = Migration::new();
|
||||
println!("Applying: {}", file!());
|
||||
|
||||
m.create_table("characters", move |t| {
|
||||
let db_enum = r#"CHECK(data_type IN ('chronicles_of_darkness_v1', 'changeling_v1'))"#;
|
||||
t.add_column("id", types::primary());
|
||||
t.add_column("user_id", types::integer());
|
||||
t.add_column("viewable", types::boolean());
|
||||
t.add_column("character_name", types::text());
|
||||
t.add_column("data_type", types::custom(db_enum));
|
||||
t.add_column("data_version", types::integer());
|
||||
t.add_column("data", types::custom("BLOB"));
|
||||
});
|
||||
|
||||
m.make::<Sqlite>()
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
use refinery::include_migration_mods;
|
||||
include_migration_mods!("src/migrator/migrations");
|
Loading…
Reference in New Issue