sea_schema/postgres/query/
pg_indexes.rs1use super::SchemaQueryBuilder;
2use crate::sqlx_types::postgres::PgRow;
3use sea_query::{Alias, Condition, Expr, Iden, JoinType, Order, Query, SeaRc, SelectStatement};
4
5#[derive(Debug, Iden)]
6pub enum PgIndexes {
7 Table,
8 #[iden = "tablename"]
9 TableName,
10 #[iden = "schemaname"]
11 SchemaName,
12 #[iden = "indexname"]
13 IndexName,
14}
15
16#[derive(Debug, Iden)]
17pub enum PgIndex {
18 Table,
19 #[iden = "indexrelid"]
20 IndexRelId,
21 #[iden = "indrelid"]
22 IndRelId,
23 #[iden = "indisunique"]
24 IndIsUnique,
25 #[iden = "indisprimary"]
26 IndIsPrimary,
27}
28
29#[derive(Debug, Iden)]
30pub enum PgClass {
31 Table,
32 Oid,
33 #[iden = "relnamespace"]
34 RelNamespace,
35 #[iden = "relname"]
36 RelName,
37}
38
39#[derive(Debug, Iden)]
40pub enum PgNamespace {
41 Table,
42 Oid,
43 #[iden = "nspname"]
44 NspName,
45}
46
47#[derive(Debug, Iden)]
48pub enum PgAttribute {
49 Table,
50 Oid,
51 #[iden = "attrelid"]
52 AttRelId,
53 #[iden = "attname"]
54 AttName,
55}
56
57#[derive(Debug, Default)]
58pub struct UniqueIndexQueryResult {
59 pub index_name: String,
60 pub table_schema: String,
61 pub table_name: String,
62 pub column_name: String,
63}
64
65impl SchemaQueryBuilder {
66 pub fn query_table_unique_indexes(
67 &self,
68 schema: SeaRc<dyn Iden>,
69 table: SeaRc<dyn Iden>,
70 ) -> SelectStatement {
71 let idx = Alias::new("idx");
72 let insp = Alias::new("insp");
73 let tbl = Alias::new("tbl");
74 let tnsp = Alias::new("tnsp");
75 let col = Alias::new("col");
76
77 Query::select()
78 .column((idx.clone(), PgClass::RelName))
79 .column((insp.clone(), PgNamespace::NspName))
80 .column((tbl.clone(), PgClass::RelName))
81 .column((col.clone(), PgAttribute::AttName))
82 .from(PgIndex::Table)
83 .join_as(
84 JoinType::Join,
85 PgClass::Table,
86 idx.clone(),
87 Expr::col((idx.clone(), PgClass::Oid))
88 .equals((PgIndex::Table, PgIndex::IndexRelId)),
89 )
90 .join_as(
91 JoinType::Join,
92 PgNamespace::Table,
93 insp.clone(),
94 Expr::col((insp.clone(), PgNamespace::Oid))
95 .equals((idx.clone(), PgClass::RelNamespace)),
96 )
97 .join_as(
98 JoinType::Join,
99 PgClass::Table,
100 tbl.clone(),
101 Expr::col((tbl.clone(), PgClass::Oid)).equals((PgIndex::Table, PgIndex::IndRelId)),
102 )
103 .join_as(
104 JoinType::Join,
105 PgNamespace::Table,
106 tnsp.clone(),
107 Expr::col((tnsp.clone(), PgNamespace::Oid))
108 .equals((tbl.clone(), PgClass::RelNamespace)),
109 )
110 .join_as(
111 JoinType::Join,
112 PgAttribute::Table,
113 col.clone(),
114 Expr::col((col.clone(), PgAttribute::AttRelId))
115 .equals((idx.clone(), PgAttribute::Oid)),
116 )
117 .cond_where(
118 Condition::all()
119 .add(Expr::col((PgIndex::Table, PgIndex::IndIsUnique)).eq(true))
120 .add(Expr::col((PgIndex::Table, PgIndex::IndIsPrimary)).eq(false))
121 .add(Expr::col((tbl.clone(), PgClass::RelName)).eq(table.to_string()))
122 .add(Expr::col((tnsp.clone(), PgNamespace::NspName)).eq(schema.to_string())),
123 )
124 .order_by((PgIndex::Table, PgIndex::IndexRelId), Order::Asc)
125 .take()
126 }
127}
128
129#[cfg(feature = "sqlx-postgres")]
130impl From<&PgRow> for UniqueIndexQueryResult {
131 fn from(row: &PgRow) -> Self {
132 use crate::sqlx_types::Row;
133 Self {
134 index_name: row.get(0),
135 table_schema: row.get(1),
136 table_name: row.get(2),
137 column_name: row.get(3),
138 }
139 }
140}
141
142#[cfg(not(feature = "sqlx-postgres"))]
143impl From<&PgRow> for UniqueIndexQueryResult {
144 fn from(_: &PgRow) -> Self {
145 Self::default()
146 }
147}