Skip to content

Commit cbc2eb6

Browse files
Add query macro docs (#543)
* Add query macro docs * fix doc errors * merge comparison section * add tests for query macro * chore(pre-commit.ci): auto fixes from pre-commit hooks * Revert "chore(pre-commit.ci): auto fixes from pre-commit hooks" This reverts commit 426596c. * Revert "add tests for query macro" This reverts commit f9ae80c. * add tests for query macro * remove line that skips parsing literals into Expr::value * clippy fix * update docs based on comments * fix doc tests * move docs to main crate --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 90474f0 commit cbc2eb6

3 files changed

Lines changed: 448 additions & 5 deletions

File tree

cot-macros/src/query.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ pub(super) fn query_to_tokens(query: Query) -> TokenStream {
3434
}
3535

3636
pub(super) fn expr_to_tokens(model_name: &syn::Type, expr: Expr) -> TokenStream {
37-
if let Some(tokens) = expr.as_tokens() {
38-
return tokens;
39-
}
40-
4137
let crate_name = cot_ident();
4238
match expr {
4339
Expr::FieldRef { field_name, .. } => {

cot-macros/tests/query.rs

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
use cot::db::query::{Expr, ExprAdd, ExprDiv, ExprEq, ExprMul, ExprOrd, ExprSub, Query};
2+
use cot::db::{model, query};
3+
4+
#[model]
5+
#[derive(Debug, PartialEq)]
6+
struct MyModel {
7+
#[model(primary_key)]
8+
id: i32,
9+
name: String,
10+
price: i64,
11+
quantity: i64,
12+
}
13+
14+
#[test]
15+
fn test_query_equality() {
16+
assert_eq!(
17+
Query::<MyModel>::new().filter(ExprEq::eq(<MyModel as cot::db::Model>::Fields::id, 5)),
18+
query!(MyModel, $id == 5)
19+
);
20+
21+
assert_eq!(
22+
Query::<MyModel>::new().filter(ExprEq::ne(<MyModel as cot::db::Model>::Fields::id, 5)),
23+
query!(MyModel, $id != 5)
24+
);
25+
}
26+
27+
#[test]
28+
fn test_query_comparison() {
29+
assert_eq!(
30+
Query::<MyModel>::new().filter(ExprOrd::lt(<MyModel as cot::db::Model>::Fields::id, 5)),
31+
query!(MyModel, $id < 5)
32+
);
33+
34+
assert_eq!(
35+
Query::<MyModel>::new().filter(ExprOrd::lte(<MyModel as cot::db::Model>::Fields::id, 5)),
36+
query!(MyModel, $id <= 5)
37+
);
38+
39+
assert_eq!(
40+
Query::<MyModel>::new().filter(ExprOrd::gt(<MyModel as cot::db::Model>::Fields::id, 5)),
41+
query!(MyModel, $id > 5)
42+
);
43+
44+
assert_eq!(
45+
Query::<MyModel>::new().filter(ExprOrd::gte(<MyModel as cot::db::Model>::Fields::id, 5)),
46+
query!(MyModel, $id >= 5)
47+
);
48+
49+
assert_eq!(
50+
Query::<MyModel>::new().filter(Expr::and(
51+
ExprEq::eq(<MyModel as cot::db::Model>::Fields::id, 5),
52+
ExprEq::eq(<MyModel as cot::db::Model>::Fields::name, "test")
53+
)),
54+
query!(MyModel, $id == 5 && $name == "test")
55+
);
56+
57+
assert_eq!(
58+
Query::<MyModel>::new().filter(Expr::or(
59+
ExprEq::eq(<MyModel as cot::db::Model>::Fields::id, 5),
60+
ExprEq::eq(<MyModel as cot::db::Model>::Fields::id, 10)
61+
)),
62+
query!(MyModel, $id == 5 || $id == 10)
63+
);
64+
65+
assert_eq!(
66+
Query::<MyModel>::new().filter(Expr::and(
67+
ExprOrd::gt(<MyModel as cot::db::Model>::Fields::id, 0),
68+
Expr::or(
69+
ExprEq::eq(<MyModel as cot::db::Model>::Fields::name, "a"),
70+
ExprEq::eq(<MyModel as cot::db::Model>::Fields::name, "b")
71+
)
72+
)),
73+
query!(MyModel, $id > 0 && ($name == "a" || $name == "b"))
74+
);
75+
}
76+
77+
#[test]
78+
fn test_query_add_fields() {
79+
assert_eq!(
80+
<MyModel as ::cot::db::Model>::objects().filter(Expr::eq(
81+
<MyModel as ::cot::db::Model>::Fields::id.as_expr(),
82+
ExprAdd::add(<MyModel as ::cot::db::Model>::Fields::id, 5)
83+
)),
84+
query!(MyModel, $id == $id + 5)
85+
);
86+
87+
assert_eq!(
88+
Query::<MyModel>::new().filter(Expr::eq(
89+
Expr::field("price"),
90+
Expr::add(
91+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
92+
<MyModel as cot::db::Model>::Fields::id.as_expr()
93+
)
94+
)),
95+
query!(MyModel, $price == $quantity + $id)
96+
);
97+
98+
assert_eq!(
99+
Query::<MyModel>::new().filter(Expr::gt(
100+
Expr::add(
101+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
102+
<MyModel as cot::db::Model>::Fields::id.as_expr()
103+
),
104+
Expr::value(11)
105+
)),
106+
query!(MyModel, $quantity + $id > 11)
107+
);
108+
109+
assert_eq!(
110+
Query::<MyModel>::new().filter(Expr::add(
111+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
112+
<MyModel as cot::db::Model>::Fields::id.as_expr()
113+
)),
114+
query!(MyModel, $quantity + $id)
115+
);
116+
}
117+
118+
#[test]
119+
fn test_query_sub_fields() {
120+
assert_eq!(
121+
Query::<MyModel>::new().filter(Expr::eq(
122+
Expr::field("id"),
123+
<MyModel as cot::db::Model>::Fields::id.sub(5)
124+
)),
125+
query!(MyModel, $id == $id - 5)
126+
);
127+
128+
assert_eq!(
129+
Query::<MyModel>::new().filter(Expr::eq(
130+
Expr::field("price"),
131+
Expr::sub(
132+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
133+
<MyModel as cot::db::Model>::Fields::id.as_expr()
134+
)
135+
)),
136+
query!(MyModel, $price == $quantity - $id)
137+
);
138+
139+
assert_eq!(
140+
Query::<MyModel>::new().filter(Expr::gt(
141+
Expr::sub(
142+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
143+
<MyModel as cot::db::Model>::Fields::id.as_expr()
144+
),
145+
Expr::value(11)
146+
)),
147+
query!(MyModel, $quantity - $id > 11)
148+
);
149+
150+
assert_eq!(
151+
<MyModel as ::cot::db::Model>::objects().filter(ExprSub::sub(
152+
<MyModel as ::cot::db::Model>::Fields::quantity,
153+
1
154+
)),
155+
query!(MyModel, $quantity - 1)
156+
);
157+
}
158+
159+
#[test]
160+
fn test_query_mul_fields() {
161+
assert_eq!(
162+
<MyModel as ::cot::db::Model>::objects().filter(Expr::eq(
163+
<MyModel as ::cot::db::Model>::Fields::id.as_expr(),
164+
ExprMul::mul(<MyModel as ::cot::db::Model>::Fields::id, 5)
165+
)),
166+
query!(MyModel, $id == $id * 5)
167+
);
168+
169+
assert_eq!(
170+
Query::<MyModel>::new().filter(Expr::eq(
171+
Expr::field("price"),
172+
Expr::mul(
173+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
174+
<MyModel as cot::db::Model>::Fields::id.as_expr()
175+
)
176+
)),
177+
query!(MyModel, $price == $quantity * $id)
178+
);
179+
180+
assert_eq!(
181+
<MyModel as ::cot::db::Model>::objects().filter(Expr::gt(
182+
Expr::mul(
183+
<MyModel as ::cot::db::Model>::Fields::quantity.as_expr(),
184+
<MyModel as ::cot::db::Model>::Fields::id.as_expr()
185+
),
186+
Expr::value(11)
187+
)),
188+
query!(MyModel, $quantity * $id > 11)
189+
);
190+
191+
assert_eq!(
192+
<MyModel as ::cot::db::Model>::objects().filter(::cot::db::query::ExprMul::mul(
193+
<MyModel as ::cot::db::Model>::Fields::quantity,
194+
5i64
195+
)),
196+
query!(MyModel, $quantity * 5)
197+
);
198+
}
199+
200+
#[test]
201+
fn test_query_div_fields() {
202+
assert_eq!(
203+
Query::<MyModel>::new().filter(Expr::eq(
204+
Expr::field("id"),
205+
<MyModel as cot::db::Model>::Fields::id.div(5)
206+
)),
207+
query!(MyModel, $id == $id / 5)
208+
);
209+
210+
assert_eq!(
211+
Query::<MyModel>::new().filter(Expr::eq(
212+
Expr::field("price"),
213+
Expr::div(
214+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
215+
<MyModel as cot::db::Model>::Fields::id.as_expr()
216+
)
217+
)),
218+
query!(MyModel, $price == $quantity / $id)
219+
);
220+
221+
assert_eq!(
222+
Query::<MyModel>::new().filter(Expr::gt(
223+
Expr::div(
224+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
225+
<MyModel as cot::db::Model>::Fields::id.as_expr()
226+
),
227+
Expr::value(11)
228+
)),
229+
query!(MyModel, $quantity / $id > 11)
230+
);
231+
232+
assert_eq!(
233+
Query::<MyModel>::new().filter(Expr::div(
234+
<MyModel as cot::db::Model>::Fields::quantity.as_expr(),
235+
Expr::value(1i64)
236+
)),
237+
query!(MyModel, $quantity / 1)
238+
);
239+
}
240+
241+
struct Outer {
242+
inner: i32,
243+
}
244+
245+
#[test]
246+
fn test_query_rust_expressions() {
247+
assert_eq!(
248+
<MyModel as ::cot::db::Model>::objects()
249+
.filter(ExprEq::eq(<MyModel as ::cot::db::Model>::Fields::id, 10)),
250+
query!(MyModel, $id == 10)
251+
);
252+
253+
let outer = Outer { inner: 20 };
254+
assert_eq!(
255+
<MyModel as ::cot::db::Model>::objects().filter(ExprEq::eq(
256+
<MyModel as ::cot::db::Model>::Fields::id,
257+
outer.inner
258+
)),
259+
query!(MyModel, $id == outer.inner)
260+
);
261+
262+
let get_id = || 30;
263+
264+
assert_eq!(
265+
<MyModel as ::cot::db::Model>::objects().filter(ExprEq::eq(
266+
<MyModel as ::cot::db::Model>::Fields::id,
267+
get_id()
268+
)),
269+
query!(MyModel, $id == get_id())
270+
);
271+
272+
assert_eq!(
273+
<MyModel as ::cot::db::Model>::objects()
274+
.filter(<MyModel as ::cot::db::Model>::Fields::id.as_expr()),
275+
query!(MyModel, $id)
276+
);
277+
}
278+
279+
#[test]
280+
fn test_query_path_access() {
281+
mod constants {
282+
pub(crate) const ID: i32 = 100;
283+
}
284+
assert_eq!(
285+
<MyModel as ::cot::db::Model>::objects().filter(ExprEq::eq(
286+
<MyModel as ::cot::db::Model>::Fields::id,
287+
constants::ID
288+
)),
289+
query!(MyModel, $id == constants::ID)
290+
);
291+
}

0 commit comments

Comments
 (0)