Name conflict of foreign key constraints when two entities have more than one foreign keys (#417)
* fix: name conflict of foreign key constraints when two entities have more than one fk * test: update test case's foreign keys * feat: override default name of foreign key constraint
This commit is contained in:
parent
946a03b426
commit
76c0d7fff5
@ -28,5 +28,6 @@ pub mod field_attr {
|
||||
pub on_delete: Option<syn::Lit>,
|
||||
pub from: Option<syn::Lit>,
|
||||
pub to: Option<syn::Lit>,
|
||||
pub fk_name: Option<syn::Lit>,
|
||||
}
|
||||
}
|
||||
|
@ -136,6 +136,22 @@ impl DeriveRelation {
|
||||
result = quote! { #result.on_delete(sea_orm::prelude::ForeignKeyAction::#on_delete) };
|
||||
}
|
||||
|
||||
if attr.fk_name.is_some() {
|
||||
let fk_name = attr
|
||||
.fk_name
|
||||
.as_ref()
|
||||
.map(|lit| {
|
||||
match lit {
|
||||
syn::Lit::Str(lit_str) => Ok(lit_str.value()),
|
||||
_ => Err(syn::Error::new_spanned(lit, "attribute must be a string")),
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
syn::Error::new_spanned(variant, "Missing value for 'fk_name'")
|
||||
})??;
|
||||
result = quote! { #result.fk_name(#fk_name) };
|
||||
}
|
||||
|
||||
result = quote! { #result.into() };
|
||||
|
||||
Result::<_, syn::Error>::Ok(result)
|
||||
|
@ -62,6 +62,8 @@ pub struct RelationDef {
|
||||
/// Defines an operation to be performed on a Foreign Key when a
|
||||
/// `UPDATE` Operation is performed
|
||||
pub on_update: Option<ForeignKeyAction>,
|
||||
/// The name of foreign key constraint
|
||||
pub fk_name: Option<String>,
|
||||
}
|
||||
|
||||
/// Defines a helper to build a relation
|
||||
@ -80,6 +82,7 @@ where
|
||||
is_owner: bool,
|
||||
on_delete: Option<ForeignKeyAction>,
|
||||
on_update: Option<ForeignKeyAction>,
|
||||
fk_name: Option<String>,
|
||||
}
|
||||
|
||||
impl RelationDef {
|
||||
@ -94,6 +97,7 @@ impl RelationDef {
|
||||
is_owner: !self.is_owner,
|
||||
on_delete: self.on_delete,
|
||||
on_update: self.on_update,
|
||||
fk_name: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,6 +118,7 @@ where
|
||||
is_owner,
|
||||
on_delete: None,
|
||||
on_update: None,
|
||||
fk_name: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,6 +133,7 @@ where
|
||||
is_owner,
|
||||
on_delete: None,
|
||||
on_update: None,
|
||||
fk_name: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +166,12 @@ where
|
||||
self.on_update = Some(action);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the name of foreign key constraint
|
||||
pub fn fk_name(mut self, fk_name: &str) -> Self {
|
||||
self.fk_name = Some(fk_name.to_owned());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, R> From<RelationBuilder<E, R>> for RelationDef
|
||||
@ -177,6 +189,7 @@ where
|
||||
is_owner: b.is_owner,
|
||||
on_delete: b.on_delete,
|
||||
on_update: b.on_update,
|
||||
fk_name: b.fk_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,20 +144,18 @@ where
|
||||
let mut foreign_key_stmt = ForeignKeyCreateStatement::new();
|
||||
let from_tbl = unpack_table_ref(&relation.from_tbl);
|
||||
let to_tbl = unpack_table_ref(&relation.to_tbl);
|
||||
match relation.from_col {
|
||||
Identity::Unary(o1) => {
|
||||
foreign_key_stmt.from_col(o1);
|
||||
}
|
||||
Identity::Binary(o1, o2) => {
|
||||
foreign_key_stmt.from_col(o1);
|
||||
foreign_key_stmt.from_col(o2);
|
||||
}
|
||||
Identity::Ternary(o1, o2, o3) => {
|
||||
foreign_key_stmt.from_col(o1);
|
||||
foreign_key_stmt.from_col(o2);
|
||||
foreign_key_stmt.from_col(o3);
|
||||
}
|
||||
let from_cols: Vec<String> = match relation.from_col {
|
||||
Identity::Unary(o1) => vec![o1],
|
||||
Identity::Binary(o1, o2) => vec![o1, o2],
|
||||
Identity::Ternary(o1, o2, o3) => vec![o1, o2, o3],
|
||||
}
|
||||
.into_iter()
|
||||
.map(|col| {
|
||||
let col_name = col.to_string();
|
||||
foreign_key_stmt.from_col(col);
|
||||
col_name
|
||||
})
|
||||
.collect();
|
||||
match relation.to_col {
|
||||
Identity::Unary(o1) => {
|
||||
foreign_key_stmt.to_col(o1);
|
||||
@ -166,7 +164,7 @@ where
|
||||
foreign_key_stmt.to_col(o1);
|
||||
foreign_key_stmt.to_col(o2);
|
||||
}
|
||||
crate::Identity::Ternary(o1, o2, o3) => {
|
||||
Identity::Ternary(o1, o2, o3) => {
|
||||
foreign_key_stmt.to_col(o1);
|
||||
foreign_key_stmt.to_col(o2);
|
||||
foreign_key_stmt.to_col(o3);
|
||||
@ -178,13 +176,14 @@ where
|
||||
if let Some(action) = relation.on_update {
|
||||
foreign_key_stmt.on_update(action);
|
||||
}
|
||||
let name = if let Some(name) = relation.fk_name {
|
||||
name
|
||||
} else {
|
||||
format!("fk-{}-{}", from_tbl.to_string(), from_cols.join("-"))
|
||||
};
|
||||
stmt.foreign_key(
|
||||
foreign_key_stmt
|
||||
.name(&format!(
|
||||
"fk-{}-{}",
|
||||
from_tbl.to_string(),
|
||||
to_tbl.to_string()
|
||||
))
|
||||
.name(&name)
|
||||
.from_tbl(from_tbl)
|
||||
.to_tbl(to_tbl),
|
||||
);
|
||||
@ -235,7 +234,7 @@ mod tests {
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKeyCreateStatement::new()
|
||||
.name("fk-cake_filling_price-cake_filling")
|
||||
.name("fk-cake_filling_price-cake_id-filling_id")
|
||||
.from_tbl(CakeFillingPrice)
|
||||
.from_col(cake_filling_price::Column::CakeId)
|
||||
.from_col(cake_filling_price::Column::FillingId)
|
||||
|
@ -55,7 +55,7 @@ pub async fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
.col(ColumnDef::new(baker::Column::BakeryId).integer())
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-baker-bakery")
|
||||
.name("fk-baker-bakery_id")
|
||||
.from(baker::Entity, baker::Column::BakeryId)
|
||||
.to(bakery::Entity, bakery::Column::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
@ -111,7 +111,7 @@ pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-order-bakery")
|
||||
.name("fk-order-bakery_id")
|
||||
.from(order::Entity, order::Column::BakeryId)
|
||||
.to(bakery::Entity, bakery::Column::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
@ -119,7 +119,7 @@ pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-order-customer")
|
||||
.name("fk-order-customer_id")
|
||||
.from(order::Entity, order::Column::CustomerId)
|
||||
.to(customer::Entity, customer::Column::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
@ -162,7 +162,7 @@ pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-lineitem-order")
|
||||
.name("fk-lineitem-order_id")
|
||||
.from(lineitem::Entity, lineitem::Column::OrderId)
|
||||
.to(order::Entity, order::Column::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
@ -170,7 +170,7 @@ pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-lineitem-cake")
|
||||
.name("fk-lineitem-cake_id")
|
||||
.from(lineitem::Entity, lineitem::Column::CakeId)
|
||||
.to(cake::Entity, cake::Column::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
@ -202,7 +202,7 @@ pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr>
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-cakes_bakers-cake")
|
||||
.name("fk-cakes_bakers-cake_id")
|
||||
.from(cakes_bakers::Entity, cakes_bakers::Column::CakeId)
|
||||
.to(cake::Entity, cake::Column::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
@ -210,7 +210,7 @@ pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr>
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-cakes_bakers-baker")
|
||||
.name("fk-cakes_bakers-baker_id")
|
||||
.from(cakes_bakers::Entity, cakes_bakers::Column::BakerId)
|
||||
.to(baker::Entity, baker::Column::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
@ -240,7 +240,7 @@ pub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
.col(ColumnDef::new(cake::Column::BakeryId).integer())
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-cake-bakery")
|
||||
.name("fk-cake-bakery_id")
|
||||
.from(cake::Entity, cake::Column::BakeryId)
|
||||
.to(bakery::Entity, bakery::Column::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
|
@ -16,6 +16,7 @@ pub struct Model {
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
fk_name = "fk-active_enum_child-active_enum",
|
||||
belongs_to = "super::active_enum::Entity",
|
||||
from = "Column::ParentId",
|
||||
to = "super::active_enum::Column::Id"
|
||||
|
@ -116,7 +116,7 @@ pub async fn create_self_join_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
.col(ColumnDef::new(self_join::Column::Time).time())
|
||||
.foreign_key(
|
||||
ForeignKeyCreateStatement::new()
|
||||
.name("fk-self_join-self_join")
|
||||
.name("fk-self_join-uuid_ref")
|
||||
.from_tbl(SelfJoin)
|
||||
.from_col(self_join::Column::UuidRef)
|
||||
.to_tbl(SelfJoin)
|
||||
|
Loading…
x
Reference in New Issue
Block a user