Skip to content

Commit f8706aa

Browse files
authored
test remaining sqlite funcs (#359)
1 parent 3608a9a commit f8706aa

File tree

5 files changed

+214
-0
lines changed

5 files changed

+214
-0
lines changed

ci/all_tests.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ for roc_file in $EXAMPLES_DIR*.roc; do
105105
DB_PATH=${EXAMPLES_DIR}todos.db $ROC dev $roc_file $ROC_BUILD_FLAGS
106106
elif [ "$base_file" == "sqlite-everything.roc" ]; then
107107
DB_PATH=${EXAMPLES_DIR}todos2.db $ROC dev $roc_file $ROC_BUILD_FLAGS
108+
elif [ "$base_file" == "sqlite-test.roc" ]; then
109+
DB_PATH=${EXAMPLES_DIR}test.db $ROC dev $roc_file $ROC_BUILD_FLAGS
108110
elif [ "$base_file" == "temp-dir.roc" ]; then
109111
$ROC dev $roc_file $ROC_BUILD_FLAGS --linker=legacy
110112
elif [ "$base_file" == "file-accessed-modified-created-time.roc" ] && [ "$IS_MUSL" == "1" ]; then

ci/expect_scripts/sqlite-test.exp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/expect
2+
3+
# uncomment line below for debugging
4+
# exp_internal 1
5+
6+
set timeout 7
7+
8+
source ./ci/expect_scripts/shared-code.exp
9+
10+
set env(DB_PATH) $env(EXAMPLES_DIR)test.db
11+
12+
spawn $env(EXAMPLES_DIR)sqlite-test
13+
14+
expect -exact "Rows: {col_bytes: \[72, 101, 108, 108, 111\], col_f32: 78.9, col_f64: 123.456, col_i16: 1234, col_i32: 123456, col_i8: 123, col_nullable_bytes: (NotNull \[119, 111, 114, 108, 100\]), col_nullable_f32: (NotNull 12.34), col_nullable_f64: (NotNull 456.789), col_nullable_i16: (NotNull 5678), col_nullable_i32: (NotNull 456789), col_nullable_i64: (NotNull 987654321), col_nullable_i8: (NotNull 56), col_nullable_str: (NotNull \"nullable text\"), col_nullable_u16: (NotNull 8765), col_nullable_u32: (NotNull 987654), col_nullable_u64: (NotNull 123456789), col_nullable_u8: (NotNull 78), col_text: \"example text\", col_u16: 4321, col_u32: 654321, col_u8: 234}\r\n{col_bytes: \[119, 111, 114, 108, 100\], col_f32: 23.45, col_f64: 456.789, col_i16: 5678, col_i32: 789012, col_i8: 45, col_nullable_bytes: Null, col_nullable_f32: (NotNull 67.89), col_nullable_f64: Null, col_nullable_i16: Null, col_nullable_i32: (NotNull 123456), col_nullable_i64: Null, col_nullable_i8: Null, col_nullable_str: Null, col_nullable_u16: Null, col_nullable_u32: (NotNull 654321), col_nullable_u64: Null, col_nullable_u8: Null, col_text: \"sample text\", col_u16: 9876, col_u32: 1234567, col_u8: 123}\r\n" {
15+
expect "Row count: 2\r\n" {
16+
expect -exact "Updated rows: \[\"Updated text 1\", \"Updated text 2\"\]\r\n" {
17+
expect -exact "Tagged value test: \[(String \"example text\"), (String \"sample text\")\]\r\n" {
18+
expect "Error: Mismatch: Data type mismatch\r\n" {
19+
expect "Success!\r\n" {
20+
expect eof {
21+
check_exit_and_segfault
22+
}
23+
}
24+
}
25+
}
26+
}
27+
}
28+
}
29+
#}
30+
31+
puts stderr "\nExpect failed: output was different from expected value."
32+
exit 1

examples/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ stdin
2727
stdin-basic
2828
sqlite-basic
2929
sqlite-everything
30+
sqlite-test
3031
task-list
3132
tcp-client
3233
time

examples/sqlite-test.roc

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
app [main!] { pf: platform "../platform/main.roc" }
2+
3+
import pf.Env
4+
import pf.Stdout
5+
import pf.Sqlite
6+
import pf.Arg exposing [Arg]
7+
8+
# Run this test with: `DB_PATH=./tests/test.db roc tests/sqlite.roc`
9+
10+
# Tests functions exposed by the Sqlite module that are not covered by the sqlite files in the examples folder.
11+
12+
# Sql to create the table:
13+
# CREATE TABLE test (
14+
# id INTEGER PRIMARY KEY AUTOINCREMENT,
15+
# col_text TEXT NOT NULL,
16+
# col_bytes BLOB NOT NULL,
17+
# col_i32 INTEGER NOT NULL,
18+
# col_i16 INTEGER NOT NULL,
19+
# col_i8 INTEGER NOT NULL,
20+
# col_u32 INTEGER NOT NULL,
21+
# col_u16 INTEGER NOT NULL,
22+
# col_u8 INTEGER NOT NULL,
23+
# col_f64 REAL NOT NULL,
24+
# col_f32 REAL NOT NULL,
25+
# col_nullable_str TEXT,
26+
# col_nullable_bytes BLOB,
27+
# col_nullable_i64 INTEGER,
28+
# col_nullable_i32 INTEGER,
29+
# col_nullable_i16 INTEGER,
30+
# col_nullable_i8 INTEGER,
31+
# col_nullable_u64 INTEGER,
32+
# col_nullable_u32 INTEGER,
33+
# col_nullable_u16 INTEGER,
34+
# col_nullable_u8 INTEGER,
35+
# col_nullable_f64 REAL,
36+
# col_nullable_f32 REAL
37+
# );
38+
39+
main! : List Arg => Result {} _
40+
main! = |_args|
41+
db_path = Env.var!("DB_PATH")?
42+
43+
# Test Sqlite.str, Sqlite.bytes, Sqlite.i32...
44+
45+
all_rows = Sqlite.query_many!({
46+
path: db_path,
47+
query: "SELECT * FROM test;",
48+
bindings: [],
49+
# This uses the record builder syntax: https://www.roc-lang.org/examples/RecordBuilder/README.html
50+
rows: { Sqlite.decode_record <-
51+
col_text: Sqlite.str("col_text"),
52+
col_bytes: Sqlite.bytes("col_bytes"),
53+
col_i32: Sqlite.i32("col_i32"),
54+
col_i16: Sqlite.i16("col_i16"),
55+
col_i8: Sqlite.i8("col_i8"),
56+
col_u32: Sqlite.u32("col_u32"),
57+
col_u16: Sqlite.u16("col_u16"),
58+
col_u8: Sqlite.u8("col_u8"),
59+
col_f64: Sqlite.f64("col_f64"),
60+
col_f32: Sqlite.f32("col_f32"),
61+
col_nullable_str: Sqlite.nullable_str("col_nullable_str"),
62+
col_nullable_bytes: Sqlite.nullable_bytes("col_nullable_bytes"),
63+
col_nullable_i64: Sqlite.nullable_i64("col_nullable_i64"),
64+
col_nullable_i32: Sqlite.nullable_i32("col_nullable_i32"),
65+
col_nullable_i16: Sqlite.nullable_i16("col_nullable_i16"),
66+
col_nullable_i8: Sqlite.nullable_i8("col_nullable_i8"),
67+
col_nullable_u64: Sqlite.nullable_u64("col_nullable_u64"),
68+
col_nullable_u32: Sqlite.nullable_u32("col_nullable_u32"),
69+
col_nullable_u16: Sqlite.nullable_u16("col_nullable_u16"),
70+
col_nullable_u8: Sqlite.nullable_u8("col_nullable_u8"),
71+
col_nullable_f64: Sqlite.nullable_f64("col_nullable_f64"),
72+
col_nullable_f32: Sqlite.nullable_f32("col_nullable_f32"),
73+
},
74+
})?
75+
76+
rows_texts_str =
77+
all_rows
78+
|> List.map(|row| Inspect.to_str(row))
79+
|> Str.join_with("\n")
80+
81+
Stdout.line!("Rows: ${rows_texts_str}")?
82+
83+
# Test query_prepared! with count
84+
85+
prepared_count = Sqlite.prepare!({
86+
path: db_path,
87+
query: "SELECT COUNT(*) as \"count\" FROM test;",
88+
})?
89+
90+
count = Sqlite.query_prepared!({
91+
stmt: prepared_count,
92+
bindings: [],
93+
row: Sqlite.u64("count"),
94+
})?
95+
96+
Stdout.line!("Row count: ${Num.to_str(count)}")?
97+
98+
# Test execute_prepared! with different params
99+
100+
prepared_update = Sqlite.prepare!({
101+
path: db_path,
102+
query: "UPDATE test SET col_text = :col_text WHERE id = :id;",
103+
})?
104+
105+
Sqlite.execute_prepared!({
106+
stmt: prepared_update,
107+
bindings: [
108+
{ name: ":id", value: Integer(1) },
109+
{ name: ":col_text", value: String("Updated text 1") },
110+
],
111+
})?
112+
113+
Sqlite.execute_prepared!({
114+
stmt: prepared_update,
115+
bindings: [
116+
{ name: ":id", value: Integer(2) },
117+
{ name: ":col_text", value: String("Updated text 2") },
118+
],
119+
})?
120+
121+
# Check if the updates were successful
122+
updated_rows = Sqlite.query_many!({
123+
path: db_path,
124+
query: "SELECT COL_TEXT FROM test;",
125+
bindings: [],
126+
rows: Sqlite.str("col_text"),
127+
})?
128+
129+
Stdout.line!("Updated rows: ${Inspect.to_str(updated_rows)}")?
130+
131+
# revert update
132+
Sqlite.execute_prepared!({
133+
stmt: prepared_update,
134+
bindings: [
135+
{ name: ":id", value: Integer(1) },
136+
{ name: ":col_text", value: String("example text") },
137+
],
138+
})?
139+
140+
Sqlite.execute_prepared!({
141+
stmt: prepared_update,
142+
bindings: [
143+
{ name: ":id", value: Integer(2) },
144+
{ name: ":col_text", value: String("sample text") },
145+
],
146+
})?
147+
148+
# Test tagged_value
149+
tagged_value_test = Sqlite.query_many!({
150+
path: db_path,
151+
query: "SELECT * FROM test;",
152+
bindings: [],
153+
# This uses the record builder syntax: https://www.roc-lang.org/examples/RecordBuilder/README.html
154+
rows: Sqlite.tagged_value("col_text"),
155+
})?
156+
157+
Stdout.line!("Tagged value test: ${Inspect.to_str(tagged_value_test)}")?
158+
159+
# Let's try to trigger a `Data type mismatch` error
160+
sql_res = Sqlite.execute!({
161+
path: db_path,
162+
query: "UPDATE test SET id = :id WHERE col_text = :col_text;",
163+
bindings: [
164+
{ name: ":col_text", value: String("sample text") },
165+
{ name: ":id", value: String("This should be an integer") },
166+
],
167+
})
168+
169+
when sql_res is
170+
Ok(_) ->
171+
crash "This should be an error."
172+
Err(err) ->
173+
when err is
174+
SqliteErr(err_type, _) ->
175+
Stdout.line!("Error: ${Sqlite.errcode_to_str(err_type)}")?
176+
_ ->
177+
crash "This should be an Sqlite error."
178+
179+
Stdout.line!("Success!")

examples/test.db

12 KB
Binary file not shown.

0 commit comments

Comments
 (0)