diff options
| author | 2022-08-16 00:21:40 +0200 | |
|---|---|---|
| committer | 2022-09-11 17:12:37 +0200 | |
| commit | c72edf38dcdb0865b8086b853bafae07d4072b44 (patch) | |
| tree | 41181b1ca3f5858d885a427e37785240064ee5da /helpers.zig | |
| parent | move setFunctionResult to helpers.setResult (diff) | |
| download | zig-sqlite-c72edf38dcdb0865b8086b853bafae07d4072b44.tar.gz zig-sqlite-c72edf38dcdb0865b8086b853bafae07d4072b44.tar.xz zig-sqlite-c72edf38dcdb0865b8086b853bafae07d4072b44.zip | |
move setFunctionArgument to helpers.setTypeFromValue
Will be used in the virtual table implementation
Diffstat (limited to 'helpers.zig')
| -rw-r--r-- | helpers.zig | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/helpers.zig b/helpers.zig index 17a5b64..aa04f54 100644 --- a/helpers.zig +++ b/helpers.zig | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const debug = std.debug; | ||
| 2 | 3 | ||
| 3 | const c = @import("c.zig").c; | 4 | const c = @import("c.zig").c; |
| 4 | 5 | ||
| @@ -39,3 +40,49 @@ pub fn setResult(ctx: ?*c.sqlite3_context, result: anytype) void { | |||
| 39 | }, | 40 | }, |
| 40 | } | 41 | } |
| 41 | } | 42 | } |
| 43 | |||
| 44 | /// Sets a type using the provided value. | ||
| 45 | /// | ||
| 46 | /// Determines at compile time which sqlite3_value_XYZ function to use based on the type `ArgType`. | ||
| 47 | pub fn setTypeFromValue(comptime ArgType: type, arg: *ArgType, sqlite_value: *c.sqlite3_value) void { | ||
| 48 | switch (ArgType) { | ||
| 49 | Text => arg.*.data = sliceFromValue(sqlite_value), | ||
| 50 | Blob => arg.*.data = sliceFromValue(sqlite_value), | ||
| 51 | else => switch (@typeInfo(ArgType)) { | ||
| 52 | .Int => |info| if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 32) { | ||
| 53 | const value = c.sqlite3_value_int(sqlite_value); | ||
| 54 | arg.* = @intCast(ArgType, value); | ||
| 55 | } else if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 64) { | ||
| 56 | const value = c.sqlite3_value_int64(sqlite_value); | ||
| 57 | arg.* = @intCast(ArgType, value); | ||
| 58 | } else { | ||
| 59 | @compileError("integer " ++ @typeName(ArgType) ++ " is not representable in sqlite"); | ||
| 60 | }, | ||
| 61 | .Float => { | ||
| 62 | const value = c.sqlite3_value_double(sqlite_value); | ||
| 63 | arg.* = @floatCast(ArgType, value); | ||
| 64 | }, | ||
| 65 | .Bool => { | ||
| 66 | const value = c.sqlite3_value_int(sqlite_value); | ||
| 67 | arg.* = value > 0; | ||
| 68 | }, | ||
| 69 | .Pointer => |ptr| switch (ptr.size) { | ||
| 70 | .Slice => switch (ptr.child) { | ||
| 71 | u8 => arg.* = sliceFromValue(sqlite_value), | ||
| 72 | else => @compileError("cannot use an argument of type " ++ @typeName(ArgType)), | ||
| 73 | }, | ||
| 74 | else => @compileError("cannot use an argument of type " ++ @typeName(ArgType)), | ||
| 75 | }, | ||
| 76 | else => @compileError("cannot use an argument of type " ++ @typeName(ArgType)), | ||
| 77 | }, | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | fn sliceFromValue(sqlite_value: *c.sqlite3_value) []const u8 { | ||
| 82 | const size = @intCast(usize, c.sqlite3_value_bytes(sqlite_value)); | ||
| 83 | |||
| 84 | const value = c.sqlite3_value_text(sqlite_value); | ||
| 85 | debug.assert(value != null); // TODO(vincent): how do we handle this properly ? | ||
| 86 | |||
| 87 | return value.?[0..size]; | ||
| 88 | } | ||