1use crate::value::Value;
2
3#[derive(Debug, Clone, Default)]
8pub struct Query {
9 pub sql: String,
10 pub bindings: Vec<Value>,
11}
12
13impl Query {
14 pub fn new(sql: impl Into<String>) -> Self {
15 Self { sql: sql.into(), bindings: vec![] }
16 }
17
18 pub fn bind(mut self, val: impl Into<Value>) -> Self {
19 self.bindings.push(val.into());
20 self
21 }
22}
23
24#[derive(Debug, Clone, Default)]
46pub struct QueryBuilder {
47 pub table: String,
48 pub operation: Operation,
49 pub conditions: Vec<Condition>,
50 pub order_by: Vec<OrderBy>,
51 pub limit: Option<u64>,
52 pub offset: Option<u64>,
53 pub columns: Vec<String>,
54 pub values: Vec<(String, Value)>,
55}
56
57#[derive(Debug, Clone, Default)]
62pub enum Operation {
63 #[default]
64 Select,
65 Insert,
66 Update,
67 Delete,
68 Count,
69}
70
71#[derive(Debug, Clone)]
72pub struct Condition {
73 pub column: String,
74 pub op: CondOp,
75 pub value: Value,
76 pub conjunction: Conjunction,
77}
78
79#[derive(Debug, Clone, Default)]
80pub enum Conjunction {
81 #[default]
82 And,
83 Or,
84}
85
86#[derive(Debug, Clone)]
101pub enum CondOp {
102 Eq,
103 Ne,
104 Gt,
105 Gte,
106 Lt,
107 Lte,
108 Like,
109 ILike,
110 In,
111 NotIn,
112 IsNull,
113 IsNotNull,
114}
115
116#[derive(Debug, Clone)]
117pub struct OrderBy {
118 pub column: String,
119 pub direction: Direction,
120}
121
122#[derive(Debug, Clone, Default)]
123pub enum Direction {
124 #[default]
125 Asc,
126 Desc,
127}
128
129impl QueryBuilder {
130 pub fn table(name: impl Into<String>) -> Self {
131 Self { table: name.into(), ..Default::default() }
132 }
133
134 pub fn select(mut self, cols: Vec<impl Into<String>>) -> Self {
135 self.columns = cols.into_iter().map(|c| c.into()).collect();
136 self
137 }
138
139 pub fn r#where(mut self, col: impl Into<String>, op: CondOp, val: impl Into<Value>) -> Self {
140 self.conditions.push(Condition {
141 column: col.into(),
142 op,
143 value: val.into(),
144 conjunction: Conjunction::And,
145 });
146 self
147 }
148
149 pub fn or_where(mut self, col: impl Into<String>, op: CondOp, val: impl Into<Value>) -> Self {
150 self.conditions.push(Condition {
151 column: col.into(),
152 op,
153 value: val.into(),
154 conjunction: Conjunction::Or,
155 });
156 self
157 }
158
159 pub fn order_by(mut self, col: impl Into<String>, dir: Direction) -> Self {
160 self.order_by.push(OrderBy { column: col.into(), direction: dir });
161 self
162 }
163
164 pub fn limit(mut self, n: u64) -> Self {
165 self.limit = Some(n);
166 self
167 }
168
169 pub fn offset(mut self, n: u64) -> Self {
170 self.offset = Some(n);
171 self
172 }
173
174 pub fn set(mut self, col: impl Into<String>, val: impl Into<Value>) -> Self {
175 self.values.push((col.into(), val.into()));
176 self
177 }
178
179 pub fn operation(mut self, op: Operation) -> Self {
180 self.operation = op;
181 self
182 }
183}