sea_query/index/
common.rs

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