diff options
Diffstat (limited to '')
| -rw-r--r-- | query.zig | 3 | ||||
| -rw-r--r-- | sqlite.zig | 47 |
2 files changed, 50 insertions, 0 deletions
| @@ -129,6 +129,9 @@ pub const ParsedQuery = struct { | |||
| 129 | if (mem.eql(u8, "f64", type_info)) return f64; | 129 | if (mem.eql(u8, "f64", type_info)) return f64; |
| 130 | if (mem.eql(u8, "f128", type_info)) return f128; | 130 | if (mem.eql(u8, "f128", type_info)) return f128; |
| 131 | 131 | ||
| 132 | // Bool | ||
| 133 | if (mem.eql(u8, "bool", type_info)) return bool; | ||
| 134 | |||
| 132 | // Strings | 135 | // Strings |
| 133 | if (mem.eql(u8, "[]const u8", type_info) or mem.eql(u8, "[]u8", type_info)) { | 136 | if (mem.eql(u8, "[]const u8", type_info) or mem.eql(u8, "[]u8", type_info)) { |
| 134 | return []const u8; | 137 | return []const u8; |
| @@ -224,6 +224,10 @@ pub fn Iterator(comptime Type: type) type { | |||
| 224 | debug.assert(columns == 1); | 224 | debug.assert(columns == 1); |
| 225 | return try self.readFloat(options); | 225 | return try self.readFloat(options); |
| 226 | }, | 226 | }, |
| 227 | .Bool => { | ||
| 228 | debug.assert(columns == 1); | ||
| 229 | return try self.readBool(options); | ||
| 230 | }, | ||
| 227 | .Void => { | 231 | .Void => { |
| 228 | debug.assert(columns == 1); | 232 | debug.assert(columns == 1); |
| 229 | }, | 233 | }, |
| @@ -280,6 +284,11 @@ pub fn Iterator(comptime Type: type) type { | |||
| 280 | return @floatCast(Type, d); | 284 | return @floatCast(Type, d); |
| 281 | } | 285 | } |
| 282 | 286 | ||
| 287 | fn readBool(self: *Self, options: anytype) !Type { | ||
| 288 | const d = c.sqlite3_column_int64(self.stmt, 0); | ||
| 289 | return d > 0; | ||
| 290 | } | ||
| 291 | |||
| 283 | const ReadBytesMode = enum { | 292 | const ReadBytesMode = enum { |
| 284 | Blob, | 293 | Blob, |
| 285 | Text, | 294 | Text, |
| @@ -488,6 +497,7 @@ pub fn Statement(comptime opts: StatementOptions, comptime query: ParsedQuery) t | |||
| 488 | else => switch (field_type_info) { | 497 | else => switch (field_type_info) { |
| 489 | .Int, .ComptimeInt => _ = c.sqlite3_bind_int64(self.stmt, column, @intCast(c_longlong, field_value)), | 498 | .Int, .ComptimeInt => _ = c.sqlite3_bind_int64(self.stmt, column, @intCast(c_longlong, field_value)), |
| 490 | .Float, .ComptimeFloat => _ = c.sqlite3_bind_double(self.stmt, column, field_value), | 499 | .Float, .ComptimeFloat => _ = c.sqlite3_bind_double(self.stmt, column, field_value), |
| 500 | .Bool => _ = c.sqlite3_bind_int64(self.stmt, column, @boolToInt(field_value)), | ||
| 491 | .Array => |arr| { | 501 | .Array => |arr| { |
| 492 | switch (arr.child) { | 502 | switch (arr.child) { |
| 493 | u8 => { | 503 | u8 => { |
| @@ -653,6 +663,7 @@ fn addTestData(db: *Db) !void { | |||
| 653 | \\ id integer PRIMARY KEY, | 663 | \\ id integer PRIMARY KEY, |
| 654 | \\ author_id integer, | 664 | \\ author_id integer, |
| 655 | \\ data text, | 665 | \\ data text, |
| 666 | \\ is_published integer, | ||
| 656 | \\ FOREIGN KEY(author_id) REFERENCES user(id) | 667 | \\ FOREIGN KEY(author_id) REFERENCES user(id) |
| 657 | \\) | 668 | \\) |
| 658 | }; | 669 | }; |
| @@ -938,6 +949,42 @@ test "sqlite: read a single value into void" { | |||
| 938 | _ = try stmt.one(void, .{}, .{ .id = @as(usize, 20) }); | 949 | _ = try stmt.one(void, .{}, .{ .id = @as(usize, 20) }); |
| 939 | } | 950 | } |
| 940 | 951 | ||
| 952 | test "sqlite: read a single value into bool" { | ||
| 953 | var db: Db = undefined; | ||
| 954 | try db.init(testing.allocator, .{ .mode = dbMode() }); | ||
| 955 | try addTestData(&db); | ||
| 956 | |||
| 957 | const query = "SELECT id FROM user WHERE id = ?{usize}"; | ||
| 958 | |||
| 959 | var stmt: Statement(.{}, ParsedQuery.from(query)) = try db.prepare(query); | ||
| 960 | defer stmt.deinit(); | ||
| 961 | |||
| 962 | const b = try stmt.one(bool, .{}, .{ .id = @as(usize, 20) }); | ||
| 963 | testing.expect(b != null); | ||
| 964 | testing.expect(b.?); | ||
| 965 | } | ||
| 966 | |||
| 967 | test "sqlite: insert bool and bind bool" { | ||
| 968 | var db: Db = undefined; | ||
| 969 | try db.init(testing.allocator, .{ .mode = dbMode() }); | ||
| 970 | try addTestData(&db); | ||
| 971 | |||
| 972 | try db.exec("INSERT INTO article(id, author_id, is_published) VALUES(?{usize}, ?{usize}, ?{bool})", .{ | ||
| 973 | .id = @as(usize, 1), | ||
| 974 | .author_id = @as(usize, 20), | ||
| 975 | .is_published = true, | ||
| 976 | }); | ||
| 977 | |||
| 978 | const query = "SELECT id FROM article WHERE is_published = ?{bool}"; | ||
| 979 | |||
| 980 | var stmt: Statement(.{}, ParsedQuery.from(query)) = try db.prepare(query); | ||
| 981 | defer stmt.deinit(); | ||
| 982 | |||
| 983 | const b = try stmt.one(bool, .{}, .{ .is_published = true }); | ||
| 984 | testing.expect(b != null); | ||
| 985 | testing.expect(b.?); | ||
| 986 | } | ||
| 987 | |||
| 941 | test "sqlite: statement reset" { | 988 | test "sqlite: statement reset" { |
| 942 | var db: Db = undefined; | 989 | var db: Db = undefined; |
| 943 | try db.init(testing.allocator, .{ .mode = dbMode() }); | 990 | try db.init(testing.allocator, .{ .mode = dbMode() }); |