toasty_driver_integration_suite/tests/
crud_composite_key_pagination.rs1use crate::prelude::*;
9use toasty::stmt::Page;
10use toasty_core::driver::{Operation, Rows};
11
12#[driver_test(requires(sql))]
13pub async fn paginate_composite_key(test: &mut Test) -> Result<()> {
14 #[derive(Debug, toasty::Model)]
15 #[key(partition = kind, local = seq)]
16 struct Event {
17 kind: String,
18 seq: i64,
19 }
20
21 let mut db = test.setup_db(models!(Event)).await;
22
23 for i in 0..20 {
25 Event::create().kind("info").seq(i).exec(&mut db).await?;
26 }
27
28 test.log().clear();
29
30 let page: Page<_> = Event::filter_by_kind("info")
32 .order_by(Event::fields().seq().desc())
33 .paginate(10)
34 .exec(&mut db)
35 .await?;
36
37 assert_eq!(page.len(), 10);
38 for (i, expected) in (10..20).rev().enumerate() {
39 assert_eq!(page[i].seq, expected);
40 }
41
42 let (op, resp) = test.log().pop();
44 if test.capability().sql {
45 assert_struct!(op, Operation::QuerySql(_));
46 } else {
47 assert_struct!(op, Operation::QueryPk(_));
48 }
49 assert_struct!(resp.values, Rows::Stream(_));
50
51 let page: Page<_> = page.next(&mut db).await?.unwrap();
53 assert_eq!(page.len(), 10);
54 for (i, expected) in (0..10).rev().enumerate() {
55 assert_eq!(page[i].seq, expected);
56 }
57
58 let page: Page<_> = page.prev(&mut db).await?.unwrap();
60 assert_eq!(page.len(), 10);
61 for (i, expected) in (10..20).rev().enumerate() {
62 assert_eq!(page[i].seq, expected);
63 }
64
65 Ok(())
66}
67
68#[driver_test]
69pub async fn paginate_composite_key_asc(test: &mut Test) -> Result<()> {
70 #[derive(Debug, toasty::Model)]
71 #[key(partition = kind, local = seq)]
72 struct Event {
73 kind: String,
74 seq: i64,
75 }
76
77 let mut db = test.setup_db(models!(Event)).await;
78
79 for i in 0..20 {
80 Event::create().kind("info").seq(i).exec(&mut db).await?;
81 }
82
83 test.log().clear();
84
85 let page: Page<_> = Event::filter_by_kind("info")
87 .order_by(Event::fields().seq().asc())
88 .paginate(5)
89 .exec(&mut db)
90 .await?;
91
92 assert_eq!(page.len(), 5);
93 for (i, expected) in (0..5).enumerate() {
94 assert_eq!(page[i].seq, expected);
95 }
96
97 let (op, _) = test.log().pop();
98 if test.capability().sql {
99 assert_struct!(op, Operation::QuerySql(_));
100 } else {
101 assert_struct!(op, Operation::QueryPk(_));
102 }
103
104 let mut all_seqs: Vec<i64> = page.iter().map(|e| e.seq).collect();
106 let mut current = page;
107 while let Some(next) = current.next(&mut db).await? {
108 all_seqs.extend(next.iter().map(|e| e.seq));
109 current = next;
110 }
111
112 assert_eq!(all_seqs, (0..20).collect::<Vec<_>>());
113
114 Ok(())
115}
116
117#[driver_test]
118pub async fn limit_offset_composite_key(test: &mut Test) -> Result<()> {
119 #[derive(Debug, toasty::Model)]
120 #[key(partition = kind, local = seq)]
121 struct Event {
122 kind: String,
123 seq: i64,
124 }
125
126 let mut db = test.setup_db(models!(Event)).await;
127
128 for i in 0..20 {
129 Event::create().kind("info").seq(i).exec(&mut db).await?;
130 }
131
132 let events: Vec<_> = Event::filter_by_kind("info").limit(5).exec(&mut db).await?;
133 assert_eq!(events.len(), 5);
134
135 test.log().clear();
136
137 let events: Vec<_> = Event::filter_by_kind("info")
138 .order_by(Event::fields().seq().asc())
139 .limit(7)
140 .offset(5)
141 .exec(&mut db)
142 .await?;
143 assert_eq!(events.len(), 7);
144 assert_eq!(events[0].seq, 5);
145 assert_eq!(events[6].seq, 11);
146
147 let (op, _) = test.log().pop();
151 if test.capability().sql {
152 assert_struct!(op, Operation::QuerySql(_));
153 } else {
154 assert_struct!(op, Operation::QueryPk(_));
155 }
156
157 let events: Vec<_> = Event::filter_by_kind("info")
159 .order_by(Event::fields().seq().asc())
160 .limit(5)
161 .offset(0)
162 .exec(&mut db)
163 .await?;
164 assert_eq!(events.len(), 5);
165 assert_eq!(events[0].seq, 0);
166 assert_eq!(events[4].seq, 4);
167
168 let events: Vec<_> = Event::filter_by_kind("info")
170 .limit(5)
171 .offset(100)
172 .exec(&mut db)
173 .await?;
174 assert!(events.is_empty());
175
176 let events: Vec<_> = Event::filter_by_kind("info")
177 .limit(100)
178 .exec(&mut db)
179 .await?;
180 assert_eq!(events.len(), 20);
181
182 Ok(())
183}
184
185#[driver_test]
186pub async fn limit_offset_gsi(test: &mut Test) -> Result<()> {
187 #[derive(Debug, toasty::Model)]
188 struct Item {
189 #[key]
190 #[auto]
191 id: uuid::Uuid,
192
193 #[index]
194 category: String,
195
196 value: i64,
197 }
198
199 let mut db = test.setup_db(models!(Item)).await;
200
201 for i in 0..20 {
202 Item::create().category("x").value(i).exec(&mut db).await?;
203 }
204
205 let items: Vec<_> = Item::filter_by_category("x").limit(5).exec(&mut db).await?;
206 assert_eq!(items.len(), 5);
207
208 let items: Vec<_> = Item::filter_by_category("x")
210 .limit(7)
211 .offset(3)
212 .exec(&mut db)
213 .await?;
214 assert_eq!(items.len(), 7);
215
216 let items: Vec<_> = Item::filter_by_category("x")
217 .limit(100)
218 .exec(&mut db)
219 .await?;
220 assert_eq!(items.len(), 20);
221
222 Ok(())
223}
224
225#[driver_test]
226pub async fn limit_composite_key(test: &mut Test) -> Result<()> {
227 #[derive(Debug, toasty::Model)]
228 #[key(partition = kind, local = seq)]
229 struct Event {
230 kind: String,
231 seq: i64,
232 }
233
234 let mut db = test.setup_db(models!(Event)).await;
235
236 for i in 0..20 {
237 Event::create().kind("info").seq(i).exec(&mut db).await?;
238 }
239
240 test.log().clear();
241
242 let events: Vec<_> = Event::filter_by_kind("info").limit(7).exec(&mut db).await?;
244 assert_eq!(events.len(), 7);
245
246 let (op, _) = test.log().pop();
247 if test.capability().sql {
248 assert_struct!(op, Operation::QuerySql(_));
249 } else {
250 assert_struct!(op, Operation::QueryPk(_));
251 }
252
253 test.log().clear();
254
255 let events: Vec<_> = Event::filter_by_kind("info")
257 .order_by(Event::fields().seq().desc())
258 .limit(5)
259 .exec(&mut db)
260 .await?;
261 assert_eq!(events.len(), 5);
262 for i in 0..4 {
263 assert!(events[i].seq > events[i + 1].seq);
264 }
265 assert_eq!(events[0].seq, 19);
267
268 test.log().clear();
269
270 let events: Vec<_> = Event::filter_by_kind("info")
272 .limit(100)
273 .exec(&mut db)
274 .await?;
275 assert_eq!(events.len(), 20);
276
277 Ok(())
278}
279
280#[driver_test]
281pub async fn sort_composite_key(test: &mut Test) -> Result<()> {
282 #[derive(Debug, toasty::Model)]
283 #[key(partition = kind, local = seq)]
284 struct Event {
285 kind: String,
286 seq: i64,
287 }
288
289 let mut db = test.setup_db(models!(Event)).await;
290
291 for i in 0..20 {
292 Event::create().kind("info").seq(i).exec(&mut db).await?;
293 }
294
295 test.log().clear();
296
297 let events: Vec<_> = Event::filter_by_kind("info")
299 .order_by(Event::fields().seq().asc())
300 .exec(&mut db)
301 .await?;
302
303 assert_eq!(events.len(), 20);
304 for i in 0..19 {
305 assert!(events[i].seq < events[i + 1].seq);
306 }
307
308 let (op, resp) = test.log().pop();
309 if test.capability().sql {
310 assert_struct!(op, Operation::QuerySql(_));
311 } else {
312 assert_struct!(op, Operation::QueryPk(_));
313 }
314 assert_struct!(resp.values, Rows::Stream(_));
315
316 test.log().clear();
317
318 let events: Vec<_> = Event::filter_by_kind("info")
320 .order_by(Event::fields().seq().desc())
321 .exec(&mut db)
322 .await?;
323
324 assert_eq!(events.len(), 20);
325 for i in 0..19 {
326 assert!(events[i].seq > events[i + 1].seq);
327 }
328
329 let (op, resp) = test.log().pop();
330 if test.capability().sql {
331 assert_struct!(op, Operation::QuerySql(_));
332 } else {
333 assert_struct!(op, Operation::QueryPk(_));
334 }
335 assert_struct!(resp.values, Rows::Stream(_));
336
337 Ok(())
338}