Migrate to sqlx

This commit is contained in:
Tobias Reisinger 2023-11-21 00:44:45 +01:00
parent bd44dc3183
commit f3d08aab80
19 changed files with 1488 additions and 588 deletions

View file

@ -1,73 +1,80 @@
use std::env;
use log::{info, trace};
use sqlx::migrate::Migrator;
use sqlx::{Pool, Sqlite};
use sqlx::sqlite::SqlitePoolOptions;
use crate::db::errors::DatabaseError;
use crate::db::model_utils::Period;
use crate::db::models::{NewSchedule, Periods};
use crate::db::models::{Schedule, Periods};
use crate::types::EmgauwaUid;
use diesel::prelude::*;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use dotenv::dotenv;
use log::{info, trace};
pub mod errors;
pub mod models;
pub mod schedules;
pub mod schema;
pub mod tag;
mod model_utils;
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
static MIGRATOR: Migrator = sqlx::migrate!(); // defaults to "./migrations"
fn get_connection() -> SqliteConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
SqliteConnection::establish(&database_url)
.unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}
pub fn run_migrations() {
pub async fn run_migrations(pool: &Pool<Sqlite>) {
info!("Running migrations");
let mut connection = get_connection();
connection
.run_pending_migrations(MIGRATIONS)
MIGRATOR
.run(pool)
.await
.expect("Failed to run migrations.");
}
fn init_schedule(schedule: &NewSchedule) -> Result<(), DatabaseError> {
trace!("Initializing schedule {:?}", schedule.name);
match schedules::get_schedule_by_uid(schedule.uid.clone()) {
async fn init_schedule(pool: &Pool<Sqlite>, uid: &EmgauwaUid, name: &str, periods: Periods) -> Result<(), DatabaseError> {
trace!("Initializing schedule {:?}", name);
match schedules::get_schedule_by_uid(pool, uid).await {
Ok(_) => Ok(()),
Err(err) => match err {
DatabaseError::NotFound => {
trace!("Schedule {:?} not found, inserting", schedule.name);
let mut connection = get_connection();
diesel::insert_into(schema::schedules::table)
.values(schedule)
.execute(&mut connection)
trace!("Schedule {:?} not found, inserting", name);
sqlx::query_as!(Schedule, "INSERT INTO schedules (uid, name, periods) VALUES (?, ?, ?) RETURNING *",
uid,
name,
periods,
)
.fetch_optional(pool)
.await?
.ok_or(DatabaseError::InsertGetError)
.map(|_| ())
.map_err(DatabaseError::InsertError)
}
_ => Err(err),
},
}
}
pub fn init(db: &str) {
run_migrations();
init_schedule(&NewSchedule {
uid: &EmgauwaUid::Off,
name: "Off",
periods: &Periods(vec![]),
})
.expect("Error initializing schedule Off");
pub async fn init(db: &str) -> Pool<Sqlite> {
let pool: Pool<Sqlite> = SqlitePoolOptions::new()
.acquire_timeout(std::time::Duration::from_secs(1))
.max_connections(5)
.connect(db)
.await
.expect("Error connecting to database.");
init_schedule(&NewSchedule {
uid: &EmgauwaUid::On,
name: "On",
periods: &Periods(vec![Period::new_on()]),
})
.expect("Error initializing schedule On");
run_migrations(&pool).await;
init_schedule(
&pool,
&EmgauwaUid::Off,
"Off",
Periods(vec![])
)
.await
.expect("Error initializing schedule Off");
init_schedule(
&pool,
&EmgauwaUid::On,
"On",
Periods(vec![Period::new_on()])
)
.await
.expect("Error initializing schedule On");
pool
}