summaryrefslogtreecommitdiff
path: root/sqlite.zig
diff options
context:
space:
mode:
Diffstat (limited to 'sqlite.zig')
-rw-r--r--sqlite.zig80
1 files changed, 42 insertions, 38 deletions
diff --git a/sqlite.zig b/sqlite.zig
index 12e9781..c08ded6 100644
--- a/sqlite.zig
+++ b/sqlite.zig
@@ -196,19 +196,15 @@ pub fn Iterator(comptime Type: type) type {
196 switch (Type) { 196 switch (Type) {
197 []const u8, []u8 => { 197 []const u8, []u8 => {
198 debug.assert(columns == 1); 198 debug.assert(columns == 1);
199 return try self.readBytes(Type, 0, options, .Text); 199 return try self.readBytes(Type, 0, .Text, options);
200 }, 200 },
201 Blob => { 201 Blob => {
202 debug.assert(columns == 1); 202 debug.assert(columns == 1);
203 var ret: Type = undefined; 203 return try self.readBytes(Blob, 0, .Blob, options);
204 ret.data = try self.readBytes([]const u8, 0, options, .Blob);
205 return ret;
206 }, 204 },
207 Text => { 205 Text => {
208 debug.assert(columns == 1); 206 debug.assert(columns == 1);
209 var ret: Type = undefined; 207 return try self.readBytes(Text, 0, .Text, options);
210 ret.data = try self.readBytes([]const u8, 0, options, .Text);
211 return ret;
212 }, 208 },
213 else => {}, 209 else => {},
214 } 210 }
@@ -292,26 +288,48 @@ pub fn Iterator(comptime Type: type) type {
292 Text, 288 Text,
293 }; 289 };
294 290
295 fn readBytes(self: *Self, comptime BytesType: type, _i: usize, options: anytype, mode: ReadBytesMode) !BytesType { 291 fn readBytes(self: *Self, comptime BytesType: type, _i: usize, comptime mode: ReadBytesMode, options: anytype) !BytesType {
296 const i = @intCast(c_int, _i); 292 const i = @intCast(c_int, _i);
293
294 var ret: BytesType = switch (BytesType) {
295 Text, Blob => .{ .data = "" },
296 else => "",
297 };
298
297 switch (mode) { 299 switch (mode) {
298 .Blob => { 300 .Blob => {
299 const data = c.sqlite3_column_blob(self.stmt, i); 301 const data = c.sqlite3_column_blob(self.stmt, i);
300 if (data == null) return ""; 302 if (data == null) return ret;
301 303
302 const size = @intCast(usize, c.sqlite3_column_bytes(self.stmt, i)); 304 const size = @intCast(usize, c.sqlite3_column_bytes(self.stmt, i));
303 const ptr = @ptrCast([*c]const u8, data)[0..size]; 305 const ptr = @ptrCast([*c]const u8, data)[0..size];
304 306
305 return options.allocator.dupe(u8, ptr); 307 return switch (BytesType) {
308 []const u8, []u8 => try options.allocator.dupe(u8, ptr),
309 Blob => blk: {
310 var tmp: Blob = undefined;
311 tmp.data = try options.allocator.dupe(u8, ptr);
312 break :blk tmp;
313 },
314 else => @compileError("cannot read blob into type " ++ @typeName(BytesType)),
315 };
306 }, 316 },
307 .Text => { 317 .Text => {
308 const data = c.sqlite3_column_text(self.stmt, i); 318 const data = c.sqlite3_column_text(self.stmt, i);
309 if (data == null) return ""; 319 if (data == null) return ret;
310 320
311 const size = @intCast(usize, c.sqlite3_column_bytes(self.stmt, i)); 321 const size = @intCast(usize, c.sqlite3_column_bytes(self.stmt, i));
312 const ptr = @ptrCast([*c]const u8, data)[0..size]; 322 const ptr = @ptrCast([*c]const u8, data)[0..size];
313 323
314 return options.allocator.dupe(u8, ptr); 324 return switch (BytesType) {
325 []const u8, []u8 => try options.allocator.dupe(u8, ptr),
326 Text => blk: {
327 var tmp: Text = undefined;
328 tmp.data = try options.allocator.dupe(u8, ptr);
329 break :blk tmp;
330 },
331 else => @compileError("cannot read text into type " ++ @typeName(BytesType)),
332 };
315 }, 333 },
316 } 334 }
317 } 335 }
@@ -323,35 +341,21 @@ pub fn Iterator(comptime Type: type) type {
323 const i = @as(usize, _i); 341 const i = @as(usize, _i);
324 const field_type_info = @typeInfo(field.field_type); 342 const field_type_info = @typeInfo(field.field_type);
325 343
326 switch (field.field_type) { 344 const ret = switch (field.field_type) {
327 []const u8, []u8 => { 345 []const u8, []u8 => try self.readBytes(field.field_type, i, .Blob, options),
328 @field(value, field.name) = try self.readBytes(field.field_type, i, options, .Blob); 346 Blob => try self.readBytes(Blob, i, .Blob, options),
329 }, 347 Text => try self.readBytes(Text, i, .Text, options),
330 Blob => {
331 @field(value, field.name).data = try self.readBytes([]const u8, i, options, .Blob);
332 },
333 Text => {
334 @field(value, field.name).data = try self.readBytes([]const u8, i, options, .Text);
335 },
336 else => switch (field_type_info) { 348 else => switch (field_type_info) {
337 .Int => { 349 .Int => try self.readInt(field.field_type, i, options),
338 @field(value, field.name) = try self.readInt(field.field_type, i, options); 350 .Float => try self.readFloat(field.field_type, i, options),
339 }, 351 .Bool => try self.readBool(i, options),
340 .Float => { 352 .Void => {},
341 @field(value, field.name) = try self.readFloat(field.field_type, i, options); 353 .Array => try self.readArray(field.field_type, i),
342 },
343 .Bool => {
344 @field(value, field.name) = try self.readBool(i, options);
345 },
346 .Void => {
347 @field(value, field.name) = {};
348 },
349 .Array => {
350 @field(value, field.name) = try self.readArray(field.field_type, i);
351 },
352 else => @compileError("cannot populate field " ++ field.name ++ " of type " ++ @typeName(field.field_type)), 354 else => @compileError("cannot populate field " ++ field.name ++ " of type " ++ @typeName(field.field_type)),
353 }, 355 },
354 } 356 };
357
358 @field(value, field.name) = ret;
355 } 359 }
356 360
357 return value; 361 return value;