use std::collections::HashMap; use structopt::StructOpt; use crate::{Settings, UrlMap, db::backend::Connectable}; use crate::db::migration::{Migration, DatabaseChange, CreateModelOption}; use crate::db::models::{Field, ModelMeta}; #[derive(StructOpt)] /// Generate migrations pub struct MakeMigrations { } #[derive(Debug)] struct AppTablesState { db: HashMap<&'static str, TableState>, } #[derive(Debug)] struct TableState { fields: Vec, } impl From<&[ModelMeta]> for AppTablesState { fn from(models: &[ModelMeta]) -> Self { let mut db = HashMap::new(); for model in models { db.insert(model.name, TableState { fields: model.fields.into() }); } Self { db } } } impl From<&[Migration]> for AppTablesState { fn from(migrations: &[Migration]) -> Self { let mut db = HashMap::new(); for migration in migrations { for change in migration.changes { match change { DatabaseChange::CreateModel { name, fields, options } => { if db.contains_key(name) { if options.contains(&CreateModelOption::IfNotExist) { continue; } else { panic!("double-created table {}", name); } } db.insert(*name, TableState { fields: (*fields).into() }); } } } } Self { db } } } impl MakeMigrations { pub fn execute(self, _urls: UrlMap, settings: Settings) { for app in settings.installed_apps { let expected_table_state = AppTablesState::from(app.models); let actual_table_state = AppTablesState::from(app.migrations); dbg!(expected_table_state, actual_table_state); todo!(); } } }