refactor: some lil things
parent
cc69935a88
commit
1bc9ae01d8
|
@ -45,3 +45,35 @@ impl From<rusqlite::Error> for DbError {
|
||||||
Self::Db(value)
|
Self::Db(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn run_migrations(pool: &DbPool, migrations: &[&str]) -> rusqlite::Result<()> {
|
||||||
|
let mut conn = pool.get().unwrap();
|
||||||
|
|
||||||
|
// If the migration version query fails, we assume it's because the table isn't there yet so we
|
||||||
|
// try to run the first migration
|
||||||
|
let mut next_version = conn
|
||||||
|
.query_row("select max(version) from migration_version", (), |row| {
|
||||||
|
row.get::<_, usize>(0).map(|n| n + 1)
|
||||||
|
})
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
while next_version < migrations.len() {
|
||||||
|
let tx = conn.transaction()?;
|
||||||
|
|
||||||
|
tx.execute(migrations[next_version], ())?;
|
||||||
|
|
||||||
|
let cur_time = chrono::Local::now().timestamp();
|
||||||
|
tx.execute(
|
||||||
|
"insert into migration_version values ($1, $2)",
|
||||||
|
(next_version, cur_time),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
tx.commit()?;
|
||||||
|
|
||||||
|
tracing::info!("Applied migration {next_version}");
|
||||||
|
|
||||||
|
next_version += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,13 @@ pub struct Plant {
|
||||||
description: String,
|
description: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct NewPlant {
|
||||||
|
name: String,
|
||||||
|
species: String,
|
||||||
|
description: String,
|
||||||
|
}
|
||||||
|
|
||||||
impl Plant {
|
impl Plant {
|
||||||
pub fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
|
pub fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -30,7 +37,7 @@ impl Plant {
|
||||||
Ok(plants?)
|
Ok(plants?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_id(pool: &DbPool, id: i32) -> Result<Option<Self>, DbError> {
|
pub fn by_id(pool: &DbPool, id: i32) -> Result<Option<Self>, DbError> {
|
||||||
let conn = pool.get()?;
|
let conn = pool.get()?;
|
||||||
|
|
||||||
let mut stmt = conn.prepare("select * from plants where id = $1")?;
|
let mut stmt = conn.prepare("select * from plants where id = $1")?;
|
||||||
|
@ -50,13 +57,6 @@ impl Plant {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct NewPlant {
|
|
||||||
name: String,
|
|
||||||
species: String,
|
|
||||||
description: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NewPlant {
|
impl NewPlant {
|
||||||
pub fn insert(self, pool: &DbPool) -> Result<Plant, DbError> {
|
pub fn insert(self, pool: &DbPool) -> Result<Plant, DbError> {
|
||||||
let conn = pool.get()?;
|
let conn = pool.get()?;
|
||||||
|
|
36
src/main.rs
36
src/main.rs
|
@ -3,7 +3,7 @@ mod server;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use r2d2_sqlite::{rusqlite, SqliteConnectionManager};
|
use r2d2_sqlite::SqliteConnectionManager;
|
||||||
use tera::Tera;
|
use tera::Tera;
|
||||||
use tower_http::compression::CompressionLayer;
|
use tower_http::compression::CompressionLayer;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ async fn main() {
|
||||||
|
|
||||||
let manager = SqliteConnectionManager::file("db.sqlite");
|
let manager = SqliteConnectionManager::file("db.sqlite");
|
||||||
let pool = r2d2::Pool::new(manager).unwrap();
|
let pool = r2d2::Pool::new(manager).unwrap();
|
||||||
run_migrations(&pool).unwrap();
|
db::run_migrations(&pool, &MIGRATIONS).unwrap();
|
||||||
|
|
||||||
let tera = load_templates();
|
let tera = load_templates();
|
||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
|
@ -48,38 +48,6 @@ async fn main() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_migrations(pool: &db::DbPool) -> rusqlite::Result<()> {
|
|
||||||
let mut conn = pool.get().unwrap();
|
|
||||||
|
|
||||||
// If the migration version query fails, we assume it's because the table isn't there yet so we
|
|
||||||
// try to run the first migration
|
|
||||||
let mut next_version = conn
|
|
||||||
.query_row("select max(version) from migration_version", (), |row| {
|
|
||||||
row.get::<_, usize>(0).map(|n| n + 1)
|
|
||||||
})
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
while next_version < MIGRATIONS.len() {
|
|
||||||
let tx = conn.transaction()?;
|
|
||||||
|
|
||||||
tx.execute(MIGRATIONS[next_version], ())?;
|
|
||||||
|
|
||||||
let cur_time = chrono::Local::now().timestamp();
|
|
||||||
tx.execute(
|
|
||||||
"insert into migration_version values ($1, $2)",
|
|
||||||
(next_version, cur_time),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
tx.commit()?;
|
|
||||||
|
|
||||||
tracing::info!("Applied migration {next_version}");
|
|
||||||
|
|
||||||
next_version += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_templates() -> Tera {
|
fn load_templates() -> Tera {
|
||||||
let mut tera = Tera::default();
|
let mut tera = Tera::default();
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ async fn get_plant_page(
|
||||||
Path(plant_id): Path<i32>,
|
Path(plant_id): Path<i32>,
|
||||||
) -> Html<String> {
|
) -> Html<String> {
|
||||||
let (plant, comments) = tokio::task::spawn_blocking(move || {
|
let (plant, comments) = tokio::task::spawn_blocking(move || {
|
||||||
let plant = Plant::with_id(&ctx.pool, plant_id)?.unwrap();
|
let plant = Plant::by_id(&ctx.pool, plant_id)?.unwrap();
|
||||||
let comments = plant.comments(&ctx.pool)?;
|
let comments = plant.comments(&ctx.pool)?;
|
||||||
|
|
||||||
Ok::<_, DbError>((plant, comments))
|
Ok::<_, DbError>((plant, comments))
|
||||||
|
|
Loading…
Reference in New Issue