rasi_spec/
rdbc.rs

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
22/// Run `rdbcq` spec.
23pub 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}