doido_model/migration/
foreign_key.rs1use sea_orm::sea_query::{
4 Alias, ForeignKey as SqForeignKey, ForeignKeyCreateStatement, ForeignKeyDropStatement,
5};
6use sea_orm::{ConnectionTrait, DbErr};
7use sea_orm_migration::SchemaManager;
8
9fn foreign_key_name(table: &str, column: &str) -> String {
11 format!("fk_{table}_{column}")
12}
13
14fn add_foreign_key_statement(
15 from_table: &str,
16 from_column: &str,
17 to_table: &str,
18 to_column: &str,
19) -> ForeignKeyCreateStatement {
20 let mut stmt = SqForeignKey::create();
21 stmt.name(foreign_key_name(from_table, from_column))
22 .from(Alias::new(from_table), Alias::new(from_column))
23 .to(Alias::new(to_table), Alias::new(to_column));
24 stmt
25}
26
27fn remove_foreign_key_statement(from_table: &str, from_column: &str) -> ForeignKeyDropStatement {
28 let mut stmt = SqForeignKey::drop();
29 stmt.name(foreign_key_name(from_table, from_column))
30 .table(Alias::new(from_table));
31 stmt
32}
33
34pub async fn add_foreign_key(
41 manager: &SchemaManager<'_>,
42 from_table: &str,
43 from_column: &str,
44 to_table: &str,
45 to_column: &str,
46) -> Result<(), DbErr> {
47 manager
48 .get_connection()
49 .execute(&add_foreign_key_statement(
50 from_table,
51 from_column,
52 to_table,
53 to_column,
54 ))
55 .await
56 .map(|_| ())
57}
58
59pub async fn remove_foreign_key(
61 manager: &SchemaManager<'_>,
62 from_table: &str,
63 from_column: &str,
64) -> Result<(), DbErr> {
65 manager
66 .get_connection()
67 .execute(&remove_foreign_key_statement(from_table, from_column))
68 .await
69 .map(|_| ())
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use sea_orm::sea_query::PostgresQueryBuilder;
76
77 #[test]
78 fn foreign_key_name_is_derived() {
79 assert_eq!(foreign_key_name("posts", "user_id"), "fk_posts_user_id");
80 }
81
82 #[test]
83 fn add_foreign_key_renders_constraint() {
84 let sql = add_foreign_key_statement("posts", "user_id", "users", "id")
85 .to_string(PostgresQueryBuilder);
86 assert!(sql.contains("\"fk_posts_user_id\""));
87 assert!(sql.contains("\"posts\""));
88 assert!(sql.contains("\"users\""));
89 }
90}