1use rasi::rdbc::{Connection, SqlParameter, SqlValue};
2use std::future::Future;
3
4async fn run_spec<R, F>(name: &str, conn: Connection, f: F)
5where
6 F: FnOnce(Connection) -> R,
7 R: Future<Output = ()> + Send,
8{
9 print!("rdbcq-spec({})", name);
10
11 f(conn).await;
12
13 println!(" -- ok");
14}
15
16macro_rules! spec {
17 ($t:expr,$setup: expr) => {
18 run_spec(stringify!($t), $setup().await, $t).await
19 };
20}
21
22pub async fn run<R, S>(setup: S)
24where
25 S: Fn() -> R,
26 R: Future<Output = Connection>,
27{
28 spec!(crud, setup);
29 spec!(tx, setup);
30 spec!(prepare, setup);
31}
32
33async fn crud(conn: Connection) {
34 conn.exec("CREATE TABLE t1(x INT,y INT);", &[])
35 .await
36 .unwrap();
37
38 conn.exec("INSERT INTO t1(x,y) VALUES(4,4);", &[])
39 .await
40 .unwrap();
41
42 conn.exec("INSERT INTO t1(x,y) VALUES(5,5);", &[])
43 .await
44 .unwrap();
45
46 conn.exec("INSERT INTO t1(x,y) VALUES(6,6);", &[])
47 .await
48 .unwrap();
49
50 let query = conn.query("SELECT count(x) from t1", &[]).await.unwrap();
51
52 let row = query.next().await.unwrap().unwrap();
53
54 assert_eq!(row.ensure_int(0).unwrap(), 3);
55
56 assert!(query.next().await.unwrap().is_none());
57
58 let query = conn.query("SELECT * from t1", &[]).await.unwrap();
59
60 let mut idx = 0;
61
62 while let Some(row) = query.next().await.unwrap() {
63 let value = idx + 4;
64 idx += 1;
65
66 assert_eq!(row.ensure_int(0).unwrap(), value);
67 assert_eq!(row.ensure_int(1).unwrap(), value);
68 }
69
70 assert_eq!(idx, 3);
71
72 conn.exec("UPDATE t1 SET y=1;", &[]).await.unwrap();
73
74 let query = conn.query("SELECT * from t1", &[]).await.unwrap();
75
76 let mut idx = 0;
77
78 while let Some(row) = query.next().await.unwrap() {
79 let value = idx + 4;
80 idx += 1;
81
82 assert_eq!(row.ensure_int(0).unwrap(), value);
83 assert_eq!(row.ensure_int(1).unwrap(), 1);
84 }
85
86 assert_eq!(idx, 3);
87
88 conn.exec("UPDATE t1 SET y=1;", &[]).await.unwrap();
89
90 conn.exec("DELETE FROM t1;VACUUM;", &[]).await.unwrap();
91
92 let query = conn.query("SELECT count(x) from t1", &[]).await.unwrap();
93
94 let row = query.next().await.unwrap().unwrap();
95
96 assert_eq!(row.ensure_int(0).unwrap(), 0);
97}
98
99async fn tx(conn: Connection) {
100 conn.exec("CREATE TABLE t1(x INT,y INT);", &[])
101 .await
102 .unwrap();
103
104 {
105 let tx = conn.begin().await.unwrap();
106
107 tx.exec("INSERT INTO t1(x,y) VALUES(4,4);", &[])
108 .await
109 .unwrap();
110
111 tx.exec("INSERT INTO t1(x,y) VALUES(5,5);", &[])
112 .await
113 .unwrap();
114
115 tx.exec("INSERT INTO t1(x,y) VALUES(6,6);", &[])
116 .await
117 .unwrap();
118 }
119
120 let query = conn.query("SELECT count(x) from t1", &[]).await.unwrap();
121
122 let row = query.next().await.unwrap().unwrap();
123
124 assert_eq!(row.ensure_int(0).unwrap(), 3);
125
126 conn.exec("DELETE FROM t1;VACUUM;", &[]).await.unwrap();
127
128 {
129 let tx = conn.begin().await.unwrap();
130
131 tx.exec("INSERT INTO t1(x,y) VALUES(4,4);", &[])
132 .await
133 .unwrap();
134
135 tx.exec("INSERT INTO t1(x,y) VALUES(5,5);", &[])
136 .await
137 .unwrap();
138
139 tx.exec("INSERT INTO t1(x,y) VALUES(6,6);", &[])
140 .await
141 .unwrap();
142
143 tx.rollback().await.unwrap();
144 }
145
146 let query = conn.query("SELECT count(x) from t1", &[]).await.unwrap();
147
148 let row = query.next().await.unwrap().unwrap();
149
150 assert_eq!(row.ensure_int(0).unwrap(), 0);
151}
152
153async fn prepare(conn: Connection) {
154 conn.exec("CREATE TABLE t1(x INT,y INT);", &[])
155 .await
156 .unwrap();
157
158 conn.exec("INSERT INTO t1(x,y) VALUES(4,4);", &[])
159 .await
160 .unwrap();
161
162 conn.exec("INSERT INTO t1(x,y) VALUES(5,5);", &[])
163 .await
164 .unwrap();
165
166 conn.exec("INSERT INTO t1(x,y) VALUES(6,6);", &[])
167 .await
168 .unwrap();
169
170 let prepare = conn
171 .prepare("SELECT count(*) FROM t1 where x > ?")
172 .await
173 .unwrap();
174
175 let query = prepare
176 .query(&[SqlParameter::Offset(SqlValue::Int(3))])
177 .await
178 .unwrap();
179
180 let row = query.next().await.unwrap().unwrap();
181
182 assert_eq!(row.ensure_int(0).unwrap(), 3);
183
184 let query = prepare
185 .query(&[SqlParameter::Offset(SqlValue::Int(4))])
186 .await
187 .unwrap();
188
189 let row = query.next().await.unwrap().unwrap();
190
191 assert_eq!(row.ensure_int(0).unwrap(), 2);
192
193 let query = prepare
194 .query(&[SqlParameter::Offset(SqlValue::Int(5))])
195 .await
196 .unwrap();
197
198 let row = query.next().await.unwrap().unwrap();
199
200 assert_eq!(row.ensure_int(0).unwrap(), 1);
201
202 let query = prepare
203 .query(&[SqlParameter::Offset(SqlValue::Int(6))])
204 .await
205 .unwrap();
206
207 let row = query.next().await.unwrap().unwrap();
208
209 assert_eq!(row.ensure_int(0).unwrap(), 0);
210}