summaryrefslogtreecommitdiff
path: root/sqlite.zig
diff options
context:
space:
mode:
authorGravatar Vincent Rischmann2021-08-26 22:39:55 +0200
committerGravatar Vincent Rischmann2021-08-26 22:40:26 +0200
commit04eb910d7662e7cd5b3351f10d07322e25e0ae18 (patch)
tree1f8ff3441a0ae466cad944ab35d5e499053d7e71 /sqlite.zig
parentfix documentation (diff)
downloadzig-sqlite-04eb910d7662e7cd5b3351f10d07322e25e0ae18.tar.gz
zig-sqlite-04eb910d7662e7cd5b3351f10d07322e25e0ae18.tar.xz
zig-sqlite-04eb910d7662e7cd5b3351f10d07322e25e0ae18.zip
implement reading an integer column into an enum value directly
one/next can't alloc so they are limited to integer values.
Diffstat (limited to '')
-rw-r--r--sqlite.zig61
1 files changed, 60 insertions, 1 deletions
diff --git a/sqlite.zig b/sqlite.zig
index ba895a5..ffff45b 100644
--- a/sqlite.zig
+++ b/sqlite.zig
@@ -604,11 +604,25 @@ pub fn Iterator(comptime Type: type) type {
604 debug.assert(columns == 1); 604 debug.assert(columns == 1);
605 return try self.readArray(Type, 0); 605 return try self.readArray(Type, 0);
606 }, 606 },
607 .Enum => |TI| {
608 debug.assert(columns == 1);
609
610 if (comptime std.meta.trait.isZigString(Type.BaseType)) {
611 @compileError("cannot read into type " ++ @typeName(Type) ++ " ; BaseType " ++ @typeName(Type.BaseType) ++ " requires allocation, use nextAlloc or oneAlloc");
612 }
613
614 if (@typeInfo(Type.BaseType) == .Int) {
615 const innervalue = try self.readField(Type.BaseType, 0, options);
616 return @intToEnum(Type, @intCast(TI.tag_type, innervalue));
617 }
618
619 @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int");
620 },
607 .Struct => { 621 .Struct => {
608 std.debug.assert(columns == TypeInfo.Struct.fields.len); 622 std.debug.assert(columns == TypeInfo.Struct.fields.len);
609 return try self.readStruct(options); 623 return try self.readStruct(options);
610 }, 624 },
611 else => @compileError("cannot read into type " ++ @typeName(Type) ++ " ; if dynamic memory allocation is required use nextAlloc"), 625 else => @compileError("cannot read into type " ++ @typeName(Type) ++ " ; if dynamic memory allocation is required use nextAlloc or oneAlloc"),
612 } 626 }
613 } 627 }
614 628
@@ -1652,6 +1666,51 @@ test "sqlite: read a single integer value" {
1652 } 1666 }
1653} 1667}
1654 1668
1669test "sqlite: read a single value into an enum backed by an integer" {
1670 var arena = std.heap.ArenaAllocator.init(testing.allocator);
1671 defer arena.deinit();
1672
1673 var db = try getTestDb();
1674 try createTestTables(&db);
1675
1676 try db.exec("INSERT INTO user(id, age) VALUES(?{usize}, ?{usize})", .{}, .{
1677 .id = @as(usize, 10),
1678 .age = @as(usize, 0),
1679 });
1680
1681 const query = "SELECT age FROM user WHERE id = ?{usize}";
1682
1683 const IntColor = enum {
1684 violet,
1685
1686 pub const BaseType = u1;
1687 };
1688
1689 // Use one
1690 {
1691 var stmt: Statement(.{}, ParsedQuery.from(query)) = try db.prepare(query);
1692 defer stmt.deinit();
1693
1694 const b = try stmt.one(IntColor, .{}, .{
1695 .id = @as(usize, 10),
1696 });
1697 try testing.expect(b != null);
1698 try testing.expectEqual(IntColor.violet, b.?);
1699 }
1700
1701 // Use oneAlloc
1702 {
1703 var stmt: Statement(.{}, ParsedQuery.from(query)) = try db.prepare(query);
1704 defer stmt.deinit();
1705
1706 const b = try stmt.oneAlloc(IntColor, &arena.allocator, .{}, .{
1707 .id = @as(usize, 10),
1708 });
1709 try testing.expect(b != null);
1710 try testing.expectEqual(IntColor.violet, b.?);
1711 }
1712}
1713
1655test "sqlite: read a single value into void" { 1714test "sqlite: read a single value into void" {
1656 var db = try getTestDb(); 1715 var db = try getTestDb();
1657 try addTestData(&db); 1716 try addTestData(&db);