aboutsummaryrefslogtreecommitdiff
path: root/src/cli/make_migrations.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/make_migrations.rs')
-rw-r--r--src/cli/make_migrations.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/cli/make_migrations.rs b/src/cli/make_migrations.rs
new file mode 100644
index 0000000..767639f
--- /dev/null
+++ b/src/cli/make_migrations.rs
@@ -0,0 +1,66 @@
+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<Field>,
+}
+
+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<impl Connectable>) {
+ 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!();
+ }
+ }
+}