summaryrefslogtreecommitdiff
path: root/errors.zig
diff options
context:
space:
mode:
Diffstat (limited to 'errors.zig')
-rw-r--r--errors.zig56
1 files changed, 50 insertions, 6 deletions
diff --git a/errors.zig b/errors.zig
index 0b3172f..654e93d 100644
--- a/errors.zig
+++ b/errors.zig
@@ -1,4 +1,5 @@
1const std = @import("std"); 1const std = @import("std");
2const mem = std.mem;
2 3
3const c = @import("c.zig").c; 4const c = @import("c.zig").c;
4 5
@@ -126,13 +127,13 @@ pub const Error = SQLiteError ||
126 SQLiteExtendedReadOnlyError || 127 SQLiteExtendedReadOnlyError ||
127 SQLiteExtendedConstraintError; 128 SQLiteExtendedConstraintError;
128 129
129fn greaterThanOrEqualsTo(major: u8, minor: u8, patch: u8) bool { 130fn versionGreaterThanOrEqualTo(major: u8, minor: u8, patch: u8) bool {
130 return c.SQLITE_VERSION_NUMBER >= @as(u32, major) * 1000000 + @as(u32, minor) * 1000 + @as(u32, patch); 131 return c.SQLITE_VERSION_NUMBER >= @as(u32, major) * 1000000 + @as(u32, minor) * 1000 + @as(u32, patch);
131} 132}
132 133
133pub fn errorFromResultCode(code: c_int) Error { 134pub fn errorFromResultCode(code: c_int) Error {
134 // These errors are only available since 3.22.0. 135 // These errors are only available since 3.22.0.
135 if (comptime greaterThanOrEqualsTo(3, 22, 0)) { 136 if (comptime versionGreaterThanOrEqualTo(3, 22, 0)) {
136 switch (code) { 137 switch (code) {
137 c.SQLITE_ERROR_MISSING_COLLSEQ => return error.SQLiteErrorMissingCollSeq, 138 c.SQLITE_ERROR_MISSING_COLLSEQ => return error.SQLiteErrorMissingCollSeq,
138 c.SQLITE_ERROR_RETRY => return error.SQLiteErrorRetry, 139 c.SQLITE_ERROR_RETRY => return error.SQLiteErrorRetry,
@@ -143,7 +144,7 @@ pub fn errorFromResultCode(code: c_int) Error {
143 } 144 }
144 145
145 // These errors are only available since 3.25.0. 146 // These errors are only available since 3.25.0.
146 if (comptime greaterThanOrEqualsTo(3, 25, 0)) { 147 if (comptime versionGreaterThanOrEqualTo(3, 25, 0)) {
147 switch (code) { 148 switch (code) {
148 c.SQLITE_ERROR_SNAPSHOT => return error.SQLiteErrorSnapshot, 149 c.SQLITE_ERROR_SNAPSHOT => return error.SQLiteErrorSnapshot,
149 c.SQLITE_LOCKED_VTAB => return error.SQLiteLockedVTab, 150 c.SQLITE_LOCKED_VTAB => return error.SQLiteLockedVTab,
@@ -153,7 +154,7 @@ pub fn errorFromResultCode(code: c_int) Error {
153 } 154 }
154 } 155 }
155 // These errors are only available since 3.31.0. 156 // These errors are only available since 3.31.0.
156 if (comptime greaterThanOrEqualsTo(3, 31, 0)) { 157 if (comptime versionGreaterThanOrEqualTo(3, 31, 0)) {
157 switch (code) { 158 switch (code) {
158 c.SQLITE_CANTOPEN_SYMLINK => return error.SQLiteCantOpenSymlink, 159 c.SQLITE_CANTOPEN_SYMLINK => return error.SQLiteCantOpenSymlink,
159 c.SQLITE_CONSTRAINT_PINNED => return error.SQLiteConstraintPinned, 160 c.SQLITE_CONSTRAINT_PINNED => return error.SQLiteConstraintPinned,
@@ -161,7 +162,7 @@ pub fn errorFromResultCode(code: c_int) Error {
161 } 162 }
162 } 163 }
163 // These errors are only available since 3.32.0. 164 // These errors are only available since 3.32.0.
164 if (comptime greaterThanOrEqualsTo(3, 32, 0)) { 165 if (comptime versionGreaterThanOrEqualTo(3, 32, 0)) {
165 switch (code) { 166 switch (code) {
166 c.SQLITE_IOERR_DATA => return error.SQLiteIOErrData, // See https://sqlite.org/cksumvfs.html 167 c.SQLITE_IOERR_DATA => return error.SQLiteIOErrData, // See https://sqlite.org/cksumvfs.html
167 c.SQLITE_BUSY_TIMEOUT => return error.SQLiteBusyTimeout, 168 c.SQLITE_BUSY_TIMEOUT => return error.SQLiteBusyTimeout,
@@ -170,7 +171,7 @@ pub fn errorFromResultCode(code: c_int) Error {
170 } 171 }
171 } 172 }
172 // These errors are only available since 3.34.0. 173 // These errors are only available since 3.34.0.
173 if (comptime greaterThanOrEqualsTo(3, 34, 0)) { 174 if (comptime versionGreaterThanOrEqualTo(3, 34, 0)) {
174 switch (code) { 175 switch (code) {
175 c.SQLITE_IOERR_CORRUPTFS => return error.SQLiteIOErrCorruptFS, 176 c.SQLITE_IOERR_CORRUPTFS => return error.SQLiteIOErrCorruptFS,
176 else => {}, 177 else => {},
@@ -271,3 +272,46 @@ pub fn errorFromResultCode(code: c_int) Error {
271 else => std.debug.panic("invalid result code {}", .{code}), 272 else => std.debug.panic("invalid result code {}", .{code}),
272 } 273 }
273} 274}
275
276/// DetailedError contains a SQLite error code and error message.
277pub const DetailedError = struct {
278 code: usize,
279 near: i32,
280 message: []const u8,
281
282 pub fn format(self: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
283 _ = fmt;
284 _ = options;
285
286 _ = try writer.print("{{code: {}, near: {d}, message: {s}}}", .{ self.code, self.near, self.message });
287 }
288};
289
290pub fn getDetailedErrorFromResultCode(code: c_int) DetailedError {
291 return .{
292 .code = @intCast(usize, code),
293 .near = -1,
294 .message = blk: {
295 const msg = c.sqlite3_errstr(code);
296 break :blk mem.sliceTo(msg, 0);
297 },
298 };
299}
300
301pub fn getErrorOffset(db: *c.sqlite3) i32 {
302 if (comptime versionGreaterThanOrEqualTo(3, 38, 0)) {
303 return c.sqlite3_error_offset(db);
304 }
305 return -1;
306}
307
308pub fn getLastDetailedErrorFromDb(db: *c.sqlite3) DetailedError {
309 return .{
310 .code = @intCast(usize, c.sqlite3_extended_errcode(db)),
311 .near = getErrorOffset(db),
312 .message = blk: {
313 const msg = c.sqlite3_errmsg(db);
314 break :blk mem.sliceTo(msg, 0);
315 },
316 };
317}