toasty_driver_integration_suite/tests/
scan_no_index.rs1use crate::prelude::*;
2use toasty::stmt::Page;
3
4#[driver_test(id(ID))]
6pub async fn scan_no_filter(t: &mut Test) -> Result<()> {
7 #[derive(Debug, toasty::Model)]
8 struct Item {
9 #[key]
10 #[auto]
11 id: ID,
12 name: String,
13 }
14
15 let mut db = t.setup_db(models!(Item)).await;
16
17 toasty::create!(Item::[
18 { name: "Alice" },
19 { name: "Bob" },
20 { name: "Charlie" },
21 ])
22 .exec(&mut db)
23 .await?;
24
25 let mut results: Vec<Item> = Item::all().exec(&mut db).await?;
26 results.sort_by(|a, b| a.name.cmp(&b.name));
27
28 assert_eq!(3, results.len());
29 assert_eq!("Alice", results[0].name);
30 assert_eq!("Bob", results[1].name);
31 assert_eq!("Charlie", results[2].name);
32
33 Ok(())
34}
35
36#[driver_test(id(ID))]
38pub async fn scan_or_filter(t: &mut Test) -> Result<()> {
39 #[derive(Debug, toasty::Model)]
40 struct Item {
41 #[key]
42 #[auto]
43 id: ID,
44 name: String,
45 }
46
47 let mut db = t.setup_db(models!(Item)).await;
48
49 toasty::create!(Item::[
50 { name: "Alice" },
51 { name: "Bob" },
52 { name: "Charlie" },
53 ])
54 .exec(&mut db)
55 .await?;
56
57 let mut results: Vec<Item> = Item::filter(
58 Item::fields()
59 .name()
60 .eq("Alice")
61 .or(Item::fields().name().eq("Charlie")),
62 )
63 .exec(&mut db)
64 .await?;
65 results.sort_by(|a, b| a.name.cmp(&b.name));
66
67 assert_eq!(2, results.len());
68 assert_eq!("Alice", results[0].name);
69 assert_eq!("Charlie", results[1].name);
70
71 Ok(())
72}
73
74#[driver_test(id(ID))]
76pub async fn scan_with_limit(t: &mut Test) -> Result<()> {
77 #[derive(Debug, toasty::Model)]
78 struct Item {
79 #[key]
80 #[auto]
81 id: ID,
82 name: String,
83 }
84
85 let mut db = t.setup_db(models!(Item)).await;
86
87 toasty::create!(Item::[
88 { name: "Alice" },
89 { name: "Bob" },
90 { name: "Charlie" },
91 { name: "Dave" },
92 { name: "Eve" },
93 ])
94 .exec(&mut db)
95 .await?;
96
97 let results: Vec<Item> = Item::all().limit(3).exec(&mut db).await?;
98
99 assert!(
100 results.len() <= 3,
101 "expected at most 3 results, got {}",
102 results.len()
103 );
104
105 Ok(())
106}
107
108#[driver_test(id(ID), requires(not(sql)))]
112pub async fn scan_limit_with_filter_returns_correct_count(t: &mut Test) -> Result<()> {
113 #[derive(Debug, toasty::Model)]
114 struct Item {
115 #[key]
116 #[auto]
117 id: ID,
118 category: String,
119 }
120
121 let mut db = t.setup_db(models!(Item)).await;
122
123 for _i in 0..10_i64 {
128 toasty::create!(Item { category: "match" })
129 .exec(&mut db)
130 .await?;
131 toasty::create!(Item { category: "other" })
132 .exec(&mut db)
133 .await?;
134 }
135
136 let results: Vec<Item> = Item::filter(Item::fields().category().eq("match"))
137 .limit(5)
138 .exec(&mut db)
139 .await?;
140
141 assert_eq!(
142 5,
143 results.len(),
144 "expected exactly 5 matching rows, got {}",
145 results.len()
146 );
147 assert!(
148 results.iter().all(|r| r.category == "match"),
149 "all returned rows should have category 'match'"
150 );
151
152 Ok(())
153}
154
155#[driver_test(id(ID), requires(not(sql)))]
158pub async fn scan_paginate_multi_page(t: &mut Test) -> Result<()> {
159 #[derive(Debug, toasty::Model)]
160 struct Item {
161 #[key]
162 #[auto]
163 id: ID,
164 score: i64,
165 }
166
167 let mut db = t.setup_db(models!(Item)).await;
168
169 for score in 1_i64..=15 {
170 toasty::create!(Item { score }).exec(&mut db).await?;
171 }
172
173 let mut page: Page<Item> = Item::all().paginate(5).exec(&mut db).await?;
175
176 let mut all_items: Vec<Item> = std::mem::take(&mut page.items);
177 while let Some(mut next) = page.next(&mut db).await? {
178 all_items.append(&mut next.items);
179 page = next;
180 }
181
182 assert_eq!(
183 15,
184 all_items.len(),
185 "expected 15 total rows across all pages"
186 );
187
188 let mut scores: Vec<i64> = all_items.iter().map(|r| r.score).collect();
190 scores.sort_unstable();
191 scores.dedup();
192 assert_eq!(15, scores.len(), "expected 15 unique scores");
193 assert_eq!((1..=15).collect::<Vec<_>>(), scores);
194
195 Ok(())
196}
197
198#[driver_test(id(ID), requires(not(sql)))]
202pub async fn scan_order_by_is_error(t: &mut Test) -> Result<()> {
203 #[derive(Debug, toasty::Model)]
204 struct Item {
205 #[key]
206 #[auto]
207 id: ID,
208 score: i64,
209 }
210
211 let mut db = t.setup_db(models!(Item)).await;
212
213 toasty::create!(Item::[
214 { score: 10_i64 },
215 { score: 30_i64 },
216 { score: 20_i64 },
217 { score: 50_i64 },
218 { score: 40_i64 },
219 ])
220 .exec(&mut db)
221 .await?;
222
223 let result: toasty::Result<Vec<Item>> = Item::all()
224 .order_by(Item::fields().score().desc())
225 .exec(&mut db)
226 .await;
227
228 assert!(
229 result.is_err(),
230 "expected error when using ORDER BY on a scan-path query on DynamoDB"
231 );
232
233 Ok(())
234}
235
236#[driver_test(id(ID), requires(sql))]
239pub async fn scan_order_by_sql(t: &mut Test) -> Result<()> {
240 #[derive(Debug, toasty::Model)]
241 struct Item {
242 #[key]
243 #[auto]
244 id: ID,
245 score: i64,
246 }
247
248 let mut db = t.setup_db(models!(Item)).await;
249
250 toasty::create!(Item::[
251 { score: 10_i64 },
252 { score: 30_i64 },
253 { score: 20_i64 },
254 { score: 50_i64 },
255 { score: 40_i64 },
256 ])
257 .exec(&mut db)
258 .await?;
259
260 let results: Vec<Item> = Item::all()
261 .order_by(Item::fields().score().desc())
262 .exec(&mut db)
263 .await?;
264
265 assert_eq!(5, results.len());
266 for i in 0..4 {
267 assert!(
268 results[i].score >= results[i + 1].score,
269 "expected descending order: results[{}].score={} >= results[{}].score={}",
270 i,
271 results[i].score,
272 i + 1,
273 results[i + 1].score
274 );
275 }
276
277 Ok(())
278}