sea_query/backend/
index_builder.rs

1use crate::*;
2
3pub trait IndexBuilder: QuotedBuilder + TableRefBuilder {
4    /// Translate [`IndexCreateStatement`] into SQL expression.
5    /// This is the default implementation for `PostgresQueryBuilder` and `SqliteQueryBuilder`.
6    /// `MysqlQueryBuilder` overrides this default implementation.
7    fn prepare_table_index_expression(
8        &self,
9        create: &IndexCreateStatement,
10        sql: &mut dyn SqlWriter,
11    ) {
12        if let Some(name) = &create.index.name {
13            sql.write_str("CONSTRAINT ").unwrap();
14            sql.write_char(self.quote().left()).unwrap();
15            sql.write_str(name).unwrap();
16            sql.write_char(self.quote().right()).unwrap();
17            sql.write_str(" ").unwrap();
18        }
19
20        self.prepare_index_prefix(create, sql);
21
22        self.prepare_index_columns(&create.index.columns, sql);
23
24        self.prepare_filter(&create.r#where, sql);
25    }
26
27    /// Translate [`IndexCreateStatement`] into SQL statement.
28    fn prepare_index_create_statement(
29        &self,
30        create: &IndexCreateStatement,
31        sql: &mut dyn SqlWriter,
32    );
33
34    /// Translate [`TableRef`] into SQL statement.
35    fn prepare_table_ref_index_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter);
36
37    /// Translate [`IndexDropStatement`] into SQL statement.
38    fn prepare_index_drop_statement(&self, drop: &IndexDropStatement, sql: &mut dyn SqlWriter);
39
40    #[doc(hidden)]
41    /// Write the index type (Btree, hash, ...).
42    fn prepare_index_type(&self, _col_index_type: &Option<IndexType>, _sql: &mut dyn SqlWriter) {}
43
44    #[doc(hidden)]
45    /// Write the index prefix (primary, unique, ...).
46    fn prepare_index_prefix(&self, create: &IndexCreateStatement, sql: &mut dyn SqlWriter);
47
48    #[doc(hidden)]
49    /// Write the column index prefix.
50    fn write_column_index_prefix(&self, col_prefix: &Option<u32>, sql: &mut dyn SqlWriter) {
51        if let Some(prefix) = col_prefix {
52            sql.write_str(" (").unwrap();
53            write!(sql, "{prefix}").unwrap();
54            sql.write_str(")").unwrap();
55        }
56    }
57
58    #[doc(hidden)]
59    /// Write the index column with table column.
60    fn prepare_index_column_with_table_column(
61        &self,
62        column: &IndexColumnTableColumn,
63        sql: &mut dyn SqlWriter,
64    ) {
65        self.prepare_iden(&column.name, sql);
66        self.write_column_index_prefix(&column.prefix, sql);
67        if let Some(order) = &column.order {
68            match order {
69                IndexOrder::Asc => sql.write_str(" ASC").unwrap(),
70                IndexOrder::Desc => sql.write_str(" DESC").unwrap(),
71            }
72        }
73    }
74
75    #[doc(hidden)]
76    /// Write the column index prefix.
77    fn prepare_index_columns(&self, columns: &[IndexColumn], sql: &mut dyn SqlWriter) {
78        macro_rules! prepare {
79            ($i:ident) => {
80                match $i {
81                    IndexColumn::TableColumn(column) => {
82                        self.prepare_index_column_with_table_column(column, sql);
83                    }
84                    IndexColumn::Expr(_) => panic!("Not supported"),
85                }
86            };
87        }
88
89        sql.write_str("(").unwrap();
90
91        let mut citer = columns.iter();
92
93        if let Some(col) = citer.next() {
94            prepare!(col)
95        }
96
97        for col in citer {
98            sql.write_str(", ").unwrap();
99            prepare!(col)
100        }
101
102        sql.write_str(")").unwrap();
103    }
104
105    #[doc(hidden)]
106    // Write WHERE clause for partial index. This function is not available in MySQL.
107    fn prepare_filter(&self, _condition: &ConditionHolder, _sql: &mut dyn SqlWriter) {}
108}