From 22d087fcc09b932b41ec5eacece4f722ef41ee06 Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Wed, 6 Jan 2021 02:02:24 +0100 Subject: allow binding and reading optionals Also allow binding the '(null)' value. --- sqlite.zig | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'sqlite.zig') diff --git a/sqlite.zig b/sqlite.zig index d96c956..2600ee2 100644 --- a/sqlite.zig +++ b/sqlite.zig @@ -548,6 +548,29 @@ pub fn Iterator(comptime Type: type) type { return ret; } + fn readOptional(self: *Self, comptime OptionalType: type, options: anytype, _i: usize) !OptionalType { + const i = @intCast(c_int, _i); + const type_info = @typeInfo(OptionalType); + + var ret: OptionalType = undefined; + switch (type_info) { + .Optional => |opt| { + // Easy way to know if the column represents a null value. + const value = c.sqlite3_column_value(self.stmt, i); + const datatype = c.sqlite3_value_type(value); + + if (datatype == c.SQLITE_NULL) { + return null; + } else { + const val = try self.readField(opt.child, _i, options); + ret = val; + return ret; + } + }, + else => @compileError("cannot read optional of type " ++ @typeName(OptionalType)), + } + } + // readStruct reads an entire sqlite row into a struct. // // Each field correspond to a column; its position in the struct determines the column used for it. @@ -596,6 +619,7 @@ pub fn Iterator(comptime Type: type) type { .Void => {}, .Array => try self.readArray(FieldType, i), .Pointer => try self.readPointer(FieldType, options.allocator, i), + .Optional => try self.readOptional(FieldType, options, i), else => @compileError("cannot populate field of type " ++ @typeName(FieldType)), }, }; @@ -758,6 +782,12 @@ pub fn Statement(comptime opts: StatementOptions, comptime query: ParsedQuery) t else => @compileError("cannot bind field " ++ field_name ++ " of type array of " ++ @typeName(arr.child)), } }, + .Optional => |opt| if (field) |non_null_field| { + self.bindField(opt.child, field_name, i, non_null_field); + } else { + _ = c.sqlite3_bind_null(self.stmt, column); + }, + .Null => _ = c.sqlite3_bind_null(self.stmt, column), else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), }, } @@ -1403,8 +1433,8 @@ test "sqlite: optional" { ); testing.expect(row != null); - testing.expect(row.data == null); - testing.expectEqual(true, row.is_published.?); + testing.expect(row.?.data == null); + testing.expectEqual(true, row.?.is_published.?); } test "sqlite: statement reset" { -- cgit v1.2.3