diff options
Diffstat (limited to '')
| -rw-r--r-- | sqlite.zig | 120 |
1 files changed, 60 insertions, 60 deletions
| @@ -33,7 +33,7 @@ const logger = std.log.scoped(.sqlite); | |||
| 33 | // Returns true if the passed type is a struct. | 33 | // Returns true if the passed type is a struct. |
| 34 | fn isStruct(comptime T: type) bool { | 34 | fn isStruct(comptime T: type) bool { |
| 35 | const type_info = @typeInfo(T); | 35 | const type_info = @typeInfo(T); |
| 36 | return type_info == .Struct; | 36 | return type_info == .@"struct"; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | // Returns true if the passed type will coerce to []const u8. | 39 | // Returns true if the passed type will coerce to []const u8. |
| @@ -43,9 +43,9 @@ fn isZigString(comptime T: type) bool { | |||
| 43 | return comptime blk: { | 43 | return comptime blk: { |
| 44 | // Only pointer types can be strings, no optionals | 44 | // Only pointer types can be strings, no optionals |
| 45 | const info = @typeInfo(T); | 45 | const info = @typeInfo(T); |
| 46 | if (info != .Pointer) break :blk false; | 46 | if (info != .pointer) break :blk false; |
| 47 | 47 | ||
| 48 | const ptr = &info.Pointer; | 48 | const ptr = &info.pointer; |
| 49 | // Check for CV qualifiers that would prevent coerction to []const u8 | 49 | // Check for CV qualifiers that would prevent coerction to []const u8 |
| 50 | if (ptr.is_volatile or ptr.is_allowzero) break :blk false; | 50 | if (ptr.is_volatile or ptr.is_allowzero) break :blk false; |
| 51 | 51 | ||
| @@ -57,8 +57,8 @@ fn isZigString(comptime T: type) bool { | |||
| 57 | // Otherwise check if it's an array type that coerces to slice. | 57 | // Otherwise check if it's an array type that coerces to slice. |
| 58 | if (ptr.size == .One) { | 58 | if (ptr.size == .One) { |
| 59 | const child = @typeInfo(ptr.child); | 59 | const child = @typeInfo(ptr.child); |
| 60 | if (child == .Array) { | 60 | if (child == .array) { |
| 61 | const arr = &child.Array; | 61 | const arr = &child.array; |
| 62 | break :blk arr.child == u8; | 62 | break :blk arr.child == u8; |
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| @@ -668,14 +668,14 @@ pub const Db = struct { | |||
| 668 | // Validate the functions | 668 | // Validate the functions |
| 669 | 669 | ||
| 670 | const step_fn_info = switch (@typeInfo(@TypeOf(step_func))) { | 670 | const step_fn_info = switch (@typeInfo(@TypeOf(step_func))) { |
| 671 | .Fn => |fn_info| fn_info, | 671 | .@"fn" => |fn_info| fn_info, |
| 672 | else => @compileError("cannot use func, expecting a function"), | 672 | else => @compileError("cannot use func, expecting a function"), |
| 673 | }; | 673 | }; |
| 674 | if (step_fn_info.is_generic) @compileError("step function can't be generic"); | 674 | if (step_fn_info.is_generic) @compileError("step function can't be generic"); |
| 675 | if (step_fn_info.is_var_args) @compileError("step function can't be variadic"); | 675 | if (step_fn_info.is_var_args) @compileError("step function can't be variadic"); |
| 676 | 676 | ||
| 677 | const finalize_fn_info = switch (@typeInfo(@TypeOf(finalize_func))) { | 677 | const finalize_fn_info = switch (@typeInfo(@TypeOf(finalize_func))) { |
| 678 | .Fn => |fn_info| fn_info, | 678 | .@"fn" => |fn_info| fn_info, |
| 679 | else => @compileError("cannot use func, expecting a function"), | 679 | else => @compileError("cannot use func, expecting a function"), |
| 680 | }; | 680 | }; |
| 681 | if (finalize_fn_info.params.len != 1) @compileError("finalize function must take exactly one argument"); | 681 | if (finalize_fn_info.params.len != 1) @compileError("finalize function must take exactly one argument"); |
| @@ -761,7 +761,7 @@ pub const Db = struct { | |||
| 761 | const Type = @TypeOf(func); | 761 | const Type = @TypeOf(func); |
| 762 | 762 | ||
| 763 | const fn_info = switch (@typeInfo(Type)) { | 763 | const fn_info = switch (@typeInfo(Type)) { |
| 764 | .Fn => |fn_info| fn_info, | 764 | .@"fn" => |fn_info| fn_info, |
| 765 | else => @compileError("expecting a function"), | 765 | else => @compileError("expecting a function"), |
| 766 | }; | 766 | }; |
| 767 | if (fn_info.is_generic) @compileError("function can't be generic"); | 767 | if (fn_info.is_generic) @compileError("function can't be generic"); |
| @@ -893,14 +893,14 @@ pub const FunctionContext = struct { | |||
| 893 | 893 | ||
| 894 | fn splitPtrTypes(comptime Type: type) SplitPtrTypes { | 894 | fn splitPtrTypes(comptime Type: type) SplitPtrTypes { |
| 895 | switch (@typeInfo(Type)) { | 895 | switch (@typeInfo(Type)) { |
| 896 | .Pointer => |ptr_info| switch (ptr_info.size) { | 896 | .pointer => |ptr_info| switch (ptr_info.size) { |
| 897 | .One => return SplitPtrTypes{ | 897 | .One => return SplitPtrTypes{ |
| 898 | .ValueType = ptr_info.child, | 898 | .ValueType = ptr_info.child, |
| 899 | .PointerType = Type, | 899 | .PointerType = Type, |
| 900 | }, | 900 | }, |
| 901 | else => @compileError("cannot use type " ++ @typeName(Type) ++ ", must be a single-item pointer"), | 901 | else => @compileError("cannot use type " ++ @typeName(Type) ++ ", must be a single-item pointer"), |
| 902 | }, | 902 | }, |
| 903 | .Void => return SplitPtrTypes{ | 903 | .void => return SplitPtrTypes{ |
| 904 | .ValueType = void, | 904 | .ValueType = void, |
| 905 | .PointerType = undefined, | 905 | .PointerType = undefined, |
| 906 | }, | 906 | }, |
| @@ -1087,41 +1087,41 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1087 | const columns = c.sqlite3_column_count(self.stmt); | 1087 | const columns = c.sqlite3_column_count(self.stmt); |
| 1088 | 1088 | ||
| 1089 | switch (TypeInfo) { | 1089 | switch (TypeInfo) { |
| 1090 | .Int => { | 1090 | .int => { |
| 1091 | debug.assert(columns == 1); | 1091 | debug.assert(columns == 1); |
| 1092 | return try self.readInt(Type, 0); | 1092 | return try self.readInt(Type, 0); |
| 1093 | }, | 1093 | }, |
| 1094 | .Float => { | 1094 | .float => { |
| 1095 | debug.assert(columns == 1); | 1095 | debug.assert(columns == 1); |
| 1096 | return try self.readFloat(Type, 0); | 1096 | return try self.readFloat(Type, 0); |
| 1097 | }, | 1097 | }, |
| 1098 | .Bool => { | 1098 | .bool => { |
| 1099 | debug.assert(columns == 1); | 1099 | debug.assert(columns == 1); |
| 1100 | return try self.readBool(0); | 1100 | return try self.readBool(0); |
| 1101 | }, | 1101 | }, |
| 1102 | .Void => { | 1102 | .void => { |
| 1103 | debug.assert(columns == 1); | 1103 | debug.assert(columns == 1); |
| 1104 | }, | 1104 | }, |
| 1105 | .Array => { | 1105 | .array => { |
| 1106 | debug.assert(columns == 1); | 1106 | debug.assert(columns == 1); |
| 1107 | return try self.readArray(Type, 0); | 1107 | return try self.readArray(Type, 0); |
| 1108 | }, | 1108 | }, |
| 1109 | .Enum => |TI| { | 1109 | .@"enum" => |TI| { |
| 1110 | debug.assert(columns == 1); | 1110 | debug.assert(columns == 1); |
| 1111 | 1111 | ||
| 1112 | if (comptime isZigString(Type.BaseType)) { | 1112 | if (comptime isZigString(Type.BaseType)) { |
| 1113 | @compileError("cannot read into type " ++ @typeName(Type) ++ " ; BaseType " ++ @typeName(Type.BaseType) ++ " requires allocation, use nextAlloc or oneAlloc"); | 1113 | @compileError("cannot read into type " ++ @typeName(Type) ++ " ; BaseType " ++ @typeName(Type.BaseType) ++ " requires allocation, use nextAlloc or oneAlloc"); |
| 1114 | } | 1114 | } |
| 1115 | 1115 | ||
| 1116 | if (@typeInfo(Type.BaseType) == .Int) { | 1116 | if (@typeInfo(Type.BaseType) == .int) { |
| 1117 | const inner_value = try self.readField(Type.BaseType, options, 0); | 1117 | const inner_value = try self.readField(Type.BaseType, options, 0); |
| 1118 | return @enumFromInt(@as(TI.tag_type, @intCast(inner_value))); | 1118 | return @enumFromInt(@as(TI.tag_type, @intCast(inner_value))); |
| 1119 | } | 1119 | } |
| 1120 | 1120 | ||
| 1121 | @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); | 1121 | @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); |
| 1122 | }, | 1122 | }, |
| 1123 | .Struct => { | 1123 | .@"struct" => { |
| 1124 | std.debug.assert(columns == TypeInfo.Struct.fields.len); | 1124 | std.debug.assert(columns == TypeInfo.@"struct".fields.len); |
| 1125 | return try self.readStruct(options); | 1125 | return try self.readStruct(options); |
| 1126 | }, | 1126 | }, |
| 1127 | else => @compileError("cannot read into type " ++ @typeName(Type) ++ " ; if dynamic memory allocation is required use nextAlloc or oneAlloc"), | 1127 | else => @compileError("cannot read into type " ++ @typeName(Type) ++ " ; if dynamic memory allocation is required use nextAlloc or oneAlloc"), |
| @@ -1161,32 +1161,32 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1161 | } | 1161 | } |
| 1162 | 1162 | ||
| 1163 | switch (TypeInfo) { | 1163 | switch (TypeInfo) { |
| 1164 | .Int => { | 1164 | .int => { |
| 1165 | debug.assert(columns == 1); | 1165 | debug.assert(columns == 1); |
| 1166 | return try self.readInt(Type, 0); | 1166 | return try self.readInt(Type, 0); |
| 1167 | }, | 1167 | }, |
| 1168 | .Float => { | 1168 | .float => { |
| 1169 | debug.assert(columns == 1); | 1169 | debug.assert(columns == 1); |
| 1170 | return try self.readFloat(Type, 0); | 1170 | return try self.readFloat(Type, 0); |
| 1171 | }, | 1171 | }, |
| 1172 | .Bool => { | 1172 | .bool => { |
| 1173 | debug.assert(columns == 1); | 1173 | debug.assert(columns == 1); |
| 1174 | return try self.readBool(0); | 1174 | return try self.readBool(0); |
| 1175 | }, | 1175 | }, |
| 1176 | .Void => { | 1176 | .void => { |
| 1177 | debug.assert(columns == 1); | 1177 | debug.assert(columns == 1); |
| 1178 | }, | 1178 | }, |
| 1179 | .Array => { | 1179 | .array => { |
| 1180 | debug.assert(columns == 1); | 1180 | debug.assert(columns == 1); |
| 1181 | return try self.readArray(Type, 0); | 1181 | return try self.readArray(Type, 0); |
| 1182 | }, | 1182 | }, |
| 1183 | .Pointer => { | 1183 | .pointer => { |
| 1184 | debug.assert(columns == 1); | 1184 | debug.assert(columns == 1); |
| 1185 | return try self.readPointer(Type, .{ | 1185 | return try self.readPointer(Type, .{ |
| 1186 | .allocator = allocator, | 1186 | .allocator = allocator, |
| 1187 | }, 0); | 1187 | }, 0); |
| 1188 | }, | 1188 | }, |
| 1189 | .Enum => |TI| { | 1189 | .@"enum" => |TI| { |
| 1190 | debug.assert(columns == 1); | 1190 | debug.assert(columns == 1); |
| 1191 | 1191 | ||
| 1192 | const inner_value = try self.readField(Type.BaseType, .{ .allocator = allocator }, 0); | 1192 | const inner_value = try self.readField(Type.BaseType, .{ .allocator = allocator }, 0); |
| @@ -1198,13 +1198,13 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1198 | // TODO(vincent): don't use unreachable | 1198 | // TODO(vincent): don't use unreachable |
| 1199 | return std.meta.stringToEnum(Type, inner_value) orelse unreachable; | 1199 | return std.meta.stringToEnum(Type, inner_value) orelse unreachable; |
| 1200 | } | 1200 | } |
| 1201 | if (@typeInfo(Type.BaseType) == .Int) { | 1201 | if (@typeInfo(Type.BaseType) == .int) { |
| 1202 | return @enumFromInt(@as(TI.tag_type, @intCast(inner_value))); | 1202 | return @enumFromInt(@as(TI.tag_type, @intCast(inner_value))); |
| 1203 | } | 1203 | } |
| 1204 | @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); | 1204 | @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); |
| 1205 | }, | 1205 | }, |
| 1206 | .Struct => { | 1206 | .@"struct" => { |
| 1207 | std.debug.assert(columns == TypeInfo.Struct.fields.len); | 1207 | std.debug.assert(columns == TypeInfo.@"struct".fields.len); |
| 1208 | return try self.readStruct(.{ | 1208 | return try self.readStruct(.{ |
| 1209 | .allocator = allocator, | 1209 | .allocator = allocator, |
| 1210 | }); | 1210 | }); |
| @@ -1225,7 +1225,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1225 | 1225 | ||
| 1226 | var ret: ArrayType = undefined; | 1226 | var ret: ArrayType = undefined; |
| 1227 | switch (type_info) { | 1227 | switch (type_info) { |
| 1228 | .Array => |arr| { | 1228 | .array => |arr| { |
| 1229 | switch (arr.child) { | 1229 | switch (arr.child) { |
| 1230 | u8 => { | 1230 | u8 => { |
| 1231 | const size: usize = @intCast(c.sqlite3_column_bytes(self.stmt, i)); | 1231 | const size: usize = @intCast(c.sqlite3_column_bytes(self.stmt, i)); |
| @@ -1286,7 +1286,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1286 | // dupeWithSentinel is like dupe/dupeZ but allows for any sentinel value. | 1286 | // dupeWithSentinel is like dupe/dupeZ but allows for any sentinel value. |
| 1287 | fn dupeWithSentinel(comptime SliceType: type, allocator: mem.Allocator, data: []const u8) !SliceType { | 1287 | fn dupeWithSentinel(comptime SliceType: type, allocator: mem.Allocator, data: []const u8) !SliceType { |
| 1288 | switch (@typeInfo(SliceType)) { | 1288 | switch (@typeInfo(SliceType)) { |
| 1289 | .Pointer => |ptr_info| { | 1289 | .pointer => |ptr_info| { |
| 1290 | if (ptr_info.sentinel) |sentinel_ptr| { | 1290 | if (ptr_info.sentinel) |sentinel_ptr| { |
| 1291 | const sentinel = @as(*const ptr_info.child, @ptrCast(sentinel_ptr)).*; | 1291 | const sentinel = @as(*const ptr_info.child, @ptrCast(sentinel_ptr)).*; |
| 1292 | 1292 | ||
| @@ -1364,7 +1364,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1364 | 1364 | ||
| 1365 | var ret: PointerType = undefined; | 1365 | var ret: PointerType = undefined; |
| 1366 | switch (@typeInfo(PointerType)) { | 1366 | switch (@typeInfo(PointerType)) { |
| 1367 | .Pointer => |ptr| { | 1367 | .pointer => |ptr| { |
| 1368 | switch (ptr.size) { | 1368 | switch (ptr.size) { |
| 1369 | .One => { | 1369 | .One => { |
| 1370 | ret = try options.allocator.create(ptr.child); | 1370 | ret = try options.allocator.create(ptr.child); |
| @@ -1392,7 +1392,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1392 | 1392 | ||
| 1393 | var ret: OptionalType = undefined; | 1393 | var ret: OptionalType = undefined; |
| 1394 | switch (@typeInfo(OptionalType)) { | 1394 | switch (@typeInfo(OptionalType)) { |
| 1395 | .Optional => |opt| { | 1395 | .optional => |opt| { |
| 1396 | // Easy way to know if the column represents a null value. | 1396 | // Easy way to know if the column represents a null value. |
| 1397 | const value = c.sqlite3_column_value(self.stmt, @intCast(_i)); | 1397 | const value = c.sqlite3_column_value(self.stmt, @intCast(_i)); |
| 1398 | const datatype = c.sqlite3_value_type(value); | 1398 | const datatype = c.sqlite3_value_type(value); |
| @@ -1437,7 +1437,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1437 | 1437 | ||
| 1438 | var value: Type = undefined; | 1438 | var value: Type = undefined; |
| 1439 | 1439 | ||
| 1440 | inline for (@typeInfo(Type).Struct.fields, 0..) |field, _i| { | 1440 | inline for (@typeInfo(Type).@"struct".fields, 0..) |field, _i| { |
| 1441 | const i = @as(usize, _i); | 1441 | const i = @as(usize, _i); |
| 1442 | 1442 | ||
| 1443 | const ret = try self.readField(field.type, options, i); | 1443 | const ret = try self.readField(field.type, options, i); |
| @@ -1469,14 +1469,14 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1469 | break :blk try self.readBytes(Text, options.allocator, i, .Text); | 1469 | break :blk try self.readBytes(Text, options.allocator, i, .Text); |
| 1470 | }, | 1470 | }, |
| 1471 | else => switch (field_type_info) { | 1471 | else => switch (field_type_info) { |
| 1472 | .Int => try self.readInt(FieldType, i), | 1472 | .int => try self.readInt(FieldType, i), |
| 1473 | .Float => try self.readFloat(FieldType, i), | 1473 | .float => try self.readFloat(FieldType, i), |
| 1474 | .Bool => try self.readBool(i), | 1474 | .bool => try self.readBool(i), |
| 1475 | .Void => {}, | 1475 | .void => {}, |
| 1476 | .Array => try self.readArray(FieldType, i), | 1476 | .array => try self.readArray(FieldType, i), |
| 1477 | .Pointer => try self.readPointer(FieldType, options, i), | 1477 | .pointer => try self.readPointer(FieldType, options, i), |
| 1478 | .Optional => try self.readOptional(FieldType, options, i), | 1478 | .optional => try self.readOptional(FieldType, options, i), |
| 1479 | .Enum => |TI| { | 1479 | .@"enum" => |TI| { |
| 1480 | const inner_value = try self.readField(FieldType.BaseType, options, i); | 1480 | const inner_value = try self.readField(FieldType.BaseType, options, i); |
| 1481 | 1481 | ||
| 1482 | if (comptime isZigString(FieldType.BaseType)) { | 1482 | if (comptime isZigString(FieldType.BaseType)) { |
| @@ -1490,7 +1490,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1490 | } | 1490 | } |
| 1491 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int"); | 1491 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int"); |
| 1492 | }, | 1492 | }, |
| 1493 | .Struct => |TI| { | 1493 | .@"struct" => |TI| { |
| 1494 | if (TI.layout == .@"packed") return @bitCast(try self.readInt(TI.backing_integer.?, i)); | 1494 | if (TI.layout == .@"packed") return @bitCast(try self.readInt(TI.backing_integer.?, i)); |
| 1495 | const inner_value = try self.readField(FieldType.BaseType, options, i); | 1495 | const inner_value = try self.readField(FieldType.BaseType, options, i); |
| 1496 | return try FieldType.readField(options.allocator, inner_value); | 1496 | return try FieldType.readField(options.allocator, inner_value); |
| @@ -1645,19 +1645,19 @@ pub const DynamicStatement = struct { | |||
| 1645 | return convertResultToError(result); | 1645 | return convertResultToError(result); |
| 1646 | }, | 1646 | }, |
| 1647 | else => switch (field_type_info) { | 1647 | else => switch (field_type_info) { |
| 1648 | .Int, .ComptimeInt => { | 1648 | .int, .comptime_int => { |
| 1649 | const result = c.sqlite3_bind_int64(self.stmt, column, @intCast(field)); | 1649 | const result = c.sqlite3_bind_int64(self.stmt, column, @intCast(field)); |
| 1650 | return convertResultToError(result); | 1650 | return convertResultToError(result); |
| 1651 | }, | 1651 | }, |
| 1652 | .Float, .ComptimeFloat => { | 1652 | .float, .comptime_float => { |
| 1653 | const result = c.sqlite3_bind_double(self.stmt, column, field); | 1653 | const result = c.sqlite3_bind_double(self.stmt, column, field); |
| 1654 | return convertResultToError(result); | 1654 | return convertResultToError(result); |
| 1655 | }, | 1655 | }, |
| 1656 | .Bool => { | 1656 | .bool => { |
| 1657 | const result = c.sqlite3_bind_int64(self.stmt, column, @intFromBool(field)); | 1657 | const result = c.sqlite3_bind_int64(self.stmt, column, @intFromBool(field)); |
| 1658 | return convertResultToError(result); | 1658 | return convertResultToError(result); |
| 1659 | }, | 1659 | }, |
| 1660 | .Pointer => |ptr| switch (ptr.size) { | 1660 | .pointer => |ptr| switch (ptr.size) { |
| 1661 | .One => { | 1661 | .One => { |
| 1662 | try self.bindField(ptr.child, options, field_name, i, field.*); | 1662 | try self.bindField(ptr.child, options, field_name, i, field.*); |
| 1663 | }, | 1663 | }, |
| @@ -1671,7 +1671,7 @@ pub const DynamicStatement = struct { | |||
| 1671 | }, | 1671 | }, |
| 1672 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), | 1672 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), |
| 1673 | }, | 1673 | }, |
| 1674 | .Array => |arr| switch (arr.child) { | 1674 | .array => |arr| switch (arr.child) { |
| 1675 | u8 => { | 1675 | u8 => { |
| 1676 | const data: []const u8 = field[0..field.len]; | 1676 | const data: []const u8 = field[0..field.len]; |
| 1677 | 1677 | ||
| @@ -1681,17 +1681,17 @@ pub const DynamicStatement = struct { | |||
| 1681 | }, | 1681 | }, |
| 1682 | else => @compileError("cannot bind field " ++ field_name ++ " of type array of " ++ @typeName(arr.child)), | 1682 | else => @compileError("cannot bind field " ++ field_name ++ " of type array of " ++ @typeName(arr.child)), |
| 1683 | }, | 1683 | }, |
| 1684 | .Optional => |opt| if (field) |non_null_field| { | 1684 | .optional => |opt| if (field) |non_null_field| { |
| 1685 | try self.bindField(opt.child, options, field_name, i, non_null_field); | 1685 | try self.bindField(opt.child, options, field_name, i, non_null_field); |
| 1686 | } else { | 1686 | } else { |
| 1687 | const result = c.sqlite3_bind_null(self.stmt, column); | 1687 | const result = c.sqlite3_bind_null(self.stmt, column); |
| 1688 | return convertResultToError(result); | 1688 | return convertResultToError(result); |
| 1689 | }, | 1689 | }, |
| 1690 | .Null => { | 1690 | .null => { |
| 1691 | const result = c.sqlite3_bind_null(self.stmt, column); | 1691 | const result = c.sqlite3_bind_null(self.stmt, column); |
| 1692 | return convertResultToError(result); | 1692 | return convertResultToError(result); |
| 1693 | }, | 1693 | }, |
| 1694 | .Enum => { | 1694 | .@"enum" => { |
| 1695 | if (comptime isZigString(FieldType.BaseType)) { | 1695 | if (comptime isZigString(FieldType.BaseType)) { |
| 1696 | try self.bindField(FieldType.BaseType, options, field_name, i, @tagName(field)); | 1696 | try self.bindField(FieldType.BaseType, options, field_name, i, @tagName(field)); |
| 1697 | } else if (@typeInfo(FieldType.BaseType) == .Int) { | 1697 | } else if (@typeInfo(FieldType.BaseType) == .Int) { |
| @@ -1700,7 +1700,7 @@ pub const DynamicStatement = struct { | |||
| 1700 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int to bind"); | 1700 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int to bind"); |
| 1701 | } | 1701 | } |
| 1702 | }, | 1702 | }, |
| 1703 | .Struct => |info| { | 1703 | .@"struct" => |info| { |
| 1704 | if (info.layout == .@"packed") { | 1704 | if (info.layout == .@"packed") { |
| 1705 | try self.bindField(info.backing_integer.?, options, field_name, i, @as(info.backing_integer.?, @bitCast(field))); | 1705 | try self.bindField(info.backing_integer.?, options, field_name, i, @as(info.backing_integer.?, @bitCast(field))); |
| 1706 | return; | 1706 | return; |
| @@ -1713,7 +1713,7 @@ pub const DynamicStatement = struct { | |||
| 1713 | 1713 | ||
| 1714 | try self.bindField(FieldType.BaseType, options, field_name, i, field_value); | 1714 | try self.bindField(FieldType.BaseType, options, field_name, i, field_value); |
| 1715 | }, | 1715 | }, |
| 1716 | .Union => |info| { | 1716 | .@"union" => |info| { |
| 1717 | if (info.tag_type) |UnionTagType| { | 1717 | if (info.tag_type) |UnionTagType| { |
| 1718 | inline for (info.fields) |u_field| { | 1718 | inline for (info.fields) |u_field| { |
| 1719 | // This wasn't entirely obvious when I saw code like this elsewhere, it works because of type coercion. | 1719 | // This wasn't entirely obvious when I saw code like this elsewhere, it works because of type coercion. |
| @@ -1771,7 +1771,7 @@ pub const DynamicStatement = struct { | |||
| 1771 | const Type = @TypeOf(values); | 1771 | const Type = @TypeOf(values); |
| 1772 | 1772 | ||
| 1773 | switch (@typeInfo(Type)) { | 1773 | switch (@typeInfo(Type)) { |
| 1774 | .Struct => |StructTypeInfo| { | 1774 | .@"struct" => |StructTypeInfo| { |
| 1775 | inline for (StructTypeInfo.fields, 0..) |struct_field, struct_field_i| { | 1775 | inline for (StructTypeInfo.fields, 0..) |struct_field, struct_field_i| { |
| 1776 | const field_value = @field(values, struct_field.name); | 1776 | const field_value = @field(values, struct_field.name); |
| 1777 | 1777 | ||
| @@ -1783,7 +1783,7 @@ pub const DynamicStatement = struct { | |||
| 1783 | } | 1783 | } |
| 1784 | } | 1784 | } |
| 1785 | }, | 1785 | }, |
| 1786 | .Pointer => |PointerTypeInfo| { | 1786 | .pointer => |PointerTypeInfo| { |
| 1787 | switch (PointerTypeInfo.size) { | 1787 | switch (PointerTypeInfo.size) { |
| 1788 | .Slice => { | 1788 | .Slice => { |
| 1789 | for (values, 0..) |value_to_bind, index| { | 1789 | for (values, 0..) |value_to_bind, index| { |
| @@ -1793,7 +1793,7 @@ pub const DynamicStatement = struct { | |||
| 1793 | else => @compileError("TODO support pointer size " ++ @tagName(PointerTypeInfo.size)), | 1793 | else => @compileError("TODO support pointer size " ++ @tagName(PointerTypeInfo.size)), |
| 1794 | } | 1794 | } |
| 1795 | }, | 1795 | }, |
| 1796 | .Array => |ArrayTypeInfo| { | 1796 | .array => |ArrayTypeInfo| { |
| 1797 | for (values, 0..) |value_to_bind, index| { | 1797 | for (values, 0..) |value_to_bind, index| { |
| 1798 | try self.bindField(ArrayTypeInfo.child, options, "unknown", @intCast(index), value_to_bind); | 1798 | try self.bindField(ArrayTypeInfo.child, options, "unknown", @intCast(index), value_to_bind); |
| 1799 | } | 1799 | } |
| @@ -2067,7 +2067,7 @@ pub fn Statement(comptime opts: StatementOptions, comptime query: anytype) type | |||
| 2067 | @compileError("options passed to Statement.bind must be a struct (DynamicStatement supports runtime slices)"); | 2067 | @compileError("options passed to Statement.bind must be a struct (DynamicStatement supports runtime slices)"); |
| 2068 | } | 2068 | } |
| 2069 | 2069 | ||
| 2070 | const StructTypeInfo = @typeInfo(StructType).Struct; | 2070 | const StructTypeInfo = @typeInfo(StructType).@"struct"; |
| 2071 | 2071 | ||
| 2072 | if (comptime query.bind_markers.len != StructTypeInfo.fields.len) { | 2072 | if (comptime query.bind_markers.len != StructTypeInfo.fields.len) { |
| 2073 | @compileError(std.fmt.comptimePrint("expected {d} bind parameters but got {d}", .{ | 2073 | @compileError(std.fmt.comptimePrint("expected {d} bind parameters but got {d}", .{ |
| @@ -2081,7 +2081,7 @@ pub fn Statement(comptime opts: StatementOptions, comptime query: anytype) type | |||
| 2081 | if (bind_marker.typed) |typ| { | 2081 | if (bind_marker.typed) |typ| { |
| 2082 | const FieldTypeInfo = @typeInfo(struct_field.type); | 2082 | const FieldTypeInfo = @typeInfo(struct_field.type); |
| 2083 | switch (FieldTypeInfo) { | 2083 | switch (FieldTypeInfo) { |
| 2084 | .Struct, .Enum, .Union => comptime assertMarkerType( | 2084 | .@"struct", .@"enum", .@"union" => comptime assertMarkerType( |
| 2085 | if (@hasDecl(struct_field.type, "BaseType")) struct_field.type.BaseType else struct_field.type, | 2085 | if (@hasDecl(struct_field.type, "BaseType")) struct_field.type.BaseType else struct_field.type, |
| 2086 | typ, | 2086 | typ, |
| 2087 | ), | 2087 | ), |
| @@ -2667,10 +2667,10 @@ test "sqlite: read a single text value" { | |||
| 2667 | else => { | 2667 | else => { |
| 2668 | const type_info = @typeInfo(typ); | 2668 | const type_info = @typeInfo(typ); |
| 2669 | switch (type_info) { | 2669 | switch (type_info) { |
| 2670 | .Pointer => { | 2670 | .pointer => { |
| 2671 | try testing.expectEqualStrings("Vincent", name.?); | 2671 | try testing.expectEqualStrings("Vincent", name.?); |
| 2672 | }, | 2672 | }, |
| 2673 | .Array => |arr| if (arr.sentinel) |sentinel_ptr| { | 2673 | .array => |arr| if (arr.sentinel) |sentinel_ptr| { |
| 2674 | const sentinel = @as(*const arr.child, @ptrCast(sentinel_ptr)).*; | 2674 | const sentinel = @as(*const arr.child, @ptrCast(sentinel_ptr)).*; |
| 2675 | const res = mem.sliceTo(&name.?, sentinel); | 2675 | const res = mem.sliceTo(&name.?, sentinel); |
| 2676 | try testing.expectEqualStrings("Vincent", res); | 2676 | try testing.expectEqualStrings("Vincent", res); |