1use crate::prelude::*;
4use toasty_core::{
5 driver::Operation,
6 stmt::{Expr, ExprSet, Statement},
7};
8
9#[driver_test(id(ID), scenario(crate::scenarios::two_models))]
10pub async fn query_index_eq(t: &mut Test) -> Result<()> {
11 let mut db = setup(t).await;
12
13 for name in ["one", "two", "three"] {
15 User::create().name(name).exec(&mut db).await?;
16 }
17
18 let users = User::filter_by_name("one").exec(&mut db).await?;
19
20 assert_eq!(1, users.len());
21 assert_eq!("one", users[0].name);
22
23 User::create().name("one").exec(&mut db).await?;
26
27 let users = User::filter_by_name("one").exec(&mut db).await?;
28
29 assert_eq!(2, users.len());
30 assert!(users.iter().all(|u| u.name == "one"));
31 Ok(())
32}
33
34#[driver_test(id(ID))]
35pub async fn query_partition_key_string_eq(test: &mut Test) -> Result<()> {
36 #[derive(Debug, toasty::Model)]
37 #[key(partition = league, local = name)]
38 struct Team {
39 league: String,
40
41 name: String,
42
43 founded: i64,
44 }
45
46 let mut db = test.setup_db(models!(Team)).await;
47
48 for (league, name, founded) in [
50 ("MLS", "Portland Timbers", 2009),
51 ("MLS", "Seattle Sounders FC", 2007),
52 ("MLS", "Vancouver Whitecaps FC", 2009),
53 ("MLS", "Los Angeles Football Club", 2014),
54 ("MLS", "San Jose Earthquakes", 1994),
55 ("MLS", "LA Galaxy", 1994),
56 ("EPL", "Arsenal", 1886),
57 ("EPL", "Chelsea", 1905),
58 ("EPL", "Manchester United", 1878),
59 ("EPL", "Tottenham", 1882),
60 ("La Liga", "FC Barcelona", 1899),
61 ("La Liga", "Girona FC", 1930),
62 ("La Liga", "Real Madrid", 1902),
63 ("La Liga", "Atlético Madrid", 1903),
64 ]
65 .into_iter()
66 {
67 Team::create()
68 .league(league)
69 .name(name)
70 .founded(founded)
71 .exec(&mut db)
72 .await?;
73 }
74
75 let teams = Team::filter(Team::fields().league().eq("EPL"))
77 .exec(&mut db)
78 .await?;
79
80 let mut names = teams.iter().map(|team| &team.name).collect::<Vec<_>>();
81 names.sort();
82
83 assert_eq!(
84 names,
85 ["Arsenal", "Chelsea", "Manchester United", "Tottenham"]
86 );
87
88 let teams = Team::filter(
90 Team::fields()
91 .league()
92 .eq("MLS")
93 .and(Team::fields().name().eq("Portland Timbers")),
94 )
95 .exec(&mut db)
96 .await?;
97
98 let mut names = teams.iter().map(|team| &team.name).collect::<Vec<_>>();
99 names.sort();
100
101 assert_eq!(names, ["Portland Timbers"]);
102
103 let teams = Team::filter(
105 Team::fields()
106 .league()
107 .eq("MLS")
108 .and(Team::fields().founded().eq(2009)),
109 )
110 .exec(&mut db)
111 .await?;
112
113 let mut names = teams.iter().map(|team| &team.name).collect::<Vec<_>>();
114 names.sort();
115
116 assert_eq!(names, ["Portland Timbers", "Vancouver Whitecaps FC"]);
117
118 let teams = Team::filter(
120 Team::fields()
121 .league()
122 .eq("MLS")
123 .and(Team::fields().founded().eq(2009))
124 .and(Team::fields().name().eq("Portland Timbers")),
125 )
126 .exec(&mut db)
127 .await?;
128
129 assert_eq!(1, teams.len());
130 assert!(teams.iter().all(|team| team.founded == 2009));
131
132 let mut names = teams.iter().map(|team| &team.name).collect::<Vec<_>>();
133 names.sort();
134
135 assert_eq!(names, ["Portland Timbers"]);
136
137 let teams = Team::filter(
139 Team::fields()
140 .league()
141 .eq("MLS")
142 .and(Team::fields().founded().eq(2009))
143 .and(Team::fields().name().eq("LA Galaxy")),
144 )
145 .exec(&mut db)
146 .await?;
147
148 assert!(teams.is_empty());
149 Ok(())
150}
151
152#[driver_test(id(ID))]
153pub async fn query_local_key_cmp(test: &mut Test) -> Result<()> {
154 #[derive(Debug, toasty::Model)]
155 #[key(partition = kind, local = timestamp)]
156 struct Event {
157 kind: String,
158
159 timestamp: i64,
160 }
161
162 let mut db = test.setup_db(models!(Event)).await;
163
164 for (kind, ts) in [
166 ("info", 0),
167 ("warn", 1),
168 ("info", 2),
169 ("warn", 3),
170 ("info", 4),
171 ("warn", 5),
172 ("info", 6),
173 ("warn", 7),
174 ("info", 8),
175 ("warn", 9),
176 ("info", 10),
177 ("warn", 11),
178 ("info", 12),
179 ("warn", 13),
180 ("info", 14),
181 ("warn", 15),
182 ("info", 16),
183 ("warn", 17),
184 ("info", 18),
185 ("warn", 19),
186 ] {
187 Event::create()
188 .kind(kind)
189 .timestamp(ts)
190 .exec(&mut db)
191 .await?;
192 }
193
194 let events: Vec<_> = Event::filter_by_kind("info")
195 .filter(Event::fields().timestamp().ne(10))
196 .exec(&mut db)
197 .await?;
198
199 assert_eq_unordered!(
200 events.iter().map(|event| event.timestamp),
201 [&0, &2, &4, &6, &8, &12, &14, &16, &18,]
202 );
203
204 let events: Vec<_> = Event::filter_by_kind("info")
205 .filter(Event::fields().timestamp().gt(10))
206 .exec(&mut db)
207 .await?;
208
209 assert_eq_unordered!(
210 events.iter().map(|event| event.timestamp),
211 [&12, &14, &16, &18,]
212 );
213
214 let events: Vec<_> = Event::filter_by_kind("info")
215 .filter(Event::fields().timestamp().ge(10))
216 .exec(&mut db)
217 .await?;
218
219 assert_eq_unordered!(
220 events.iter().map(|event| event.timestamp),
221 [&10, &12, &14, &16, &18,]
222 );
223
224 let events: Vec<_> = Event::filter_by_kind("info")
225 .filter(Event::fields().timestamp().lt(10))
226 .exec(&mut db)
227 .await?;
228
229 assert_eq_unordered!(
230 events.iter().map(|event| event.timestamp),
231 [&0, &2, &4, &6, &8]
232 );
233
234 let events: Vec<_> = Event::filter_by_kind("info")
235 .filter(Event::fields().timestamp().le(10))
236 .exec(&mut db)
237 .await?;
238
239 assert_eq_unordered!(
240 events.iter().map(|event| event.timestamp),
241 [&0, &2, &4, &6, &8, &10]
242 );
243 Ok(())
244}
245
246#[driver_test(id(ID), scenario(crate::scenarios::user_with_age))]
247pub async fn set_filter_overwrites(test: &mut Test) -> Result<()> {
248 let mut db = setup(test).await;
249
250 toasty::create!(User::[
251 { name: "Alice", age: 30 },
252 { name: "Bob", age: 20 },
253 ])
254 .exec(&mut db)
255 .await?;
256
257 use toasty::stmt::{List, Query};
260 let mut q = Query::<List<User>>::all().filter(User::fields().name().eq("Alice"));
261 q.set_filter(User::fields().name().eq("Bob"));
262
263 let users = q.exec(&mut db).await?;
264
265 assert_eq!(1, users.len());
266 assert_eq!("Bob", users[0].name);
267 Ok(())
268}
269
270#[driver_test(id(ID), scenario(crate::scenarios::user_with_age))]
271pub async fn query_or_basic(test: &mut Test) -> Result<()> {
272 let mut db = setup(test).await;
273 let _name_column = db.schema().table_for(User::id()).columns[1].id;
274 let _age_column = db.schema().table_for(User::id()).columns[2].id;
275
276 for (name, age) in [("Alice", 25), ("Bob", 30), ("Charlie", 35), ("Diana", 40)] {
278 User::create().name(name).age(age).exec(&mut db).await?;
279 }
280
281 test.log().clear();
283
284 let result = User::filter(
286 User::fields()
287 .name()
288 .eq("Alice")
289 .or(User::fields().age().eq(35)),
290 )
291 .exec(&mut db)
292 .await;
293
294 if test.capability().sql {
295 let users = result?;
296 assert_eq!(2, users.len());
297 let mut names: Vec<_> = users.iter().map(|u| u.name.as_str()).collect();
298 names.sort();
299 assert_eq!(names, ["Alice", "Charlie"]);
300
301 let (op, _) = test.log().pop();
303
304 assert_struct!(&op, Operation::QuerySql({
305 stmt: Statement::Query({
306 body: ExprSet::Select({
307 filter.expr: Some(Expr::Or({
308 })),
324 }),
325 }),
326 }));
327 } else if test.capability().scan {
328 let users = result?;
329 assert_eq!(2, users.len());
330 let mut names: Vec<_> = users.iter().map(|u| u.name.as_str()).collect();
331 names.sort();
332 assert_eq!(names, ["Alice", "Charlie"]);
333 } else {
334 assert!(
335 result.is_err(),
336 "Expected error for OR query without key condition on non-SQL database"
337 );
338 }
339 Ok(())
340}
341
342#[driver_test(id(ID), scenario(crate::scenarios::user_with_age))]
343pub async fn query_or_multiple(test: &mut Test) -> Result<()> {
344 let mut db = setup(test).await;
345
346 for (name, age) in [("Alice", 25), ("Bob", 30), ("Charlie", 35), ("Diana", 40)] {
348 User::create().name(name).age(age).exec(&mut db).await?;
349 }
350
351 let result = User::filter(
353 User::fields()
354 .name()
355 .eq("Alice")
356 .or(User::fields().age().eq(35))
357 .or(User::fields().age().eq(40)),
358 )
359 .exec(&mut db)
360 .await;
361
362 if test.capability().sql || test.capability().scan {
363 let users = result?;
364 assert_eq!(3, users.len());
365 let mut names: Vec<_> = users.iter().map(|u| u.name.as_str()).collect();
366 names.sort();
367 assert_eq!(names, ["Alice", "Charlie", "Diana"]);
368 } else {
369 assert!(
370 result.is_err(),
371 "Expected error for OR query without key condition on non-SQL database"
372 );
373 }
374 Ok(())
375}
376
377#[driver_test(id(ID), scenario(crate::scenarios::user_with_active))]
378pub async fn query_or_and_combined(test: &mut Test) -> Result<()> {
379 let mut db = setup(test).await;
380
381 for (name, age, active) in [
383 ("Alice", 25, true),
384 ("Bob", 30, false),
385 ("Charlie", 35, true),
386 ("Diana", 40, false),
387 ("Eve", 25, false),
388 ] {
389 User::create()
390 .name(name)
391 .age(age)
392 .active(active)
393 .exec(&mut db)
394 .await?;
395 }
396
397 let result = User::filter(
399 User::fields()
400 .name()
401 .eq("Alice")
402 .or(User::fields().age().eq(35))
403 .and(User::fields().active().eq(true)),
404 )
405 .exec(&mut db)
406 .await;
407
408 if test.capability().sql || test.capability().scan {
409 let users = result?;
410 assert_eq!(2, users.len());
411 let mut names: Vec<_> = users.iter().map(|u| u.name.as_str()).collect();
412 names.sort();
413 assert_eq!(names, ["Alice", "Charlie"]);
414 } else {
415 assert!(
416 result.is_err(),
417 "Expected error for OR query without key condition on non-SQL database"
418 );
419 }
420 Ok(())
421}
422
423#[driver_test(id(ID))]
424pub async fn query_or_with_index(test: &mut Test) -> Result<()> {
425 #[derive(Debug, toasty::Model)]
426 #[key(partition = team, local = name)]
427 struct Player {
428 team: String,
429
430 name: String,
431
432 #[allow(dead_code)]
433 position: String,
434
435 #[allow(dead_code)]
436 number: i64,
437 }
438
439 let mut db = test.setup_db(models!(Player)).await;
440
441 for (team, name, position, number) in [
443 ("Timbers", "Diego Valeri", "Midfielder", 8),
444 ("Timbers", "Darlington Nagbe", "Midfielder", 6),
445 ("Timbers", "Diego Chara", "Midfielder", 21),
446 ("Timbers", "Fanendo Adi", "Forward", 9),
447 ("Timbers", "Adam Kwarasey", "Goalkeeper", 1),
448 ("Sounders", "Clint Dempsey", "Forward", 2),
449 ("Sounders", "Obafemi Martins", "Forward", 9),
450 ("Sounders", "Osvaldo Alonso", "Midfielder", 6),
451 ] {
452 Player::create()
453 .team(team)
454 .name(name)
455 .position(position)
456 .number(number)
457 .exec(&mut db)
458 .await?;
459 }
460
461 let players = Player::filter(
464 Player::fields().team().eq("Timbers").and(
465 Player::fields()
466 .position()
467 .eq("Forward")
468 .or(Player::fields().position().eq("Goalkeeper")),
469 ),
470 )
471 .exec(&mut db)
472 .await?;
473
474 assert_eq!(2, players.len());
475 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
476 names.sort();
477 assert_eq!(names, ["Adam Kwarasey", "Fanendo Adi"]);
478
479 let players = Player::filter(
481 Player::fields().team().eq("Timbers").and(
482 Player::fields()
483 .number()
484 .eq(8)
485 .or(Player::fields().number().eq(21))
486 .or(Player::fields().number().eq(9)),
487 ),
488 )
489 .exec(&mut db)
490 .await?;
491
492 assert_eq!(3, players.len());
493 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
494 names.sort();
495 assert_eq!(names, ["Diego Chara", "Diego Valeri", "Fanendo Adi"]);
496 Ok(())
497}
498
499#[driver_test(id(ID))]
500pub async fn query_or_on_partition_key(test: &mut Test) -> Result<()> {
501 #[derive(Debug, toasty::Model)]
507 #[key(partition = team, local = name)]
508 struct Player {
509 team: String,
510
511 name: String,
512
513 #[allow(dead_code)]
514 position: String,
515 }
516
517 let mut db = test.setup_db(models!(Player)).await;
518
519 for (team, name, position) in [
520 ("Timbers", "Diego Valeri", "Midfielder"),
521 ("Timbers", "Fanendo Adi", "Forward"),
522 ("Sounders", "Clint Dempsey", "Forward"),
523 ("Sounders", "Osvaldo Alonso", "Midfielder"),
524 ("Galaxy", "Robbie Keane", "Forward"),
525 ] {
526 Player::create()
527 .team(team)
528 .name(name)
529 .position(position)
530 .exec(&mut db)
531 .await?;
532 }
533
534 let players = Player::filter(
536 Player::fields()
537 .team()
538 .eq("Timbers")
539 .or(Player::fields().team().eq("Sounders")),
540 )
541 .exec(&mut db)
542 .await?;
543
544 assert_eq!(4, players.len());
545 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
546 names.sort();
547 assert_eq!(
548 names,
549 [
550 "Clint Dempsey",
551 "Diego Valeri",
552 "Fanendo Adi",
553 "Osvaldo Alonso"
554 ]
555 );
556 Ok(())
557}
558
559#[driver_test(id(ID))]
560pub async fn query_or_on_composite_pk(test: &mut Test) -> Result<()> {
561 #[derive(Debug, toasty::Model)]
567 #[key(partition = team, local = name)]
568 struct Player {
569 team: String,
570
571 name: String,
572
573 #[allow(dead_code)]
574 position: String,
575 }
576
577 let mut db = test.setup_db(models!(Player)).await;
578
579 for (team, name, position) in [
580 ("Timbers", "Diego Valeri", "Midfielder"),
581 ("Timbers", "Fanendo Adi", "Forward"),
582 ("Sounders", "Clint Dempsey", "Forward"),
583 ("Sounders", "Osvaldo Alonso", "Midfielder"),
584 ] {
585 Player::create()
586 .team(team)
587 .name(name)
588 .position(position)
589 .exec(&mut db)
590 .await?;
591 }
592
593 let players = Player::filter(
595 Player::fields()
596 .team()
597 .eq("Timbers")
598 .and(Player::fields().name().eq("Diego Valeri"))
599 .or(Player::fields()
600 .team()
601 .eq("Sounders")
602 .and(Player::fields().name().eq("Clint Dempsey"))),
603 )
604 .exec(&mut db)
605 .await?;
606
607 assert_eq!(2, players.len());
608 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
609 names.sort();
610 assert_eq!(names, ["Clint Dempsey", "Diego Valeri"]);
611 Ok(())
612}
613
614#[driver_test(id(ID))]
615pub async fn query_or_with_comparisons(test: &mut Test) -> Result<()> {
616 #[derive(Debug, toasty::Model)]
617 #[key(partition = team, local = name)]
618 struct Player {
619 team: String,
620
621 name: String,
622
623 #[allow(dead_code)]
624 position: String,
625
626 #[allow(dead_code)]
627 number: i64,
628 }
629
630 let mut db = test.setup_db(models!(Player)).await;
631
632 for (team, name, position, number) in [
634 ("Timbers", "Diego Valeri", "Midfielder", 8),
635 ("Timbers", "Darlington Nagbe", "Midfielder", 6),
636 ("Timbers", "Diego Chara", "Midfielder", 21),
637 ("Timbers", "Fanendo Adi", "Forward", 9),
638 ("Timbers", "Adam Kwarasey", "Goalkeeper", 1),
639 ("Sounders", "Clint Dempsey", "Forward", 2),
640 ("Sounders", "Obafemi Martins", "Forward", 9),
641 ("Sounders", "Osvaldo Alonso", "Midfielder", 6),
642 ] {
643 Player::create()
644 .team(team)
645 .name(name)
646 .position(position)
647 .number(number)
648 .exec(&mut db)
649 .await?;
650 }
651
652 let players = Player::filter(
656 Player::fields().team().eq("Timbers").and(
657 Player::fields()
658 .number()
659 .gt(20)
660 .or(Player::fields().number().lt(2)),
661 ),
662 )
663 .exec(&mut db)
664 .await?;
665
666 assert_eq!(2, players.len());
667 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
668 names.sort();
669 assert_eq!(names, ["Adam Kwarasey", "Diego Chara"]);
670 Ok(())
671}
672
673#[driver_test(id(ID), requires(scan), scenario(crate::scenarios::user_with_active))]
674pub async fn query_arbitrary_constraint(test: &mut Test) -> Result<()> {
675 let mut db = setup(test).await;
676
677 for (kind, ts) in [
679 ("info", 0),
680 ("warn", 1),
681 ("info", 2),
682 ("warn", 3),
683 ("info", 4),
684 ("warn", 5),
685 ("info", 6),
686 ("warn", 7),
687 ("info", 8),
688 ("warn", 9),
689 ("info", 10),
690 ("warn", 11),
691 ("info", 12),
692 ("warn", 13),
693 ("info", 14),
694 ("warn", 15),
695 ("info", 16),
696 ("warn", 17),
697 ("info", 18),
698 ("warn", 19),
699 ] {
700 User::create()
701 .name(kind)
702 .age(ts)
703 .active(true)
704 .exec(&mut db)
705 .await?;
706 }
707
708 let events: Vec<_> = User::filter(User::fields().age().gt(12))
709 .exec(&mut db)
710 .await?;
711
712 assert_eq_unordered!(
713 events.iter().map(|event| event.age),
714 [&13, &14, &15, &16, &17, &18, &19,]
715 );
716
717 let events: Vec<_> = User::filter(
718 User::fields()
719 .age()
720 .gt(12)
721 .and(User::fields().name().ne("info")),
722 )
723 .exec(&mut db)
724 .await?;
725
726 assert!(events.iter().all(|event| event.name != "info"));
727
728 assert_eq_unordered!(events.iter().map(|event| event.age), [&13, &15, &17, &19,]);
729
730 let events: Vec<_> = User::filter(
731 User::fields()
732 .name()
733 .eq("info")
734 .and(User::fields().age().ne(10)),
735 )
736 .exec(&mut db)
737 .await?;
738
739 assert_eq_unordered!(
740 events.iter().map(|event| event.age),
741 [&0, &2, &4, &6, &8, &12, &14, &16, &18,]
742 );
743
744 let events: Vec<_> = User::filter(
745 User::fields()
746 .name()
747 .eq("info")
748 .and(User::fields().age().gt(10)),
749 )
750 .exec(&mut db)
751 .await?;
752
753 assert_eq_unordered!(events.iter().map(|event| event.age), [&12, &14, &16, &18,]);
754
755 let events: Vec<_> = User::filter(
756 User::fields()
757 .name()
758 .eq("info")
759 .and(User::fields().age().ge(10)),
760 )
761 .exec(&mut db)
762 .await?;
763
764 assert_eq_unordered!(
765 events.iter().map(|event| event.age),
766 [&10, &12, &14, &16, &18,]
767 );
768
769 let events: Vec<_> = User::filter(
770 User::fields()
771 .name()
772 .eq("info")
773 .and(User::fields().age().lt(10)),
774 )
775 .exec(&mut db)
776 .await?;
777
778 assert_eq_unordered!(events.iter().map(|event| event.age), [&0, &2, &4, &6, &8]);
779
780 let events: Vec<_> = User::filter(
781 User::fields()
782 .name()
783 .eq("info")
784 .and(User::fields().age().le(10)),
785 )
786 .exec(&mut db)
787 .await?;
788
789 assert_eq_unordered!(
790 events.iter().map(|event| event.age),
791 [&0, &2, &4, &6, &8, &10]
792 );
793 Ok(())
794}
795
796#[driver_test(id(ID), scenario(crate::scenarios::user_with_age))]
797pub async fn query_not_basic(test: &mut Test) -> Result<()> {
798 let mut db = setup(test).await;
799
800 for (name, age) in [("Alice", 25), ("Bob", 30), ("Charlie", 35), ("Diana", 40)] {
802 User::create().name(name).age(age).exec(&mut db).await?;
803 }
804
805 test.log().clear();
807
808 let result = User::filter(User::fields().name().eq("Alice").not())
810 .exec(&mut db)
811 .await;
812
813 if test.capability().sql || test.capability().scan {
814 let users = result?;
815 assert_eq!(3, users.len());
816 let mut names: Vec<_> = users.iter().map(|u| u.name.as_str()).collect();
817 names.sort();
818 assert_eq!(names, ["Bob", "Charlie", "Diana"]);
819 } else {
820 assert!(
821 result.is_err(),
822 "Expected error for NOT query without key condition on non-SQL database"
823 );
824 }
825 Ok(())
826}
827
828#[driver_test(id(ID), scenario(crate::scenarios::user_with_active))]
829pub async fn query_not_and_combined(test: &mut Test) -> Result<()> {
830 let mut db = setup(test).await;
831
832 for (name, age, active) in [
834 ("Alice", 25, true),
835 ("Bob", 30, false),
836 ("Charlie", 35, true),
837 ("Diana", 40, false),
838 ("Eve", 25, false),
839 ] {
840 User::create()
841 .name(name)
842 .age(age)
843 .active(active)
844 .exec(&mut db)
845 .await?;
846 }
847
848 let result = User::filter(
851 User::fields()
852 .active()
853 .eq(true)
854 .and(User::fields().age().eq(25).not()),
855 )
856 .exec(&mut db)
857 .await;
858
859 if test.capability().sql || test.capability().scan {
860 let users = result?;
861 assert_eq!(1, users.len());
862 assert_eq!("Charlie", users[0].name);
863 } else {
864 assert!(
865 result.is_err(),
866 "Expected error for NOT query without key condition on non-SQL database"
867 );
868 }
869 Ok(())
870}
871
872#[driver_test(id(ID), scenario(crate::scenarios::user_with_age))]
873pub async fn query_not_or_combined(test: &mut Test) -> Result<()> {
874 let mut db = setup(test).await;
875
876 for (name, age) in [("Alice", 25), ("Bob", 30), ("Charlie", 35), ("Diana", 40)] {
878 User::create().name(name).age(age).exec(&mut db).await?;
879 }
880
881 let result = User::filter(
884 User::fields()
885 .name()
886 .eq("Alice")
887 .or(User::fields().name().eq("Bob"))
888 .not(),
889 )
890 .exec(&mut db)
891 .await;
892
893 if test.capability().sql || test.capability().scan {
894 let users = result?;
895 assert_eq!(2, users.len());
896 let mut names: Vec<_> = users.iter().map(|u| u.name.as_str()).collect();
897 names.sort();
898 assert_eq!(names, ["Charlie", "Diana"]);
899 } else {
900 assert!(
901 result.is_err(),
902 "Expected error for NOT query without key condition on non-SQL database"
903 );
904 }
905 Ok(())
906}
907
908#[driver_test(id(ID))]
909pub async fn query_not_with_index(test: &mut Test) -> Result<()> {
910 #[derive(Debug, toasty::Model)]
911 #[key(partition = team, local = name)]
912 struct Player {
913 team: String,
914
915 name: String,
916
917 #[allow(dead_code)]
918 position: String,
919
920 #[allow(dead_code)]
921 number: i64,
922 }
923
924 let mut db = test.setup_db(models!(Player)).await;
925
926 for (team, name, position, number) in [
928 ("Timbers", "Diego Valeri", "Midfielder", 8),
929 ("Timbers", "Darlington Nagbe", "Midfielder", 6),
930 ("Timbers", "Diego Chara", "Midfielder", 21),
931 ("Timbers", "Fanendo Adi", "Forward", 9),
932 ("Timbers", "Adam Kwarasey", "Goalkeeper", 1),
933 ("Sounders", "Clint Dempsey", "Forward", 2),
934 ("Sounders", "Obafemi Martins", "Forward", 9),
935 ("Sounders", "Osvaldo Alonso", "Midfielder", 6),
936 ] {
937 Player::create()
938 .team(team)
939 .name(name)
940 .position(position)
941 .number(number)
942 .exec(&mut db)
943 .await?;
944 }
945
946 let players = Player::filter(
950 Player::fields()
951 .team()
952 .eq("Timbers")
953 .and(Player::fields().position().eq("Midfielder").not()),
954 )
955 .exec(&mut db)
956 .await?;
957
958 assert_eq!(2, players.len());
959 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
960 names.sort();
961 assert_eq!(names, ["Adam Kwarasey", "Fanendo Adi"]);
962
963 let players = Player::filter(
967 Player::fields()
968 .team()
969 .eq("Timbers")
970 .and(Player::fields().number().gt(8).not()),
971 )
972 .exec(&mut db)
973 .await?;
974
975 assert_eq!(3, players.len());
976 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
977 names.sort();
978 assert_eq!(names, ["Adam Kwarasey", "Darlington Nagbe", "Diego Valeri"]);
979 Ok(())
980}
981
982#[driver_test(id(ID))]
983pub async fn query_not_operator_syntax(test: &mut Test) -> Result<()> {
984 #[derive(Debug, toasty::Model)]
985 #[key(partition = team, local = name)]
986 struct Player {
987 team: String,
988
989 name: String,
990
991 #[allow(dead_code)]
992 position: String,
993
994 #[allow(dead_code)]
995 number: i64,
996 }
997
998 let mut db = test.setup_db(models!(Player)).await;
999
1000 for (team, name, position, number) in [
1001 ("Timbers", "Diego Valeri", "Midfielder", 8),
1002 ("Timbers", "Darlington Nagbe", "Midfielder", 6),
1003 ("Timbers", "Diego Chara", "Midfielder", 21),
1004 ("Timbers", "Fanendo Adi", "Forward", 9),
1005 ("Timbers", "Adam Kwarasey", "Goalkeeper", 1),
1006 ] {
1007 Player::create()
1008 .team(team)
1009 .name(name)
1010 .position(position)
1011 .number(number)
1012 .exec(&mut db)
1013 .await?;
1014 }
1015
1016 let players = Player::filter(
1019 Player::fields()
1020 .team()
1021 .eq("Timbers")
1022 .and(!Player::fields().position().eq("Midfielder")),
1023 )
1024 .exec(&mut db)
1025 .await?;
1026
1027 assert_eq!(2, players.len());
1028 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
1029 names.sort();
1030 assert_eq!(names, ["Adam Kwarasey", "Fanendo Adi"]);
1031
1032 let players = Player::filter(
1034 Player::fields().team().eq("Timbers").and(
1035 !(Player::fields()
1036 .number()
1037 .gt(8)
1038 .or(Player::fields().position().eq("Goalkeeper"))),
1039 ),
1040 )
1041 .exec(&mut db)
1042 .await?;
1043
1044 assert_eq!(2, players.len());
1047 let mut names: Vec<_> = players.iter().map(|p| p.name.as_str()).collect();
1048 names.sort();
1049 assert_eq!(names, ["Darlington Nagbe", "Diego Valeri"]);
1050 Ok(())
1051}