authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-08-17 23:06:02-07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-08-17 23:06:02-07:00
logcd19192e296443273d1572b297cbc628f11e99b9
tree1fcbb6196d09f0dd04e829536d5ca10e52d69283
parentb9fc4a67c309082dcd7f34d075c9ff25b5156d5b
signature Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

sqlite3: better debug panics


1 files changed, 23 insertions(+), 9 deletions(-)

src/sqlite3.zig+23-9
......@@ -257,21 +257,34 @@ pub const s = struct {
257257 if (code == c.SQLITE_OK) return;
258258 return rc2p(code);
259259 }
260 pub fn rc2p_d(db: *c.sqlite3, code: c_int) Error {
261 if (builtin.mode == .Debug) @panic(std.mem.sliceTo(c.sqlite3_errmsg(db), 0));
262 return rc2e(code);
263 }
264 pub fn assert_d(db: *c.sqlite3, code: c_int) void {
265 if (code == c.SQLITE_OK) return;
266 @panic(std.mem.sliceTo(c.sqlite3_errmsg(db), 0));
267 }
268 pub fn please_d(db: *c.sqlite3, code: c_int) !void {
269 if (code == c.SQLITE_OK) return;
270 return rc2p_d(db, code);
271 }
260272};
261273
262274pub const Statement = struct {
275 db: *c.sqlite3,
263276 stmt: *c.sqlite3_stmt,
264277
265278 pub fn prepare(driver: *Self, query: []const u8) !Statement {
266279 var stmt: ?*c.sqlite3_stmt = null;
267280 var flags: c_uint = 0;
268281 _ = &flags;
269 try s.please(c.sqlite3_prepare_v3(driver.db, query.ptr, @intCast(query.len), flags, &stmt, null));
270 return .{ .stmt = stmt.? };
282 try s.please_d(driver.db, c.sqlite3_prepare_v3(driver.db, query.ptr, @intCast(query.len), flags, &stmt, null));
283 return .{ .db = driver.db, .stmt = stmt.? };
271284 }
272285
273286 pub fn finalize(stmt: Statement) void {
274 s.assert(c.sqlite3_finalize(stmt.stmt));
287 s.assert_d(stmt.db, c.sqlite3_finalize(stmt.stmt));
275288 }
276289
277290 pub fn bindArgs(stmt: Statement, allocator: std.mem.Allocator, args: anytype) !void {
......@@ -289,10 +302,10 @@ pub const Statement = struct {
289302
290303 fn bindType(stmt: Statement, allocator: std.mem.Allocator, idx: usize, T: type, value: T) !void {
291304 if (comptime extras.isZigString(T)) {
292 return s.please(c.sqlite3_bind_text64(stmt.stmt, @intCast(idx), value.ptr, value.len, c.SQLITE_STATIC, c.SQLITE_UTF8));
305 return s.please_d(stmt.db, c.sqlite3_bind_text64(stmt.stmt, @intCast(idx), value.ptr, value.len, c.SQLITE_STATIC, c.SQLITE_UTF8));
293306 }
294307 if (comptime extras.isArrayOf(u8)(T)) {
295 return s.please(c.sqlite3_bind_blob64(stmt.stmt, @intCast(idx), &value, value.len, c.SQLITE_TRANSIENT));
308 return s.please_d(stmt.db, c.sqlite3_bind_blob64(stmt.stmt, @intCast(idx), &value, value.len, c.SQLITE_TRANSIENT));
296309 }
297310 switch (@typeInfo(T)) {
298311 .@"struct" => |info| {
......@@ -304,7 +317,7 @@ pub const Statement = struct {
304317 comptime std.debug.assert(info.bits <= 64);
305318 if (value > std.math.maxInt(c.sqlite_int64)) return error.Overflow;
306319 if (value < std.math.minInt(c.sqlite_int64)) return error.Overflow;
307 return s.please(c.sqlite3_bind_int64(stmt.stmt, @intCast(idx), @intCast(value)));
320 return s.please_d(stmt.db, c.sqlite3_bind_int64(stmt.stmt, @intCast(idx), @intCast(value)));
308321 },
309322 .optional => |info| {
310323 if (value == null) return s.please(c.sqlite3_bind_null(stmt.stmt, @intCast(idx)));
......@@ -352,20 +365,21 @@ pub const Statement = struct {
352365 }
353366
354367 pub fn iterate(stmt: Statement) Iterator {
355 return .{ .stmt = stmt.stmt };
368 return .{ .db = stmt.db, .stmt = stmt.stmt };
356369 }
357370
358371 pub const Iterator = struct {
372 db: *c.sqlite3,
359373 stmt: *c.sqlite3_stmt,
360374
361375 pub fn reset(iter: Iterator) void {
362 return s.please(c.sqlite3_reset(iter.stmt)) catch {};
376 return s.please_d(iter.db, c.sqlite3_reset(iter.stmt)) catch {};
363377 }
364378
365379 pub fn step(iter: Iterator, allocator: std.mem.Allocator, T: type) !?T {
366380 const code = c.sqlite3_step(iter.stmt);
367381 if (code == c.SQLITE_DONE) return null;
368 if (code != c.SQLITE_ROW) return s.rc2p(code);
382 if (code != c.SQLITE_ROW) return s.rc2p_d(iter.db, code);
369383 if (T == void) return;
370384 if (T == string) return try readType(iter, allocator, 0, string);
371385 if (@typeInfo(T) == .int) return try readType(iter, allocator, 0, T);