sea_schema/postgres/query/
pg_indexes.rs

1use 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}