aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelody Horn / boringcactus <melody@boringcactus.com>2021-06-18 13:42:52 -0600
committerMelody Horn / boringcactus <melody@boringcactus.com>2021-06-18 13:42:52 -0600
commitacf79a306797b1b12e95415c340792d7c88815ab (patch)
treee2c34c6620e0782e31278c087f5ce201606ce9c0
parent7969e3a85dcb2d936fa2e09b4253b8e801c48c6e (diff)
downloadtosin-acf79a306797b1b12e95415c340792d7c88815ab.tar.gz
tosin-acf79a306797b1b12e95415c340792d7c88815ab.zip
lay groundwork for make-migrations
-rw-r--r--src/cli/make_migrations.rs66
-rw-r--r--src/cli/mod.rs3
-rw-r--r--src/db/models/meta.rs3
-rw-r--r--src/db/models/mod.rs1
-rw-r--r--tosin-macros/src/lib.rs4
5 files changed, 76 insertions, 1 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!();
+ }
+ }
+}
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index a11fd48..851812f 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -2,11 +2,13 @@ use structopt::StructOpt;
use crate::{Settings, UrlMap, db::backend::Connectable};
+mod make_migrations;
mod migrate;
mod run_server;
#[derive(StructOpt)]
enum Command {
+ MakeMigrations(make_migrations::MakeMigrations),
Migrate(migrate::Migrate),
RunServer(run_server::RunServer),
}
@@ -14,6 +16,7 @@ enum Command {
impl Command {
fn execute(self, urls: UrlMap, settings: Settings<impl Connectable>) {
match self {
+ Command::MakeMigrations(command) => command.execute(urls, settings),
Command::Migrate(command) => command.execute(urls, settings),
Command::RunServer(command) => command.execute(urls, settings),
}
diff --git a/src/db/models/meta.rs b/src/db/models/meta.rs
index 50729a8..16e7290 100644
--- a/src/db/models/meta.rs
+++ b/src/db/models/meta.rs
@@ -1,3 +1,6 @@
+use super::Field;
+
pub struct ModelMeta {
pub name: &'static str,
+ pub fields: &'static [Field],
}
diff --git a/src/db/models/mod.rs b/src/db/models/mod.rs
index feadb43..3f39ccd 100644
--- a/src/db/models/mod.rs
+++ b/src/db/models/mod.rs
@@ -5,6 +5,7 @@ pub use meta::*;
pub type Id = usize;
+#[derive(Clone, Debug)]
pub enum Field {
CharField {
name: &'static str,
diff --git a/tosin-macros/src/lib.rs b/tosin-macros/src/lib.rs
index 531a92b..86750e1 100644
--- a/tosin-macros/src/lib.rs
+++ b/tosin-macros/src/lib.rs
@@ -20,9 +20,11 @@ pub fn model_derive(input: TokenStream) -> TokenStream {
fn impl_model(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let gen = quote! {
+ use tosin::db::models::ModelMeta;
impl #name {
- pub const META: tosin::db::models::ModelMeta = tosin::db::models::ModelMeta {
+ pub const META: ModelMeta = ModelMeta {
name: stringify!(#name),
+ fields: &[],
};
}
};