Skip to content

Commit cfd549b

Browse files
committed
libsql-sqlite3: Add WAL API tests
1 parent 092fd3c commit cfd549b

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed

libsql-sqlite3/src/test_walapi.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#include <sqlite3.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
5+
#if 0
6+
static void dump_frame(unsigned char *frame, size_t size){
7+
for(int addr=0; addr<size; addr+=16){
8+
int sum = 0;
9+
for(int i=0; i<16 && addr+1<size; i++){
10+
sum += frame[addr+i] != 0;
11+
}
12+
if( sum ){
13+
printf("%08x: ", addr);
14+
for(int i=0; i<16 && addr+i<size; i++){
15+
printf("%02x ", frame[addr+i]);
16+
}
17+
printf(" |");
18+
for(int i=0; i<16 && addr+i<size; i++){
19+
printf("%c", frame[addr+i] ? frame[addr+i] : '.');
20+
}
21+
printf("|");
22+
printf("\n");
23+
}
24+
}
25+
}
26+
#endif
27+
28+
static int cmp_data(sqlite3 *db1, sqlite3 *db2){
29+
sqlite3_stmt *stmt1, *stmt2;
30+
int rc;
31+
32+
rc = sqlite3_prepare_v2(db1, "SELECT * FROM users", -1, &stmt1, 0);
33+
if( rc!=SQLITE_OK ){
34+
fprintf(stderr, "Can't prepare statement: %s\n", sqlite3_errmsg(db1));
35+
return 1;
36+
}
37+
38+
rc = sqlite3_prepare_v2(db2, "SELECT * FROM users", -1, &stmt2, 0);
39+
if( rc!=SQLITE_OK ){
40+
fprintf(stderr, "Can't prepare statement: %s\n", sqlite3_errmsg(db2));
41+
return 1;
42+
}
43+
44+
for(;;){
45+
int step1 = sqlite3_step(stmt1);
46+
int step2 = sqlite3_step(stmt2);
47+
if( step1!=step2 ){
48+
fprintf(stderr, "Step mismatch: %d != %d\n", step1, step2);
49+
return 1;
50+
}
51+
if( step1!=SQLITE_ROW ){
52+
break;
53+
}
54+
const unsigned char *name1 = sqlite3_column_text(stmt1, 1);
55+
const unsigned char *name2 = sqlite3_column_text(stmt2, 1);
56+
if( strcmp((const char *)name1, (const char *)name2)!=0 ){
57+
fprintf(stderr, "Data mismatch: %s != %s\n", name1, name2);
58+
return 1;
59+
}
60+
}
61+
return 0;
62+
}
63+
64+
static int sync_db(sqlite3 *db_primary, sqlite3 *db_backup){
65+
unsigned int max_frame;
66+
int rc;
67+
68+
rc = libsql_wal_frame_count(db_primary, &max_frame);
69+
if( rc!=SQLITE_OK ){
70+
fprintf(stderr, "Can't get frame count: %s\n", sqlite3_errmsg(db_primary));
71+
return 1;
72+
}
73+
rc = libsql_wal_insert_begin(db_backup);
74+
if( rc!=SQLITE_OK ){
75+
fprintf(stderr, "Can't begin commit: %s\n", sqlite3_errmsg(db_backup));
76+
return 1;
77+
}
78+
for(int i=1; i<=max_frame; i++){
79+
char frame[4096+24];
80+
rc = libsql_wal_get_frame(db_primary, i, frame, sizeof(frame));
81+
if( rc!=SQLITE_OK ){
82+
fprintf(stderr, "Can't get frame: %s\n", sqlite3_errmsg(db_primary));
83+
return 1;
84+
}
85+
rc = libsql_wal_insert_frame(db_backup, i, frame, sizeof(frame));
86+
if( rc!=SQLITE_OK ){
87+
fprintf(stderr, "Can't inject frame %d: %s\n", rc, sqlite3_errmsg(db_backup));
88+
return 1;
89+
}
90+
}
91+
rc = libsql_wal_insert_end(db_backup);
92+
if( rc!=SQLITE_OK ){
93+
fprintf(stderr, "Can't end commit: %s\n", sqlite3_errmsg(db_backup));
94+
return 1;
95+
}
96+
return 0;
97+
}
98+
99+
static void gen_data(sqlite3 *db){
100+
sqlite3_exec(db, "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)", 0, 0, 0);
101+
sqlite3_exec(db, "INSERT INTO users (id, name) VALUES (1, 'John Doe')", 0, 0, 0);
102+
sqlite3_exec(db, "INSERT INTO users (id, name) VALUES (2, 'Jane Doe')", 0, 0, 0);
103+
sqlite3_exec(db, "INSERT INTO users (id, name) VALUES (3, 'Jim Beam')", 0, 0, 0);
104+
}
105+
106+
int main(int argc, char *argv[])
107+
{
108+
sqlite3 *db_primary, *db_backup;
109+
int rc;
110+
111+
rc = sqlite3_open("primary.db", &db_primary);
112+
if (rc != SQLITE_OK) {
113+
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db_primary));
114+
return 1;
115+
}
116+
rc = sqlite3_wal_autocheckpoint(db_primary, 0);
117+
if (rc != SQLITE_OK) {
118+
fprintf(stderr, "Can't disable checkpointing: %s\n", sqlite3_errmsg(db_primary));
119+
return 1;
120+
}
121+
sqlite3_exec(db_primary, "PRAGMA journal_mode=WAL", NULL, NULL, NULL);
122+
123+
gen_data(db_primary);
124+
125+
rc = sqlite3_open("backup.db", &db_backup);
126+
if (rc != SQLITE_OK) {
127+
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db_backup));
128+
return 1;
129+
}
130+
rc = sqlite3_wal_autocheckpoint(db_backup, 0);
131+
if (rc != SQLITE_OK) {
132+
fprintf(stderr, "Can't disable checkpointing: %s\n", sqlite3_errmsg(db_backup));
133+
return 1;
134+
}
135+
rc = sqlite3_exec(db_backup, "PRAGMA journal_mode=WAL", NULL, NULL, NULL);
136+
if (rc != SQLITE_OK) {
137+
fprintf(stderr, "Can't set journal mode: %s\n", sqlite3_errmsg(db_backup));
138+
return 1;
139+
}
140+
141+
sync_db(db_primary, db_backup);
142+
if (cmp_data(db_primary, db_backup)) {
143+
return 1;
144+
}
145+
146+
sync_db(db_primary, db_backup);
147+
if (cmp_data(db_primary, db_backup)) {
148+
return 1;
149+
}
150+
151+
printf("OK\n");
152+
153+
return 0;
154+
}

0 commit comments

Comments
 (0)