Skip to main content

sql_orm_query/
expr.rs

1use sql_orm_core::{Entity, EntityColumn, SqlValue};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub struct TableRef {
5    pub schema: &'static str,
6    pub table: &'static str,
7    pub alias: Option<&'static str>,
8}
9
10impl TableRef {
11    pub const fn new(schema: &'static str, table: &'static str) -> Self {
12        Self {
13            schema,
14            table,
15            alias: None,
16        }
17    }
18
19    pub const fn with_alias(
20        schema: &'static str,
21        table: &'static str,
22        alias: &'static str,
23    ) -> Self {
24        Self {
25            schema,
26            table,
27            alias: Some(alias),
28        }
29    }
30
31    pub fn for_entity<E: Entity>() -> Self {
32        let metadata = E::metadata();
33        Self::new(metadata.schema, metadata.table)
34    }
35
36    pub fn for_entity_as<E: Entity>(alias: &'static str) -> Self {
37        let metadata = E::metadata();
38        Self::with_alias(metadata.schema, metadata.table, alias)
39    }
40
41    pub const fn as_alias(self, alias: &'static str) -> Self {
42        Self {
43            schema: self.schema,
44            table: self.table,
45            alias: Some(alias),
46        }
47    }
48
49    pub const fn without_alias(self) -> Self {
50        Self {
51            schema: self.schema,
52            table: self.table,
53            alias: None,
54        }
55    }
56
57    pub const fn reference_name(&self) -> &'static str {
58        match self.alias {
59            Some(alias) => alias,
60            None => self.table,
61        }
62    }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub struct ColumnRef {
67    pub table: TableRef,
68    pub rust_field: &'static str,
69    pub column_name: &'static str,
70}
71
72impl ColumnRef {
73    pub const fn new(table: TableRef, rust_field: &'static str, column_name: &'static str) -> Self {
74        Self {
75            table,
76            rust_field,
77            column_name,
78        }
79    }
80
81    pub fn for_entity_column<E: Entity>(column: EntityColumn<E>) -> Self {
82        Self::new(
83            TableRef::for_entity::<E>(),
84            column.rust_field(),
85            column.column_name(),
86        )
87    }
88
89    pub fn for_entity_column_as<E: Entity>(column: EntityColumn<E>, alias: &'static str) -> Self {
90        Self::new(
91            TableRef::for_entity_as::<E>(alias),
92            column.rust_field(),
93            column.column_name(),
94        )
95    }
96
97    pub const fn with_table_alias(self, alias: &'static str) -> Self {
98        Self {
99            table: self.table.as_alias(alias),
100            rust_field: self.rust_field,
101            column_name: self.column_name,
102        }
103    }
104}
105
106impl<E: Entity> From<EntityColumn<E>> for ColumnRef {
107    fn from(value: EntityColumn<E>) -> Self {
108        Self::for_entity_column(value)
109    }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub enum BinaryOp {
114    Add,
115    Subtract,
116    Multiply,
117    Divide,
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq)]
121pub enum UnaryOp {
122    Negate,
123}
124
125#[derive(Debug, Clone, PartialEq)]
126pub enum Expr {
127    Column(ColumnRef),
128    Value(SqlValue),
129    Binary {
130        left: Box<Expr>,
131        op: BinaryOp,
132        right: Box<Expr>,
133    },
134    Unary {
135        op: UnaryOp,
136        expr: Box<Expr>,
137    },
138    Function {
139        name: String,
140        args: Vec<Expr>,
141    },
142}
143
144impl Expr {
145    pub fn column<E: Entity>(column: EntityColumn<E>) -> Self {
146        Self::Column(column.into())
147    }
148
149    pub fn column_as<E: Entity>(column: EntityColumn<E>, alias: &'static str) -> Self {
150        Self::Column(ColumnRef::for_entity_column_as(column, alias))
151    }
152
153    pub const fn value(value: SqlValue) -> Self {
154        Self::Value(value)
155    }
156
157    pub fn binary(left: Expr, op: BinaryOp, right: Expr) -> Self {
158        Self::Binary {
159            left: Box::new(left),
160            op,
161            right: Box::new(right),
162        }
163    }
164
165    pub fn unary(op: UnaryOp, expr: Expr) -> Self {
166        Self::Unary {
167            op,
168            expr: Box::new(expr),
169        }
170    }
171
172    pub fn function(name: impl Into<String>, args: Vec<Expr>) -> Self {
173        Self::Function {
174            name: name.into(),
175            args,
176        }
177    }
178}
179
180impl<E: Entity> From<EntityColumn<E>> for Expr {
181    fn from(value: EntityColumn<E>) -> Self {
182        Self::column(value)
183    }
184}
185
186impl From<SqlValue> for Expr {
187    fn from(value: SqlValue) -> Self {
188        Self::Value(value)
189    }
190}