1use std::pin::pin;
2use std::sync::LazyLock;
3use tank::stream::StreamExt;
4use tank::{AsValue, Entity, Executor, QueryBuilder, Row, cols, expr};
5use tokio::sync::Mutex;
6
7static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
8
9#[derive(Entity, Debug, PartialEq)]
10#[tank(name = "reserved_table")]
11pub struct ReservedWords {
12 #[tank(primary_key)]
13 pub id: i32,
14 #[tank(name = "select")]
15 pub select_field: String,
16 #[tank(name = "where")]
17 pub where_field: i32,
18 #[tank(name = "group")]
19 pub group_field: bool,
20 #[tank(name = "order")]
21 pub order_field: Option<String>,
22 #[tank(name = "limit")]
23 pub limit_field: f64,
24}
25
26pub async fn keywords(executor: &mut impl Executor) {
27 let _lock = MUTEX.lock().await;
28
29 ReservedWords::drop_table(executor, true, false)
31 .await
32 .expect("Failed to drop ReservedWords table");
33 ReservedWords::create_table(executor, true, true)
34 .await
35 .expect("Failed to create ReservedWords table");
36
37 let entity = ReservedWords {
39 id: 1,
40 select_field: "value".to_string(),
41 where_field: 42,
42 group_field: true,
43 order_field: Some("asc".to_string()),
44 limit_field: 10.5,
45 };
46 entity
47 .save(executor)
48 .await
49 .expect("Failed to save entity with reserved keywords");
50
51 let found = ReservedWords::find_one(executor, expr!(ReservedWords::id == 1))
52 .await
53 .expect("Failed to query")
54 .expect("Entity not found");
55 assert_eq!(found, entity);
56
57 let found_by_where = ReservedWords::find_one(executor, expr!(ReservedWords::where_field == 42))
58 .await
59 .expect("Failed to query by reserved keyword field");
60 assert!(found_by_where.is_some());
61 assert_eq!(found_by_where.unwrap(), entity);
62
63 {
64 let mut stream = pin!(
65 executor.fetch(
66 QueryBuilder::new()
67 .select(cols!(ReservedWords::group_field, COUNT(*)))
68 .from(ReservedWords::table())
69 .group_by(cols!(ReservedWords::group_field))
70 .build(&executor.driver())
71 )
72 );
73 let row = stream
74 .next()
75 .await
76 .expect("Expected a row")
77 .expect("Query failed");
78 let Row { values, .. } = row;
79 let group_val =
80 bool::try_from_value(values[0].clone()).expect("Failed to decode group bool");
81 let count_val = i64::try_from_value(values[1].clone()).expect("Failed to decode count");
82 assert_eq!(group_val, true);
83 assert_eq!(count_val, 1);
84 }
85 {
86 let mut ordered_stream = pin!(ReservedWords::find_many(executor, true, None));
87 while let Some(res) = ordered_stream.next().await {
88 res.expect("Failed while fetching ordered");
89 }
90 }
91 {
92 let mut stream_ordered = pin!(
93 executor.fetch(
94 QueryBuilder::new()
95 .select(ReservedWords::columns())
96 .from(ReservedWords::table())
97 .order_by(cols!(ReservedWords::order_field ASC))
98 .limit(Some(1))
99 .build(&executor.driver())
100 )
101 );
102
103 let row_ordered = stream_ordered
104 .next()
105 .await
106 .expect("Expected row")
107 .expect("Query failed");
108 let entity_ordered = ReservedWords::from_row(row_ordered).expect("Failed to parse entity");
109 assert_eq!(entity_ordered.order_field.as_deref(), Some("asc"));
110 }
111
112 let entity2 = ReservedWords {
113 id: 2,
114 select_field: "value2".to_string(),
115 where_field: 43,
116 group_field: false,
117 order_field: Some("desc".to_string()),
118 limit_field: 20.5,
119 };
120 entity2.save(executor).await.expect("Saved 2");
121 {
122 let mut stream_group = pin!(
123 executor.fetch(
124 QueryBuilder::new()
125 .select(cols!(ReservedWords::group_field, COUNT(*)))
126 .from(ReservedWords::table())
127 .group_by(cols!(ReservedWords::group_field))
128 .order_by(cols!(ReservedWords::group_field ASC))
129 .build(&executor.driver())
130 )
131 );
132
133 let row1 = stream_group.next().await.unwrap().unwrap();
134 let Row { values, .. } = row1;
135 let g = bool::try_from_value(values[0].clone()).unwrap();
136 assert_eq!(g, false);
137
138 let row2 = stream_group.next().await.unwrap().unwrap();
139 let Row { values, .. } = row2;
140 let g = bool::try_from_value(values[0].clone()).unwrap();
141 assert_eq!(g, true);
142 }
143
144 let found_limit = ReservedWords::find_one(executor, expr!(ReservedWords::limit_field > 15.0))
145 .await
146 .expect("Query limit failed")
147 .expect("Limit entity not found");
148 assert_eq!(found_limit.id, 2);
149}