yauth_migration/
postgres.rs1use super::collector::YAuthSchema;
4use super::types::*;
5
6use std::borrow::Cow;
7
8pub(crate) fn pg_type(col_type: &ColumnType) -> Cow<'static, str> {
10 match col_type {
11 ColumnType::Uuid => Cow::Borrowed("UUID"),
12 ColumnType::Varchar => Cow::Borrowed("VARCHAR"),
13 ColumnType::VarcharN(n) => Cow::Owned(format!("VARCHAR({n})")),
14 ColumnType::Boolean => Cow::Borrowed("BOOLEAN"),
15 ColumnType::DateTime => Cow::Borrowed("TIMESTAMPTZ"),
16 ColumnType::Json => Cow::Borrowed("JSONB"),
17 ColumnType::Int => Cow::Borrowed("INT"),
18 ColumnType::SmallInt => Cow::Borrowed("SMALLINT"),
19 ColumnType::Text => Cow::Borrowed("TEXT"),
20 }
21}
22
23fn pg_on_delete(action: &OnDelete) -> &'static str {
25 match action {
26 OnDelete::Cascade => "ON DELETE CASCADE",
27 OnDelete::SetNull => "ON DELETE SET NULL",
28 OnDelete::Restrict => "ON DELETE RESTRICT",
29 OnDelete::NoAction => "ON DELETE NO ACTION",
30 }
31}
32
33fn generate_create_table(table: &TableDef) -> String {
35 let mut sql = String::new();
36 if let Some(ref desc) = table.description {
37 sql.push_str(&format!("-- {desc}\n"));
38 }
39 sql.push_str(&format!("CREATE TABLE IF NOT EXISTS {} (\n", table.name));
40
41 let col_count = table.columns.len();
42 for (i, col) in table.columns.iter().enumerate() {
43 sql.push_str(" ");
44 sql.push_str(&col.name);
45 sql.push(' ');
46 sql.push_str(&pg_type(&col.col_type));
47
48 if col.primary_key {
49 sql.push_str(" PRIMARY KEY");
50 if let Some(ref default) = col.default {
51 sql.push_str(" DEFAULT ");
52 sql.push_str(default);
53 }
54 if let Some(ref fk) = col.foreign_key {
56 sql.push_str(&format!(
57 " REFERENCES {}({}) {}",
58 fk.references_table,
59 fk.references_column,
60 pg_on_delete(&fk.on_delete)
61 ));
62 }
63 } else if let Some(ref fk) = col.foreign_key {
64 if !col.nullable {
66 sql.push_str(" NOT NULL");
67 }
68 sql.push_str(&format!(
69 " REFERENCES {}({}) {}",
70 fk.references_table,
71 fk.references_column,
72 pg_on_delete(&fk.on_delete)
73 ));
74 if col.unique {
75 sql.push_str(" UNIQUE");
76 }
77 } else {
78 if !col.nullable {
79 sql.push_str(" NOT NULL");
80 }
81 if col.unique {
82 sql.push_str(" UNIQUE");
83 }
84 if let Some(ref default) = col.default {
85 sql.push_str(" DEFAULT ");
86 sql.push_str(default);
87 }
88 }
89
90 if i < col_count - 1 {
91 sql.push(',');
92 }
93 sql.push('\n');
94 }
95
96 sql.push_str(");\n");
97 sql
98}
99
100pub fn generate_postgres_ddl(schema: &YAuthSchema) -> String {
105 let mut ddl = String::new();
106 for (i, table) in schema.tables.iter().enumerate() {
107 if i > 0 {
108 ddl.push('\n');
109 }
110 ddl.push_str(&generate_create_table(table));
111 }
112 ddl
113}
114
115pub fn generate_postgres_drop(table: &TableDef) -> String {
117 format!("DROP TABLE IF EXISTS {} CASCADE;\n", table.name)
118}
119
120pub fn generate_postgres_drops(tables: &[TableDef]) -> String {
122 let mut ddl = String::new();
123 for (i, table) in tables.iter().rev().enumerate() {
124 if i > 0 {
125 ddl.push('\n');
126 }
127 ddl.push_str(&generate_postgres_drop(table));
128 }
129 ddl
130}