doido_generators/generators/
migration_support.rs1use crate::generators::field::Field;
9
10pub const MIGRATION_SRC_DIR: &str = "db/migration/src";
12
13pub const MIGRATION_LIB_BASE: &str = include_str!("../../templates/new/db/migration/src/lib.rs");
16
17pub fn render_migration_file(
20 migration_name: &str,
21 imports: &str,
22 up_body: &str,
23 down_body: &str,
24) -> String {
25 crate::templates::get("migration/migration.rs.template")
26 .replace("{migration_name}", migration_name)
27 .replace("{migration_imports}", imports)
28 .replace("{up_body}", up_body)
29 .replace("{down_body}", down_body)
30}
31
32pub fn create_table_imports(fields: &[Field]) -> String {
36 if fields.iter().any(Field::wants_index) {
37 "use doido::model::migration::{add_index, create_table, drop_table};".to_string()
38 } else {
39 "use doido::model::migration::{create_table, drop_table};".to_string()
40 }
41}
42
43pub fn create_table_up(table_name: &str, fields: &[Field]) -> String {
47 if fields.is_empty() {
49 return format!(
50 " // `create_table` adds an auto-incrementing `id` primary key for you.\n\
51 \x20 // Add columns with the builder, e.g. `t.string(\"name\").not_null();`.\n\
52 \x20 create_table(manager, \"{table_name}\", |_t| {{}}).await\n"
53 );
54 }
55
56 let columns: String = fields
57 .iter()
58 .map(|f| format!(" {}\n", f.migration_line()))
59 .collect();
60
61 let indexes: Vec<&Field> = fields.iter().filter(|f| f.wants_index()).collect();
62
63 let mut body = String::new();
64 body.push_str(
65 " // `create_table` adds an auto-incrementing `id` primary key for you.\n",
66 );
67 body.push_str(&format!(
68 " create_table(manager, \"{table_name}\", |t| {{\n{columns} }})\n"
69 ));
70
71 if indexes.is_empty() {
72 body.push_str(" .await\n");
74 } else {
75 body.push_str(" .await?;\n");
76 for f in indexes {
77 body.push_str(&format!(
78 " add_index(manager, \"{table_name}\", &[\"{}\"]).await?;\n",
79 f.column_name()
80 ));
81 }
82 body.push_str(" Ok(())\n");
83 }
84
85 body
86}
87
88pub fn drop_table_down(table_name: &str) -> String {
90 format!(" drop_table(manager, \"{table_name}\").await\n")
91}
92
93pub fn register_migration(lib: &str, module: &str) -> String {
97 let mut lines: Vec<String> = lib.lines().map(String::from).collect();
98
99 if let Some(i) = lines
100 .iter()
101 .position(|l| l.contains("@generated-migrations-mod"))
102 {
103 lines.insert(i, format!("mod {module};"));
104 }
105
106 if let Some(i) = lines
107 .iter()
108 .position(|l| l.contains("@generated-migrations-list"))
109 {
110 let indent: String = lines[i].chars().take_while(|c| c.is_whitespace()).collect();
111 lines.insert(i, format!("{indent}Box::new({module}::Migration),"));
112 }
113
114 let mut out = lines.join("\n");
115 out.push('\n');
116 out
117}