Blame


1 e84153de 2023-12-31 op // This is free and unencumbered software released into the public domain.
2 e84153de 2023-12-31 op //
3 e84153de 2023-12-31 op // Anyone is free to copy, modify, publish, use, compile, sell, or
4 e84153de 2023-12-31 op // distribute this software, either in source code form or as a compiled
5 e84153de 2023-12-31 op // binary, for any purpose, commercial or non-commercial, and by any
6 e84153de 2023-12-31 op // means.
7 e84153de 2023-12-31 op //
8 e84153de 2023-12-31 op // In jurisdictions that recognize copyright laws, the author or authors
9 e84153de 2023-12-31 op // of this software dedicate any and all copyright interest in the
10 e84153de 2023-12-31 op // software to the public domain. We make this dedication for the benefit
11 e84153de 2023-12-31 op // of the public at large and to the detriment of our heirs and
12 e84153de 2023-12-31 op // successors. We intend this dedication to be an overt act of
13 e84153de 2023-12-31 op // relinquishment in perpetuity of all present and future rights to this
14 e84153de 2023-12-31 op // software under copyright law.
15 e84153de 2023-12-31 op //
16 e84153de 2023-12-31 op // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 e84153de 2023-12-31 op // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 e84153de 2023-12-31 op // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 e84153de 2023-12-31 op // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 e84153de 2023-12-31 op // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 e84153de 2023-12-31 op // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 e84153de 2023-12-31 op // OTHER DEALINGS IN THE SOFTWARE.
23 e84153de 2023-12-31 op
24 e84153de 2023-12-31 op use strings;
25 e84153de 2023-12-31 op use types;
26 e84153de 2023-12-31 op use types::c;
27 e84153de 2023-12-31 op
28 7446e0fc 2023-12-31 op export type conn = *opaque;
29 e84153de 2023-12-31 op export type statement = *opaque;
30 e84153de 2023-12-31 op
31 e84153de 2023-12-31 op export def OPEN_READONLY: int = 0x00000001;
32 e84153de 2023-12-31 op export def OPEN_READWRITE: int = 0x00000002;
33 e84153de 2023-12-31 op export def OPEN_CREATE: int = 0x00000004;
34 e84153de 2023-12-31 op export def OPEN_DELETEONCLOSE: int = 0x00000008; // VFS only
35 e84153de 2023-12-31 op export def OPEN_EXCLUSIVE: int = 0x00000010; // VFS only
36 e84153de 2023-12-31 op export def OPEN_AUTOPROXY: int = 0x00000020; // VFS only
37 e84153de 2023-12-31 op export def OPEN_URI: int = 0x00000040;
38 703acc91 2023-12-31 op export def OPEN_MEMORY: int = 0x00000080;
39 703acc91 2023-12-31 op export def OPEN_MAIN_DB: int = 0x00000100; // VFS only
40 703acc91 2023-12-31 op export def OPEN_TEMP_DB: int = 0x00000200; // VFS only
41 703acc91 2023-12-31 op export def OPEN_TRANSIENT_DB: int = 0x00000400; // VFS ONLY
42 703acc91 2023-12-31 op export def OPEN_MAIN_JOURNAL: int = 0x00000800; // VFS ONLY
43 703acc91 2023-12-31 op export def OPEN_TEMP_JOURNAL: int = 0x00001000; // VFS ONLY
44 703acc91 2023-12-31 op export def OPEN_SUBJOURNAL: int = 0x00002000; // VFS ONLY
45 703acc91 2023-12-31 op export def OPEN_SUPER_JOURNAL: int = 0x00004000; // VFS ONLY
46 e84153de 2023-12-31 op export def OPEN_NOMUTEX: int = 0x00008000;
47 703acc91 2023-12-31 op export def OPEN_FULLMUTEX: int = 0x00010000;
48 703acc91 2023-12-31 op export def OPEN_SHAREDCACHE: int = 0x00020000;
49 703acc91 2023-12-31 op export def OPEN_PRIVATECACHE: int = 0x00040000;
50 e84153de 2023-12-31 op export def OPEN_WAL: int = 0x00080000; // VFS only
51 e84153de 2023-12-31 op export def OPEN_NOFOLLOW: int = 0x01000000;
52 e84153de 2023-12-31 op export def OPEN_EXRESCODE: int = 0x02000000;
53 e84153de 2023-12-31 op
54 e84153de 2023-12-31 op export def def_open_flags = OPEN_READWRITE | OPEN_CREATE | OPEN_WAL |
55 e84153de 2023-12-31 op OPEN_URI | OPEN_NOMUTEX;
56 e84153de 2023-12-31 op
57 e84153de 2023-12-31 op @symbol("sqlite3_open_v2") fn libsqlite3_open_v2(
58 e84153de 2023-12-31 op filename: *const c::char,
59 e84153de 2023-12-31 op sqlite3: *opaque,
60 e84153de 2023-12-31 op flags: int,
61 e84153de 2023-12-31 op vfs: nullable *const c::char,
62 e84153de 2023-12-31 op ) int;
63 e84153de 2023-12-31 op
64 19e3939c 2023-12-31 op // Opens an SQLite database file as specified by the filename
65 19e3939c 2023-12-31 op // argument. If no flags are provided, [[def_open_flags]] is assumed.
66 19e3939c 2023-12-31 op // The OPEN_WAL flag is "abused" to implicitly enable the WAL journal
67 19e3939c 2023-12-31 op // mode if specified, as it's not a valid open flag otherwise.
68 7446e0fc 2023-12-31 op export fn open(filename: const str, flags: int...) (conn | error) = {
69 19e3939c 2023-12-31 op // XXX VFS support?
70 19e3939c 2023-12-31 op
71 e84153de 2023-12-31 op let f = if (len(flags) == 0) def_open_flags else flags[0];
72 e84153de 2023-12-31 op
73 19e3939c 2023-12-31 op let use_wal: bool = (f & OPEN_WAL) != 0;
74 19e3939c 2023-12-31 op f &= ~OPEN_WAL;
75 19e3939c 2023-12-31 op
76 e84153de 2023-12-31 op let path = c::fromstr(filename);
77 e84153de 2023-12-31 op defer free(path);
78 e84153de 2023-12-31 op
79 e84153de 2023-12-31 op let addr: uintptr = 0;
80 e84153de 2023-12-31 op let ret = libsqlite3_open_v2(path, &addr: *opaque, f, null);
81 19e3939c 2023-12-31 op if (ret != sqlite_ok) {
82 19e3939c 2023-12-31 op return code2err(ret);
83 e84153de 2023-12-31 op };
84 19e3939c 2023-12-31 op
85 19e3939c 2023-12-31 op let conn = addr: *opaque: conn;
86 19e3939c 2023-12-31 op
87 19e3939c 2023-12-31 op if (use_wal) {
88 19e3939c 2023-12-31 op let stmt = prepare(conn, "PRAGMA journal_mode=wal;")?;
89 19e3939c 2023-12-31 op defer finalize(stmt)!; // cannot propagate error in defer
90 19e3939c 2023-12-31 op runstmt(stmt)?;
91 19e3939c 2023-12-31 op };
92 19e3939c 2023-12-31 op
93 19e3939c 2023-12-31 op return conn;
94 e84153de 2023-12-31 op };
95 e84153de 2023-12-31 op
96 e84153de 2023-12-31 op @symbol("sqlite3_close_v2") fn libsqlite3_close_v2(sqlite3: *opaque) int;
97 e84153de 2023-12-31 op
98 73419a01 2023-12-31 op // Closes a database connection.
99 7446e0fc 2023-12-31 op export fn close(conn: conn) (void | error) = {
100 7446e0fc 2023-12-31 op let ret = libsqlite3_close_v2(conn: *opaque);
101 e84153de 2023-12-31 op if (ret != sqlite_ok) {
102 e84153de 2023-12-31 op return code2err(ret);
103 e84153de 2023-12-31 op };
104 e84153de 2023-12-31 op };
105 e84153de 2023-12-31 op
106 e84153de 2023-12-31 op @symbol("sqlite3_prepare_v2") fn libsqlite3_prepare_v2(
107 e84153de 2023-12-31 op sqlite3: *opaque,
108 e84153de 2023-12-31 op sql: *const c::char,
109 e84153de 2023-12-31 op nbyte: int,
110 e84153de 2023-12-31 op stmt: *opaque,
111 e84153de 2023-12-31 op tail: nullable *opaque,
112 e84153de 2023-12-31 op ) int;
113 e84153de 2023-12-31 op
114 73419a01 2023-12-31 op // Prepares a statement that would run the given SQL. Parameters in
115 73419a01 2023-12-31 op // the query can be specified using ?, ?NNN, :VVV, @VVV or $VVV (with
116 73419a01 2023-12-31 op // NNN being a integer literal and VVV an alphanumeric identifier) and
117 73419a01 2023-12-31 op // later set with [[bind]]. The statement can then ran with [[step]].
118 73419a01 2023-12-31 op // A statement can be reused by calling [[reset]] (and optionally
119 73419a01 2023-12-31 op // [[clear_bindings]] too). Once a statement is no longer needed it
120 73419a01 2023-12-31 op // should be destroyed with [[finalize]].
121 7446e0fc 2023-12-31 op export fn prepare(conn: conn, sql: const str) (statement | error) = {
122 e84153de 2023-12-31 op let s = c::fromstr(sql);
123 e84153de 2023-12-31 op defer free(s);
124 e84153de 2023-12-31 op
125 e84153de 2023-12-31 op let stmt: uintptr = 0;
126 7446e0fc 2023-12-31 op let ret = libsqlite3_prepare_v2(conn: *opaque, s, -1, &stmt: *opaque,
127 e84153de 2023-12-31 op null);
128 e84153de 2023-12-31 op if (ret == sqlite_ok) {
129 e84153de 2023-12-31 op return stmt: statement;
130 e84153de 2023-12-31 op };
131 e84153de 2023-12-31 op return code2err(ret);
132 e84153de 2023-12-31 op };
133 e84153de 2023-12-31 op
134 e84153de 2023-12-31 op // XXX missing
135 e84153de 2023-12-31 op // sqlite3_bind_blob
136 e84153de 2023-12-31 op // sqlite3_bind_blob64
137 e84153de 2023-12-31 op // sqlite3_bind_double
138 e84153de 2023-12-31 op
139 e84153de 2023-12-31 op @symbol("sqlite3_bind_parameter_index") fn libsqlite3_bind_parameter_index(
140 e84153de 2023-12-31 op stmt: *opaque,
141 e84153de 2023-12-31 op name: *const c::char,
142 e84153de 2023-12-31 op ) int;
143 e84153de 2023-12-31 op
144 e84153de 2023-12-31 op fn bind_parameter_index(stmt: statement, col: (str | int)) (int | error) = {
145 e84153de 2023-12-31 op let name = match (col) {
146 e84153de 2023-12-31 op case let n: int => return n;
147 e84153de 2023-12-31 op case let n: str => yield n;
148 e84153de 2023-12-31 op };
149 e84153de 2023-12-31 op
150 e84153de 2023-12-31 op let n = c::fromstr(name);
151 e84153de 2023-12-31 op defer free(n);
152 e84153de 2023-12-31 op
153 e84153de 2023-12-31 op let ret = libsqlite3_bind_parameter_index(stmt: *opaque, n);
154 e84153de 2023-12-31 op if (ret == 0) {
155 703acc91 2023-12-31 op return range;
156 e84153de 2023-12-31 op };
157 e84153de 2023-12-31 op
158 e84153de 2023-12-31 op return ret;
159 e84153de 2023-12-31 op };
160 e84153de 2023-12-31 op
161 e84153de 2023-12-31 op @symbol("sqlite3_bind_int") fn libsqlite3_bind_int(
162 e84153de 2023-12-31 op stmt: *opaque,
163 e84153de 2023-12-31 op col: int,
164 e84153de 2023-12-31 op val: int,
165 e84153de 2023-12-31 op ) int;
166 e84153de 2023-12-31 op
167 73419a01 2023-12-31 op // Binds an integer value to the parameter given by name or index.
168 e84153de 2023-12-31 op export fn bind_int(stmt: statement, col: (str | int), v: int) (void | error) = {
169 e84153de 2023-12-31 op let n = bind_parameter_index(stmt, col)?;
170 e84153de 2023-12-31 op let ret = libsqlite3_bind_int(stmt: *opaque, n, v);
171 e84153de 2023-12-31 op if (ret != sqlite_ok) {
172 e84153de 2023-12-31 op return code2err(ret);
173 e84153de 2023-12-31 op };
174 e84153de 2023-12-31 op };
175 e84153de 2023-12-31 op
176 e84153de 2023-12-31 op @symbol("sqlite3_bind_null") fn libsqlite3_bind_null(
177 e84153de 2023-12-31 op stmt: *opaque,
178 e84153de 2023-12-31 op col: int,
179 e84153de 2023-12-31 op ) int;
180 e84153de 2023-12-31 op
181 73419a01 2023-12-31 op // Binds a NULL value to the parameter given by name or index.
182 e84153de 2023-12-31 op export fn bind_null(stmt: statement, col: (str | int)) (void | error) = {
183 e84153de 2023-12-31 op let n = bind_parameter_index(stmt, col)?;
184 e84153de 2023-12-31 op let ret = libsqlite3_bind_null(stmt: *opaque, n);
185 e84153de 2023-12-31 op if (ret != sqlite_ok) {
186 e84153de 2023-12-31 op return code2err(ret);
187 e84153de 2023-12-31 op };
188 e84153de 2023-12-31 op };
189 e84153de 2023-12-31 op
190 e84153de 2023-12-31 op fn freecstr(s: *opaque) void = free(s: *c::char);
191 e84153de 2023-12-31 op
192 e84153de 2023-12-31 op @symbol("sqlite3_bind_text") fn libsqlite3_bind_text(
193 e84153de 2023-12-31 op stmt: *opaque,
194 e84153de 2023-12-31 op col: int,
195 e84153de 2023-12-31 op val: *const c::char,
196 e84153de 2023-12-31 op bytelen: int,
197 e84153de 2023-12-31 op freefn: *fn(*opaque) void
198 e84153de 2023-12-31 op ) int;
199 e84153de 2023-12-31 op
200 73419a01 2023-12-31 op // Binds a text value to the parameter given by name or index.
201 e84153de 2023-12-31 op export fn bind_text(stmt: statement, col: (str | int), v: str) (void | error) = {
202 e84153de 2023-12-31 op let n = bind_parameter_index(stmt, col)?;
203 e84153de 2023-12-31 op
204 e84153de 2023-12-31 op let s = c::fromstr(v);
205 e84153de 2023-12-31 op // free'd via the callback
206 e84153de 2023-12-31 op
207 e84153de 2023-12-31 op let ret = libsqlite3_bind_text(stmt: *opaque, n, s, -1, &freecstr);
208 e84153de 2023-12-31 op if (ret != sqlite_ok) {
209 e84153de 2023-12-31 op return code2err(ret);
210 e84153de 2023-12-31 op };
211 e84153de 2023-12-31 op };
212 e84153de 2023-12-31 op
213 73419a01 2023-12-31 op // Binds a value to the parameter given by name or index.
214 e84153de 2023-12-31 op export fn bind(
215 e84153de 2023-12-31 op stmt: statement,
216 e84153de 2023-12-31 op col: (str | int),
217 e84153de 2023-12-31 op val: (int | void | str),
218 e84153de 2023-12-31 op ) (void | error) = {
219 e84153de 2023-12-31 op match (val) {
220 e84153de 2023-12-31 op case let v: int => return bind_int(stmt, col, v);
221 e84153de 2023-12-31 op case let v: void => return bind_null(stmt, col);
222 e84153de 2023-12-31 op case let v: str => return bind_text(stmt, col, v);
223 e84153de 2023-12-31 op };
224 e84153de 2023-12-31 op };
225 e84153de 2023-12-31 op
226 e84153de 2023-12-31 op @symbol("sqlite3_step") fn libsqlite3_step(stmt: *opaque) int;
227 e84153de 2023-12-31 op
228 73419a01 2023-12-31 op // Runs the statement. This function may need to be called more than
229 73419a01 2023-12-31 op // one time to evaluate a statement. A return value of false means
230 73419a01 2023-12-31 op // that the statement was completely executed, true that it should be
231 73419a01 2023-12-31 op // called again, otherwise an error is returned.
232 e84153de 2023-12-31 op export fn step(stmt: statement) (bool | error) = {
233 e84153de 2023-12-31 op let ret = libsqlite3_step(stmt: *opaque);
234 e84153de 2023-12-31 op switch (ret) {
235 e84153de 2023-12-31 op case sqlite_row => return true;
236 e84153de 2023-12-31 op case sqlite_done => return false;
237 e84153de 2023-12-31 op case => return code2err(ret);
238 e84153de 2023-12-31 op };
239 e84153de 2023-12-31 op };
240 e84153de 2023-12-31 op
241 e84153de 2023-12-31 op @symbol("sqlite3_column_text") fn libsqlite3_column_text(
242 e84153de 2023-12-31 op stmt: *opaque,
243 e84153de 2023-12-31 op col: int,
244 e84153de 2023-12-31 op ) *const c::char;
245 e84153de 2023-12-31 op
246 73419a01 2023-12-31 op // Extracts the value of a column as a string. A NULL value is turned
247 73419a01 2023-12-31 op // into the empty string "".
248 e84153de 2023-12-31 op export fn column_text(stmt: statement, col: int) const str = {
249 e84153de 2023-12-31 op let s = libsqlite3_column_text(stmt: *opaque, col);
250 e84153de 2023-12-31 op if (s == null) {
251 e84153de 2023-12-31 op return "";
252 e84153de 2023-12-31 op };
253 e84153de 2023-12-31 op return c::tostr_unsafe(s);
254 e84153de 2023-12-31 op };
255 e84153de 2023-12-31 op
256 e84153de 2023-12-31 op @symbol("sqlite3_column_int") fn libsqlite3_column_int(
257 e84153de 2023-12-31 op stmt: *opaque,
258 e84153de 2023-12-31 op col: int,
259 e84153de 2023-12-31 op ) int;
260 e84153de 2023-12-31 op
261 73419a01 2023-12-31 op // Extracts the values of a column as an integer.
262 e84153de 2023-12-31 op export fn column_int(stmt: statement, col: int) int = {
263 e84153de 2023-12-31 op return libsqlite3_column_int(stmt: *opaque, col);
264 e84153de 2023-12-31 op };
265 e84153de 2023-12-31 op
266 e84153de 2023-12-31 op @symbol("sqlite3_finalize") fn libsqlite3_finalize(stmt: *opaque) int;
267 e84153de 2023-12-31 op
268 73419a01 2023-12-31 op // Deallocates a statement.
269 e84153de 2023-12-31 op export fn finalize(stmt: statement) (void | error) = {
270 e84153de 2023-12-31 op let ret = libsqlite3_finalize(stmt: *opaque);
271 e84153de 2023-12-31 op if (ret != sqlite_ok) {
272 e84153de 2023-12-31 op return code2err(ret);
273 e84153de 2023-12-31 op };
274 e84153de 2023-12-31 op };
275 e84153de 2023-12-31 op
276 e84153de 2023-12-31 op @symbol("sqlite3_reset") fn libsqlite3_reset(stmt: *opaque) int;
277 e84153de 2023-12-31 op
278 73419a01 2023-12-31 op // Resets a statement so that it can be run again. It doesn't clear
279 73419a01 2023-12-31 op // the bindings, for that use [[clear_bindings]] too.
280 e84153de 2023-12-31 op export fn reset(stmt: statement) (void | error) = {
281 e84153de 2023-12-31 op let ret = libsqlite3_reset(stmt: *opaque);
282 e84153de 2023-12-31 op if (ret != sqlite_ok) {
283 e84153de 2023-12-31 op return code2err(ret);
284 e84153de 2023-12-31 op };
285 e84153de 2023-12-31 op };
286 e84153de 2023-12-31 op
287 e84153de 2023-12-31 op @symbol("sqlite3_clear_bindings") fn libsqlite3_clear_bindings(stmt: *opaque) int;
288 e84153de 2023-12-31 op
289 73419a01 2023-12-31 op // Clears the bindings associated with a statement.
290 e84153de 2023-12-31 op export fn clear_bindings(stmt: statement) (void | error) = {
291 e84153de 2023-12-31 op let ret = libsqlite3_clear_bindings(stmt: *opaque);
292 e84153de 2023-12-31 op if (ret != sqlite_ok) {
293 e84153de 2023-12-31 op return code2err(ret);
294 59c79ed2 2023-12-31 op };
295 59c79ed2 2023-12-31 op };
296 59c79ed2 2023-12-31 op
297 73419a01 2023-12-31 op // Helper that runs a statement until it has been fully processed.
298 59c79ed2 2023-12-31 op export fn runstmt(stmt: statement) (void | error) = {
299 59c79ed2 2023-12-31 op for (step(stmt)?) {
300 59c79ed2 2023-12-31 op continue;
301 e84153de 2023-12-31 op };
302 e84153de 2023-12-31 op };