2020-05-09 15:41:25 +00:00
|
|
|
pub mod character;
|
2020-04-25 13:41:27 +00:00
|
|
|
|
2020-04-20 08:44:29 +00:00
|
|
|
mod error;
|
2020-05-09 15:41:25 +00:00
|
|
|
mod models;
|
|
|
|
mod schema;
|
|
|
|
|
|
|
|
extern crate diesel;
|
|
|
|
|
2020-06-06 08:26:48 +00:00
|
|
|
use diesel::{connection::SimpleConnection, prelude::*};
|
2020-05-09 15:41:25 +00:00
|
|
|
use diesel_migrations::embed_migrations;
|
2020-05-14 18:47:16 +00:00
|
|
|
use std::{env, fs, path::PathBuf};
|
2020-06-21 14:26:06 +00:00
|
|
|
use tracing::warn;
|
2020-05-09 15:41:25 +00:00
|
|
|
|
|
|
|
// See: https://docs.rs/diesel_migrations/1.4.0/diesel_migrations/macro.embed_migrations.html
|
|
|
|
// This macro is called at build-time, and produces the necessary migration info
|
|
|
|
// for the `embedded_migrations` call below.
|
|
|
|
embed_migrations!();
|
|
|
|
|
2020-05-12 23:58:15 +00:00
|
|
|
pub fn run_migrations(db_dir: &str) -> Result<(), diesel_migrations::RunMigrationsError> {
|
2020-05-14 18:47:16 +00:00
|
|
|
let db_dir = &apply_saves_dir_override(db_dir);
|
2020-05-12 23:58:15 +00:00
|
|
|
let _ = fs::create_dir(format!("{}/", db_dir));
|
|
|
|
embedded_migrations::run_with_output(&establish_connection(db_dir), &mut std::io::stdout())
|
2020-05-09 15:41:25 +00:00
|
|
|
}
|
|
|
|
|
2020-05-12 23:58:15 +00:00
|
|
|
fn establish_connection(db_dir: &str) -> SqliteConnection {
|
2020-05-14 18:47:16 +00:00
|
|
|
let db_dir = &apply_saves_dir_override(db_dir);
|
2020-05-12 23:58:15 +00:00
|
|
|
let database_url = format!("{}/db.sqlite", db_dir);
|
2020-06-06 08:26:48 +00:00
|
|
|
|
|
|
|
let connection = SqliteConnection::establish(&database_url)
|
|
|
|
.unwrap_or_else(|_| panic!("Error connecting to {}", database_url));
|
|
|
|
|
|
|
|
// Use Write-Ahead-Logging for improved concurrency: https://sqlite.org/wal.html
|
|
|
|
// Set a busy timeout (in ms): https://sqlite.org/c3ref/busy_timeout.html
|
2020-06-21 21:47:49 +00:00
|
|
|
if let Err(e) = connection.batch_execute(
|
2020-06-06 08:26:48 +00:00
|
|
|
"
|
|
|
|
PRAGMA journal_mode = WAL;
|
|
|
|
PRAGMA busy_timeout = 250;
|
|
|
|
",
|
|
|
|
) {
|
2020-06-21 14:26:06 +00:00
|
|
|
warn!(
|
2020-06-21 21:47:49 +00:00
|
|
|
?e,
|
2020-06-06 08:26:48 +00:00
|
|
|
"Failed adding PRAGMA statements while establishing sqlite connection, this will \
|
2020-06-21 21:47:49 +00:00
|
|
|
result in a higher likelihood of locking errors"
|
2020-06-06 08:26:48 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
connection
|
2020-05-09 15:41:25 +00:00
|
|
|
}
|
2020-05-14 18:47:16 +00:00
|
|
|
|
2020-06-10 19:47:36 +00:00
|
|
|
#[allow(clippy::single_match)] // TODO: Pending review in #587
|
2020-05-14 18:47:16 +00:00
|
|
|
fn apply_saves_dir_override(db_dir: &str) -> String {
|
2020-06-21 21:47:49 +00:00
|
|
|
if let Some(saves_dir) = env::var_os("VELOREN_SAVES_DIR") {
|
|
|
|
let path = PathBuf::from(saves_dir.clone());
|
2020-05-14 18:47:16 +00:00
|
|
|
if path.exists() || path.parent().map(|x| x.exists()).unwrap_or(false) {
|
|
|
|
// Only allow paths with valid unicode characters
|
|
|
|
match path.to_str() {
|
|
|
|
Some(path) => return path.to_owned(),
|
|
|
|
None => {},
|
|
|
|
}
|
|
|
|
}
|
2020-06-21 21:47:49 +00:00
|
|
|
warn!(?saves_dir, "VELOREN_SAVES_DIR points to an invalid path.");
|
2020-05-14 18:47:16 +00:00
|
|
|
}
|
|
|
|
db_dir.to_string()
|
|
|
|
}
|