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 = format!("CREATE TABLE IF NOT EXISTS {} (\n", table.name);
36
37 let col_count = table.columns.len();
38 for (i, col) in table.columns.iter().enumerate() {
39 sql.push_str(" ");
40 sql.push_str(&col.name);
41 sql.push(' ');
42 sql.push_str(&pg_type(&col.col_type));
43
44 if col.primary_key {
45 sql.push_str(" PRIMARY KEY");
46 if let Some(ref default) = col.default {
47 sql.push_str(" DEFAULT ");
48 sql.push_str(default);
49 }
50 if let Some(ref fk) = col.foreign_key {
52 sql.push_str(&format!(
53 " REFERENCES {}({}) {}",
54 fk.references_table,
55 fk.references_column,
56 pg_on_delete(&fk.on_delete)
57 ));
58 }
59 } else if let Some(ref fk) = col.foreign_key {
60 if !col.nullable {
62 sql.push_str(" NOT NULL");
63 }
64 sql.push_str(&format!(
65 " REFERENCES {}({}) {}",
66 fk.references_table,
67 fk.references_column,
68 pg_on_delete(&fk.on_delete)
69 ));
70 if col.unique {
71 sql.push_str(" UNIQUE");
72 }
73 } else {
74 if !col.nullable {
75 sql.push_str(" NOT NULL");
76 }
77 if col.unique {
78 sql.push_str(" UNIQUE");
79 }
80 if let Some(ref default) = col.default {
81 sql.push_str(" DEFAULT ");
82 sql.push_str(default);
83 }
84 }
85
86 if i < col_count - 1 {
87 sql.push(',');
88 }
89 sql.push('\n');
90 }
91
92 sql.push_str(");\n");
93 sql
94}
95
96pub fn generate_postgres_ddl(schema: &YAuthSchema) -> String {
101 let mut ddl = String::new();
102 for (i, table) in schema.tables.iter().enumerate() {
103 if i > 0 {
104 ddl.push('\n');
105 }
106 ddl.push_str(&generate_create_table(table));
107 }
108 ddl
109}
110
111pub fn generate_postgres_drop(table: &TableDef) -> String {
113 format!("DROP TABLE IF EXISTS {} CASCADE;\n", table.name)
114}
115
116pub fn generate_postgres_drops(tables: &[TableDef]) -> String {
118 let mut ddl = String::new();
119 for (i, table) in tables.iter().rev().enumerate() {
120 if i > 0 {
121 ddl.push('\n');
122 }
123 ddl.push_str(&generate_postgres_drop(table));
124 }
125 ddl
126}