From b7cdcce9b5946fd469591124da4b9d4712708a39 Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Thu, 26 Aug 2021 22:40:05 +0200 Subject: implement reading a text column into an enum value directly oneAlloc/nextAlloc can allocate memory so are allowed to use text backed enums. --- sqlite.zig | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/sqlite.zig b/sqlite.zig index ffff45b..6f8705b 100644 --- a/sqlite.zig +++ b/sqlite.zig @@ -682,6 +682,21 @@ pub fn Iterator(comptime Type: type) type { debug.assert(columns == 1); return try self.readPointer(Type, allocator, 0); }, + .Enum => |TI| { + debug.assert(columns == 1); + + const innervalue = try self.readField(Type.BaseType, 0, .{ + .allocator = allocator, + }); + + if (comptime std.meta.trait.isZigString(Type.BaseType)) { + return std.meta.stringToEnum(Type, innervalue) orelse unreachable; + } + if (@typeInfo(Type.BaseType) == .Int) { + return @intToEnum(Type, @intCast(TI.tag_type, innervalue)); + } + @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); + }, .Struct => { std.debug.assert(columns == TypeInfo.Struct.fields.len); return try self.readStruct(.{ @@ -1711,6 +1726,30 @@ test "sqlite: read a single value into an enum backed by an integer" { } } +test "sqlite: read a single value into an enum backed by a string" { + var arena = std.heap.ArenaAllocator.init(testing.allocator); + defer arena.deinit(); + + var db = try getTestDb(); + try createTestTables(&db); + + try db.exec("INSERT INTO user(id, favorite_color) VALUES(?{usize}, ?{[]const u8})", .{}, .{ + .id = @as(usize, 10), + .age = @as([]const u8, "violet"), + }); + + const query = "SELECT favorite_color FROM user WHERE id = ?{usize}"; + + var stmt: Statement(.{}, ParsedQuery.from(query)) = try db.prepare(query); + defer stmt.deinit(); + + const b = try stmt.oneAlloc(TestUser.Color, &arena.allocator, .{}, .{ + .id = @as(usize, 10), + }); + try testing.expect(b != null); + try testing.expectEqual(TestUser.Color.violet, b.?); +} + test "sqlite: read a single value into void" { var db = try getTestDb(); try addTestData(&db); -- cgit v1.2.3