sea_schema/mysql/query/
foreign_key.rs1use super::{InformationSchema, SchemaQueryBuilder};
2use crate::sqlx_types::SqlxRow;
3use sea_query::{DynIden, Expr, ExprTrait, Order, Query, SelectStatement};
4
5#[derive(Debug, sea_query::Iden)]
6pub enum KeyColumnUsageFields {
8 ConstraintSchema,
9 ConstraintName,
10 TableSchema,
11 TableName,
12 ColumnName,
13 OrdinalPosition,
14 PositionInUniqueConstraint,
15 ReferencedTableSchema,
16 ReferencedTableName,
17 ReferencedColumnName,
18}
19
20#[derive(Debug, sea_query::Iden)]
21pub enum ReferentialConstraintsFields {
23 ConstraintSchema,
24 ConstraintName,
25 UniqueConstraintSchema,
26 UniqueConstraintName,
27 UpdateRule,
28 DeleteRule,
29 TableName,
30 ReferencedTableName,
31}
32
33#[derive(Debug, Default)]
34pub struct ForeignKeyQueryResult {
35 pub constraint_name: String,
36 pub column_name: String,
37 pub referenced_table_name: String,
38 pub referenced_column_name: String,
39 pub update_rule: String,
40 pub delete_rule: String,
41}
42
43impl SchemaQueryBuilder {
44 pub fn query_foreign_key(&self, schema: DynIden, table: DynIden) -> SelectStatement {
45 type Schema = InformationSchema;
46 type Key = KeyColumnUsageFields;
47 type Ref = ReferentialConstraintsFields;
48 Query::select()
49 .columns(vec![
50 (Schema::KeyColumnUsage, Key::ConstraintName),
51 (Schema::KeyColumnUsage, Key::ColumnName),
52 (Schema::KeyColumnUsage, Key::ReferencedTableName),
53 (Schema::KeyColumnUsage, Key::ReferencedColumnName),
54 ])
55 .columns(vec![
56 (Schema::ReferentialConstraints, Ref::UpdateRule),
57 (Schema::ReferentialConstraints, Ref::DeleteRule),
58 ])
59 .from((Schema::Schema, Schema::KeyColumnUsage))
60 .inner_join(
61 (Schema::Schema, Schema::ReferentialConstraints),
62 Expr::col((Schema::KeyColumnUsage, Key::ConstraintSchema))
63 .equals((Schema::ReferentialConstraints, Ref::ConstraintSchema))
64 .and(
65 Expr::col((Schema::KeyColumnUsage, Key::ConstraintName))
66 .equals((Schema::ReferentialConstraints, Ref::ConstraintName)),
67 ),
68 )
69 .and_where(
70 Expr::col((Schema::KeyColumnUsage, Key::ConstraintSchema)).eq(schema.to_string()),
71 )
72 .and_where(Expr::col((Schema::KeyColumnUsage, Key::TableName)).eq(table.to_string()))
73 .and_where(Expr::col((Schema::KeyColumnUsage, Key::ReferencedTableName)).is_not_null())
74 .and_where(Expr::col((Schema::KeyColumnUsage, Key::ReferencedColumnName)).is_not_null())
75 .order_by(Key::ConstraintName, Order::Asc)
76 .order_by(Key::OrdinalPosition, Order::Asc)
77 .take()
78 }
79}
80
81#[cfg(feature = "sqlx-mysql")]
82impl From<SqlxRow> for ForeignKeyQueryResult {
83 fn from(row: SqlxRow) -> Self {
84 let row = row.mysql();
85 use crate::mysql::discovery::GetMySqlValue;
86 Self {
87 constraint_name: row.get_string(0),
88 column_name: row.get_string(1),
89 referenced_table_name: row.get_string(2),
90 referenced_column_name: row.get_string(3),
91 update_rule: row.get_string(4),
92 delete_rule: row.get_string(5),
93 }
94 }
95}
96
97#[cfg(not(feature = "sqlx-mysql"))]
98impl From<SqlxRow> for ForeignKeyQueryResult {
99 fn from(_: SqlxRow) -> Self {
100 Self::default()
101 }
102}