-
Notifications
You must be signed in to change notification settings - Fork 255
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
657 additions
and
626 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use cruet::{case::snake::to_snake_case, Inflector}; // For pluralization and singularization | ||
|
||
#[derive(Debug, PartialEq, Eq)] | ||
pub enum MigrationType { | ||
CreateTable { table: String }, | ||
AddColumns { table: String }, | ||
RemoveColumns { table: String }, | ||
AddReference { table: String }, | ||
CreateJoinTable { table_a: String, table_b: String }, | ||
Empty, | ||
} | ||
|
||
pub fn guess_migration_type(migration_name: &str) -> MigrationType { | ||
let normalized_name = to_snake_case(migration_name); | ||
let parts: Vec<&str> = normalized_name.split('_').collect(); | ||
|
||
match parts.as_slice() { | ||
["create", table_name] => MigrationType::CreateTable { | ||
table: table_name.to_plural(), | ||
}, | ||
["add", _reference_name, "ref", "to", table_name] => MigrationType::AddReference { | ||
table: table_name.to_plural(), | ||
}, | ||
["add", _column_names @ .., "to", table_name] => MigrationType::AddColumns { | ||
table: table_name.to_plural(), | ||
}, | ||
["remove", _column_names @ .., "from", table_name] => MigrationType::RemoveColumns { | ||
table: table_name.to_plural(), | ||
}, | ||
["create", "join", "table", table_a, "and", table_b] => { | ||
let table_a = table_a.to_singular(); | ||
let table_b = table_b.to_singular(); | ||
MigrationType::CreateJoinTable { table_a, table_b } | ||
} | ||
_ => MigrationType::Empty, | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_infer_create_table() { | ||
assert_eq!( | ||
guess_migration_type("CreateUsers"), | ||
MigrationType::CreateTable { | ||
table: "users".to_string(), | ||
} | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_infer_add_columns() { | ||
assert_eq!( | ||
guess_migration_type("AddNameAndAgeToUsers"), | ||
MigrationType::AddColumns { | ||
table: "users".to_string(), | ||
} | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_infer_remove_columns() { | ||
assert_eq!( | ||
guess_migration_type("RemoveNameAndAgeFromUsers"), | ||
MigrationType::RemoveColumns { | ||
table: "users".to_string(), | ||
} | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_infer_add_reference() { | ||
assert_eq!( | ||
guess_migration_type("AddUserRefToPosts"), | ||
MigrationType::AddReference { | ||
table: "posts".to_string(), | ||
} | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_infer_create_join_table() { | ||
assert_eq!( | ||
guess_migration_type("CreateJoinTableUsersAndGroups"), | ||
MigrationType::CreateJoinTable { | ||
table_a: "user".to_string(), | ||
table_b: "group".to_string() | ||
} | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_empty_migration() { | ||
assert_eq!( | ||
guess_migration_type("UnknownMigrationType"), | ||
MigrationType::Empty | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
use chrono::Utc; | ||
use rrgen::RRgen; | ||
use serde_json::json; | ||
|
||
use super::Result; | ||
use crate::{ | ||
infer, | ||
model::{get_columns_and_references, MODEL_T}, | ||
}; | ||
|
||
const MIGRATION_T: &str = include_str!("templates/migration/empty.t"); | ||
const ADD_COLS_T: &str = include_str!("templates/migration/add_columns.t"); | ||
const ADD_REFS_T: &str = include_str!("templates/migration/add_references.t"); | ||
const REMOVE_COLS_T: &str = include_str!("templates/migration/remove_columns.t"); | ||
const JOIN_TABLE_T: &str = include_str!("templates/migration/join_table.t"); | ||
|
||
use super::{collect_messages, AppInfo}; | ||
|
||
/// skipping some fields from the generated models. | ||
/// For example, the `created_at` and `updated_at` fields are automatically | ||
/// generated by the Loco app and should be given | ||
pub const IGNORE_FIELDS: &[&str] = &["created_at", "updated_at", "create_at", "update_at"]; | ||
|
||
pub fn generate( | ||
rrgen: &RRgen, | ||
name: &str, | ||
fields: &[(String, String)], | ||
appinfo: &AppInfo, | ||
) -> Result<String> { | ||
let pkg_name: &str = &appinfo.app_name; | ||
let ts = Utc::now(); | ||
|
||
let res = infer::guess_migration_type(name); | ||
let migration_gen = match res { | ||
// NOTE: re-uses the 'new model' migration template! | ||
infer::MigrationType::CreateTable { table } => { | ||
let (columns, references) = get_columns_and_references(fields)?; | ||
let vars = json!({"name": table, "ts": ts, "pkg_name": pkg_name, "is_link": false, "columns": columns, "references": references}); | ||
rrgen.generate(MODEL_T, &vars)? | ||
} | ||
infer::MigrationType::AddColumns { table } => { | ||
let (columns, references) = get_columns_and_references(fields)?; | ||
let vars = json!({"name": name, "table": table, "ts": ts, "pkg_name": pkg_name, "is_link": false, "columns": columns, "references": references}); | ||
rrgen.generate(ADD_COLS_T, &vars)? | ||
} | ||
infer::MigrationType::RemoveColumns { table } => { | ||
let (columns, _references) = get_columns_and_references(fields)?; | ||
let vars = json!({"name": name, "table": table, "ts": ts, "pkg_name": pkg_name, "columns": columns}); | ||
rrgen.generate(REMOVE_COLS_T, &vars)? | ||
} | ||
infer::MigrationType::AddReference { table } => { | ||
let (columns, references) = get_columns_and_references(fields)?; | ||
let vars = json!({"name": name, "table": table, "ts": ts, "pkg_name": pkg_name, "columns": columns, "references": references}); | ||
rrgen.generate(ADD_REFS_T, &vars)? | ||
} | ||
infer::MigrationType::CreateJoinTable { table_a, table_b } => { | ||
let mut tables = [table_a.clone(), table_b.clone()]; | ||
tables.sort(); | ||
let table = tables.join("_"); | ||
let (columns, references) = get_columns_and_references(&[ | ||
(table_a, "references".to_string()), | ||
(table_b, "references".to_string()), | ||
])?; | ||
let vars = json!({"name": name, "table": table, "ts": ts, "pkg_name": pkg_name, "columns": columns, "references": references}); | ||
rrgen.generate(JOIN_TABLE_T, &vars)? | ||
} | ||
infer::MigrationType::Empty => { | ||
let vars = json!({"name": name, "ts": ts, "pkg_name": pkg_name}); | ||
rrgen.generate(MIGRATION_T, &vars)? | ||
} | ||
}; | ||
|
||
let messages = collect_messages(vec![migration_gen]); | ||
Ok(messages) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.