use diesel::Connection as _; use crate::db::backend::{Connection, SqlGenerator}; use crate::db::models::Field; pub enum DatabaseChange { CreateModel { name: &'static str, fields: &'static [Field], options: &'static [CreateModelOption], }, } impl DatabaseChange { pub fn apply(&self, app_name: &str, connection: &Connection) { use barrel::{types, Migration, Table}; match self { DatabaseChange::CreateModel { name, fields, options, } => { let mut m = Migration::new(); let columns: Vec<(&'static str, _)> = fields .iter() .map(|field| match field { Field::CharField { name, max_length } => { let name = *name; let _type = match max_length { None => types::text(), Some(max_length) => types::varchar(*max_length), }; (name, _type) } Field::DateTimeField { name } => { (*name, types::text()) // TODO do smart things on non-sqlite } Field::IntField { name } => (*name, types::integer()), }) .collect(); let callback = move |t: &mut Table| { for (name, _type) in &columns { t.add_column(*name, _type.clone()); } }; let table_name = format!("{}-{}", app_name, name); if options.contains(&CreateModelOption::IfNotExist) { m.create_table_if_not_exists(table_name, callback); } else { m.create_table(table_name, callback); } connection.execute(&m.make::()).unwrap(); } } } } #[derive(PartialEq)] pub enum CreateModelOption { IfNotExist, }