Fix to_sql method on BTreeTable to include foreign keys

This commit is contained in:
PThorpe92
2025-10-18 13:20:18 -04:00
parent 43681379a0
commit 4dcabf37f1

View File

@@ -1358,12 +1358,13 @@ impl BTreeTable {
/// `CREATE TABLE t (x)`, whereas sqlite stores it with the original extra whitespace.
pub fn to_sql(&self) -> String {
let mut sql = format!("CREATE TABLE {} (", self.name);
// Add columns
for (i, column) in self.columns.iter().enumerate() {
if i > 0 {
sql.push_str(", ");
}
// we need to wrap the column name in square brackets if it contains special characters
// Wrap column name in square brackets if it contains special characters
let column_name = column.name.as_ref().expect("column name is None");
if identifier_contains_special_chars(column_name) {
sql.push('[');
@@ -1372,7 +1373,6 @@ impl BTreeTable {
} else {
sql.push_str(column_name);
}
if !column.ty_str.is_empty() {
sql.push(' ');
sql.push_str(&column.ty_str);
@@ -1380,20 +1380,75 @@ impl BTreeTable {
if column.notnull {
sql.push_str(" NOT NULL");
}
if column.unique {
sql.push_str(" UNIQUE");
}
if column.primary_key {
sql.push_str(" PRIMARY KEY");
}
if let Some(default) = &column.default {
sql.push_str(" DEFAULT ");
sql.push_str(&default.to_string());
}
}
let has_table_pk = !self.primary_key_columns.is_empty();
// Add table-level PRIMARY KEY constraint if exists
if has_table_pk {
sql.push_str(", PRIMARY KEY (");
for (i, col) in self.primary_key_columns.iter().enumerate() {
if i > 0 {
sql.push_str(", ");
}
sql.push_str(&col.0);
}
sql.push(')');
}
for fk in &self.foreign_keys {
sql.push_str(", FOREIGN KEY (");
for (i, col) in fk.child_columns.iter().enumerate() {
if i > 0 {
sql.push_str(", ");
}
sql.push_str(col);
}
sql.push_str(") REFERENCES ");
sql.push_str(&fk.parent_table);
sql.push('(');
for (i, col) in fk.parent_columns.iter().enumerate() {
if i > 0 {
sql.push_str(", ");
}
sql.push_str(col);
}
sql.push(')');
// Add ON DELETE/UPDATE actions, NoAction is default so just make empty in that case
if fk.on_delete != RefAct::NoAction {
sql.push_str(" ON DELETE ");
sql.push_str(match fk.on_delete {
RefAct::SetNull => "SET NULL",
RefAct::SetDefault => "SET DEFAULT",
RefAct::Cascade => "CASCADE",
RefAct::Restrict => "RESTRICT",
_ => "",
});
}
if fk.on_update != RefAct::NoAction {
sql.push_str(" ON UPDATE ");
sql.push_str(match fk.on_update {
RefAct::SetNull => "SET NULL",
RefAct::SetDefault => "SET DEFAULT",
RefAct::Cascade => "CASCADE",
RefAct::Restrict => "RESTRICT",
_ => "",
});
}
if fk.deferred {
sql.push_str(" DEFERRABLE INITIALLY DEFERRED");
}
}
sql.push(')');
sql
}