sea_query/index/
common.rs

1use crate::expr::Expr;
2use crate::{FunctionCall, types::*};
3
4/// Specification of a table index
5#[derive(Default, Debug, Clone)]
6pub struct TableIndex {
7    pub(crate) name: Option<String>,
8    pub(crate) columns: Vec<IndexColumn>,
9}
10
11#[derive(Debug, Clone)]
12#[non_exhaustive]
13pub enum IndexColumn {
14    TableColumn(IndexColumnTableColumn),
15    Expr(IndexColumnExpr),
16}
17
18#[derive(Debug, Clone)]
19pub struct IndexColumnTableColumn {
20    pub(crate) name: DynIden,
21    pub(crate) prefix: Option<u32>,
22    pub(crate) order: Option<IndexOrder>,
23}
24
25#[derive(Debug, Clone)]
26pub struct IndexColumnExpr {
27    pub(crate) expr: Expr,
28    pub(crate) order: Option<IndexOrder>,
29}
30
31impl IndexColumn {
32    /// Get column name for this index component if it's a `TableColumn`, `None` otherwise.
33    pub fn get_col_name(&self) -> Option<&DynIden> {
34        match self {
35            IndexColumn::TableColumn(IndexColumnTableColumn { name, .. }) => Some(name),
36            IndexColumn::Expr(_) => None,
37        }
38    }
39}
40
41#[derive(Debug, Clone)]
42#[non_exhaustive]
43pub enum IndexOrder {
44    Asc,
45    Desc,
46}
47
48pub trait IntoIndexColumn: Into<IndexColumn> {
49    fn into_index_column(self) -> IndexColumn;
50}
51
52impl<T> IntoIndexColumn for T
53where
54    T: Into<IndexColumn>,
55{
56    fn into_index_column(self) -> IndexColumn {
57        self.into()
58    }
59}
60
61impl<I> From<I> for IndexColumn
62where
63    I: IntoIden,
64{
65    fn from(value: I) -> Self {
66        IndexColumn::TableColumn(IndexColumnTableColumn {
67            name: value.into_iden(),
68            prefix: None,
69            order: None,
70        })
71    }
72}
73
74impl<I> From<(I, u32)> for IndexColumn
75where
76    I: IntoIden,
77{
78    fn from(value: (I, u32)) -> Self {
79        IndexColumn::TableColumn(IndexColumnTableColumn {
80            name: value.0.into_iden(),
81            prefix: Some(value.1),
82            order: None,
83        })
84    }
85}
86
87impl<I> From<(I, IndexOrder)> for IndexColumn
88where
89    I: IntoIden,
90{
91    fn from(value: (I, IndexOrder)) -> Self {
92        IndexColumn::TableColumn(IndexColumnTableColumn {
93            name: value.0.into_iden(),
94            prefix: None,
95            order: Some(value.1),
96        })
97    }
98}
99
100impl<I> From<(I, u32, IndexOrder)> for IndexColumn
101where
102    I: IntoIden,
103{
104    fn from(value: (I, u32, IndexOrder)) -> Self {
105        IndexColumn::TableColumn(IndexColumnTableColumn {
106            name: value.0.into_iden(),
107            prefix: Some(value.1),
108            order: Some(value.2),
109        })
110    }
111}
112
113impl From<FunctionCall> for IndexColumn {
114    fn from(value: FunctionCall) -> Self {
115        IndexColumn::Expr(IndexColumnExpr {
116            expr: value.into(),
117            order: None,
118        })
119    }
120}
121
122impl From<(FunctionCall, IndexOrder)> for IndexColumn {
123    fn from(value: (FunctionCall, IndexOrder)) -> Self {
124        IndexColumn::Expr(IndexColumnExpr {
125            expr: value.0.into(),
126            order: Some(value.1),
127        })
128    }
129}
130
131impl From<Expr> for IndexColumn {
132    fn from(value: Expr) -> Self {
133        IndexColumn::Expr(IndexColumnExpr {
134            expr: value,
135            order: None,
136        })
137    }
138}
139
140impl From<(Expr, IndexOrder)> for IndexColumn {
141    fn from(value: (Expr, IndexOrder)) -> Self {
142        IndexColumn::Expr(IndexColumnExpr {
143            expr: value.0,
144            order: Some(value.1),
145        })
146    }
147}
148
149impl TableIndex {
150    /// Construct a new table index
151    pub fn new() -> Self {
152        Self::default()
153    }
154
155    /// Set index name
156    pub fn name<T>(&mut self, name: T) -> &mut Self
157    where
158        T: Into<String>,
159    {
160        self.name = Some(name.into());
161        self
162    }
163
164    /// Set index column
165    pub fn col(&mut self, col: IndexColumn) -> &mut Self {
166        self.columns.push(col);
167        self
168    }
169
170    pub fn get_name(&self) -> Option<&str> {
171        self.name.as_deref()
172    }
173
174    pub fn get_column_names(&self) -> Vec<String> {
175        self.columns
176            .iter()
177            .filter_map(|col| col.get_col_name().map(|name| name.to_string()))
178            .collect()
179    }
180
181    pub fn take(&mut self) -> Self {
182        Self {
183            name: self.name.take(),
184            columns: std::mem::take(&mut self.columns),
185        }
186    }
187}