From da04bbe425714dafc3329e4800afaa0866fb032c Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Fri, 1 Jan 2021 18:46:17 +0100 Subject: reorder fields to workaround a compiler bug --- sqlite.zig | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'sqlite.zig') diff --git a/sqlite.zig b/sqlite.zig index 20ccc6d..29f40bf 100644 --- a/sqlite.zig +++ b/sqlite.zig @@ -889,16 +889,16 @@ pub fn Statement(comptime opts: StatementOptions, comptime query: ParsedQuery) t } const TestUser = struct { - id: usize, name: []const u8, + id: usize, age: usize, weight: f32, }; const test_users = &[_]TestUser{ - .{ .id = 20, .name = "Vincent", .age = 33, .weight = 85.4 }, - .{ .id = 40, .name = "Julien", .age = 35, .weight = 100.3 }, - .{ .id = 60, .name = "José", .age = 40, .weight = 240.2 }, + .{ .name = "Vincent", .id = 20, .age = 33, .weight = 85.4 }, + .{ .name = "Julien", .id = 40, .age = 35, .weight = 100.3 }, + .{ .name = "José", .id = 60, .age = 40, .weight = 240.2 }, }; fn addTestData(db: *Db) !void { @@ -925,7 +925,7 @@ fn addTestData(db: *Db) !void { } for (test_users) |user| { - try db.exec("INSERT INTO user(id, name, age, weight) VALUES(?{usize}, ?{[]const u8}, ?{usize}, ?{f32})", user); + try db.exec("INSERT INTO user(name, id, age, weight) VALUES(?{[]const u8}, ?{usize}, ?{usize}, ?{f32})", user); const rows_inserted = db.rowsAffected(); testing.expectEqual(@as(usize, 1), rows_inserted); @@ -1010,7 +1010,7 @@ test "sqlite: read a single user into a struct" { try db.init(initOptions()); try addTestData(&db); - var stmt = try db.prepare("SELECT id, name, age, weight FROM user WHERE id = ?{usize}"); + var stmt = try db.prepare("SELECT name, id, age, weight FROM user WHERE id = ?{usize}"); defer stmt.deinit(); var rows = try stmt.all(TestUser, &arena.allocator, .{}, .{ @@ -1026,11 +1026,11 @@ test "sqlite: read a single user into a struct" { { var row = try db.one( struct { - id: usize, name: [128:0]u8, + id: usize, age: usize, }, - "SELECT id, name, age FROM user WHERE id = ?{usize}", + "SELECT name, id, age FROM user WHERE id = ?{usize}", .{}, .{@as(usize, 20)}, ); @@ -1046,12 +1046,12 @@ test "sqlite: read a single user into a struct" { { var row = try db.oneAlloc( struct { - id: usize, name: Text, + id: usize, age: usize, }, &arena.allocator, - "SELECT id, name, age FROM user WHERE id = ?{usize}", + "SELECT name, id, age FROM user WHERE id = ?{usize}", .{}, .{@as(usize, 20)}, ); @@ -1072,7 +1072,7 @@ test "sqlite: read all users into a struct" { try db.init(initOptions()); try addTestData(&db); - var stmt = try db.prepare("SELECT id, name, age, weight FROM user"); + var stmt = try db.prepare("SELECT name, id, age, weight FROM user"); defer stmt.deinit(); var rows = try stmt.all(TestUser, &arena.allocator, .{}, .{}); @@ -1094,13 +1094,13 @@ test "sqlite: read in an anonymous struct" { try db.init(initOptions()); try addTestData(&db); - var stmt = try db.prepare("SELECT id, name, name, age, id, weight FROM user WHERE id = ?{usize}"); + var stmt = try db.prepare("SELECT name, id, name, age, id, weight FROM user WHERE id = ?{usize}"); defer stmt.deinit(); var row = try stmt.oneAlloc( struct { - id: usize, name: []const u8, + id: usize, name_2: [200:0xAD]u8, age: usize, is_id: bool, @@ -1129,13 +1129,13 @@ test "sqlite: read in a Text struct" { try db.init(initOptions()); try addTestData(&db); - var stmt = try db.prepare("SELECT id, name, age FROM user WHERE id = ?{usize}"); + var stmt = try db.prepare("SELECT name, id, age FROM user WHERE id = ?{usize}"); defer stmt.deinit(); var row = try stmt.oneAlloc( struct { - id: usize, name: Text, + id: usize, age: usize, }, &arena.allocator, @@ -1342,7 +1342,7 @@ test "sqlite: statement reset" { // Add data - var stmt = try db.prepare("INSERT INTO user(id, name, age, weight) VALUES(?{usize}, ?{[]const u8}, ?{usize}, ?{f32})"); + var stmt = try db.prepare("INSERT INTO user(name, id, age, weight) VALUES(?{[]const u8}, ?{usize}, ?{usize}, ?{f32})"); defer stmt.deinit(); const users = &[_]TestUser{ @@ -1373,7 +1373,7 @@ test "sqlite: statement iterator" { try db.exec("DELETE FROM user", .{}); // Add data - var stmt = try db.prepare("INSERT INTO user(id, name, age, weight) VALUES(?{usize}, ?{[]const u8}, ?{usize}, ?{f32})"); + var stmt = try db.prepare("INSERT INTO user(name, id, age, weight) VALUES(?{[]const u8}, ?{usize}, ?{usize}, ?{f32})"); defer stmt.deinit(); var expected_rows = std.ArrayList(TestUser).init(allocator); -- cgit v1.2.3 From f74d40048465965fe044b4e2e3c26b939256fadf Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Fri, 1 Jan 2021 18:46:57 +0100 Subject: add readField --- sqlite.zig | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'sqlite.zig') diff --git a/sqlite.zig b/sqlite.zig index 29f40bf..125c489 100644 --- a/sqlite.zig +++ b/sqlite.zig @@ -569,27 +569,32 @@ pub fn Iterator(comptime Type: type) type { inline for (@typeInfo(Type).Struct.fields) |field, _i| { const i = @as(usize, _i); - const field_type_info = @typeInfo(field.field_type); - - const ret = switch (field.field_type) { - Blob => try self.readBytes(Blob, options.allocator, i, .Blob), - Text => try self.readBytes(Text, options.allocator, i, .Text), - else => switch (field_type_info) { - .Int => try self.readInt(field.field_type, i), - .Float => try self.readFloat(field.field_type, i), - .Bool => try self.readBool(i), - .Void => {}, - .Array => try self.readArray(field.field_type, i), - .Pointer => try self.readPointer(field.field_type, options.allocator, i), - else => @compileError("cannot populate field " ++ field.name ++ " of type " ++ @typeName(field.field_type)), - }, - }; + + const ret = try self.readField(field.field_type, i, options); @field(value, field.name) = ret; } return value; } + + fn readField(self: *Self, comptime FieldType: type, i: usize, options: anytype) !FieldType { + const field_type_info = @typeInfo(FieldType); + + return switch (FieldType) { + Blob => try self.readBytes(Blob, options.allocator, i, .Blob), + Text => try self.readBytes(Text, options.allocator, i, .Text), + else => switch (field_type_info) { + .Int => try self.readInt(FieldType, i), + .Float => try self.readFloat(FieldType, i), + .Bool => try self.readBool(i), + .Void => {}, + .Array => try self.readArray(FieldType, i), + .Pointer => try self.readPointer(FieldType, options.allocator, i), + else => @compileError("cannot populate field " ++ field.name ++ " of type " ++ @typeName(FieldType)), + }, + }; + } }; } -- cgit v1.2.3 From b9edd067444a0641e7a0ecbb47ef1279b22b8e43 Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Fri, 1 Jan 2021 21:48:29 +0100 Subject: implement reading a value into a one-element pointer --- sqlite.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'sqlite.zig') diff --git a/sqlite.zig b/sqlite.zig index 125c489..32a5f97 100644 --- a/sqlite.zig +++ b/sqlite.zig @@ -529,7 +529,12 @@ pub fn Iterator(comptime Type: type) type { switch (type_info) { .Pointer => |ptr| { switch (ptr.size) { - .One => unreachable, + .One => { + ret = try allocator.create(ptr.child); + errdefer allocator.destroy(ret); + + ret.* = try self.readField(ptr.child, i, .{ .allocator = allocator }); + }, .Slice => switch (ptr.child) { u8 => ret = try self.readBytes(PointerType, allocator, i, .Text), else => @compileError("cannot read pointer of type " ++ @typeName(PointerType)), -- cgit v1.2.3 From f698726cf8bdd37789bc458e80eb6e4a2d05e955 Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Fri, 1 Jan 2021 21:50:48 +0100 Subject: add a test that reads only pointers --- sqlite.zig | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'sqlite.zig') diff --git a/sqlite.zig b/sqlite.zig index 32a5f97..f68d13f 100644 --- a/sqlite.zig +++ b/sqlite.zig @@ -1345,6 +1345,41 @@ test "sqlite: bind pointer" { } } +test "sqlite: read pointers" { + var arena = std.heap.ArenaAllocator.init(testing.allocator); + defer arena.deinit(); + + var db: Db = undefined; + try db.init(initOptions()); + try addTestData(&db); + + const query = "SELECT id, name, age, weight FROM user"; + + var stmt = try db.prepare(query); + defer stmt.deinit(); + + const rows = try stmt.all( + struct { + id: *usize, + name: *[]const u8, + age: *u32, + weight: *f32, + }, + &arena.allocator, + .{}, + .{}, + ); + + testing.expectEqual(@as(usize, 3), rows.len); + for (rows) |row, i| { + const exp = test_users[i]; + testing.expectEqual(exp.id, row.id.*); + testing.expectEqualStrings(exp.name, row.name.*); + testing.expectEqual(exp.age, row.age.*); + testing.expectEqual(exp.weight, row.weight.*); + } +} + test "sqlite: statement reset" { var db: Db = undefined; try db.init(initOptions()); -- cgit v1.2.3