summaryrefslogtreecommitdiff
path: root/helpers.zig
diff options
context:
space:
mode:
authorGravatar Vincent Rischmann2022-08-16 00:21:40 +0200
committerGravatar Vincent Rischmann2022-09-18 20:11:36 +0200
commitab32ef616a520f8a727ff146df68e59d2de0a609 (patch)
treed1cf406ac0ab14678bab54587d0b5af08f136de8 /helpers.zig
parentmove setFunctionResult to helpers.setResult (diff)
downloadzig-sqlite-ab32ef616a520f8a727ff146df68e59d2de0a609.tar.gz
zig-sqlite-ab32ef616a520f8a727ff146df68e59d2de0a609.tar.xz
zig-sqlite-ab32ef616a520f8a727ff146df68e59d2de0a609.zip
move setFunctionArgument to helpers.setTypeFromValue
Will be used in the virtual table implementation
Diffstat (limited to 'helpers.zig')
-rw-r--r--helpers.zig47
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 @@
1const std = @import("std"); 1const std = @import("std");
2const debug = std.debug;
2 3
3const c = @import("c.zig").c; 4const 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`.
47pub 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
81fn 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}