comptime sql bindings for zig
ziglang sql

fix fromRow to use type-aware row accessors

- call row.text(idx) for []const u8 fields
- call row.int(idx) for i64 fields
- call row.int(idx) != 0 for bool fields
- matches leaflet-search's Row interface

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+27 -10
+27 -10
src/Query.zig
··· 48 48 } 49 49 50 50 /// map row data to a struct using column names 51 - pub fn fromRow(comptime T: type, row_data: anytype) T { 51 + /// row must have .text(idx) and .int(idx) methods 52 + pub fn fromRow(comptime T: type, row: anytype) T { 52 53 comptime validateStruct(T); 53 54 var result: T = undefined; 54 55 const fields = @typeInfo(T).@"struct".fields; 55 56 inline for (fields) |f| { 56 57 const idx = comptime columnIndex(f.name); 57 - @field(result, f.name) = row_data.get(idx); 58 + @field(result, f.name) = switch (f.type) { 59 + []const u8 => row.text(idx), 60 + i64 => row.int(idx), 61 + bool => row.int(idx) != 0, 62 + else => @compileError("unsupported field type: " ++ @typeName(f.type)), 63 + }; 58 64 } 59 65 return result; 60 66 } ··· 138 144 test "fromRow" { 139 145 const Q = Query("SELECT id, name, age FROM users"); 140 146 147 + // mock row matching leaflet-search's Row interface 141 148 const MockRow = struct { 142 - values: [3]i64, 143 - pub fn get(self: @This(), idx: usize) i64 { 144 - return self.values[idx]; 149 + texts: [3][]const u8, 150 + ints: [3]i64, 151 + 152 + pub fn text(self: @This(), idx: usize) []const u8 { 153 + return self.texts[idx]; 154 + } 155 + pub fn int(self: @This(), idx: usize) i64 { 156 + return self.ints[idx]; 145 157 } 146 158 }; 147 159 148 - const row = MockRow{ .values = .{ 42, 100, 25 } }; 149 - const Result = struct { id: i64, age: i64 }; 150 - const result = Q.fromRow(Result, row); 160 + const row = MockRow{ 161 + .texts = .{ "42", "alice", "25" }, 162 + .ints = .{ 42, 0, 25 }, 163 + }; 164 + 165 + const User = struct { id: i64, name: []const u8, age: i64 }; 166 + const user = Q.fromRow(User, row); 151 167 152 - try std.testing.expectEqual(42, result.id); 153 - try std.testing.expectEqual(25, result.age); 168 + try std.testing.expectEqual(42, user.id); 169 + try std.testing.expectEqualStrings("alice", user.name); 170 + try std.testing.expectEqual(25, user.age); 154 171 }