diff options
| author | 2021-10-18 19:39:42 +0200 | |
|---|---|---|
| committer | 2021-10-18 21:26:06 +0200 | |
| commit | 7c22eb1507fd3dc3a33c7f4926b0e99e3762a291 (patch) | |
| tree | 82797bfca1ae28495e999474db6c8f757835cf4d | |
| parent | no need for comptimePrint here (diff) | |
| download | zig-sqlite-7c22eb1507fd3dc3a33c7f4926b0e99e3762a291.tar.gz zig-sqlite-7c22eb1507fd3dc3a33c7f4926b0e99e3762a291.tar.xz zig-sqlite-7c22eb1507fd3dc3a33c7f4926b0e99e3762a291.zip | |
make bindField clearer
Be less clever with comptime reflection.
This has the advantage of making the code a lot clearer, clearly
identifying which case are converting an sqlite int result to an error.
This also makes it easier to follow the error trace if there is an error
while binding a field.
| -rw-r--r-- | sqlite.zig | 86 |
1 files changed, 52 insertions, 34 deletions
| @@ -1130,17 +1130,9 @@ pub const DynamicStatement = struct { | |||
| 1130 | } | 1130 | } |
| 1131 | } | 1131 | } |
| 1132 | 1132 | ||
| 1133 | fn translateError(value: anytype) !void { | 1133 | fn convertResultToError(result: c_int) !void { |
| 1134 | if (@TypeOf(value) != void) { | 1134 | if (result != c.SQLITE_OK) { |
| 1135 | if (@typeInfo(@TypeOf(value)) == .ErrorUnion and @typeInfo(@TypeOf(value)).ErrorUnion.payload == void) { | 1135 | return errors.errorFromResultCode(result); |
| 1136 | return value; | ||
| 1137 | } else if (@TypeOf(value) == c_int and value == c.SQLITE_OK) { | ||
| 1138 | return; | ||
| 1139 | } else { | ||
| 1140 | return errors.errorFromResultCode(value); | ||
| 1141 | } | ||
| 1142 | } else { | ||
| 1143 | return; | ||
| 1144 | } | 1136 | } |
| 1145 | } | 1137 | } |
| 1146 | 1138 | ||
| @@ -1148,53 +1140,79 @@ pub const DynamicStatement = struct { | |||
| 1148 | const field_type_info = @typeInfo(FieldType); | 1140 | const field_type_info = @typeInfo(FieldType); |
| 1149 | const column = i + 1; | 1141 | const column = i + 1; |
| 1150 | 1142 | ||
| 1151 | const val = switch (FieldType) { | 1143 | switch (FieldType) { |
| 1152 | Text => c.sqlite3_bind_text(self.stmt, column, field.data.ptr, @intCast(c_int, field.data.len), null), | 1144 | Text => { |
| 1153 | Blob => c.sqlite3_bind_blob(self.stmt, column, field.data.ptr, @intCast(c_int, field.data.len), null), | 1145 | const result = c.sqlite3_bind_text(self.stmt, column, field.data.ptr, @intCast(c_int, field.data.len), null); |
| 1154 | ZeroBlob => c.sqlite3_bind_zeroblob64(self.stmt, column, field.length), | 1146 | return convertResultToError(result); |
| 1147 | }, | ||
| 1148 | Blob => { | ||
| 1149 | const result = c.sqlite3_bind_blob(self.stmt, column, field.data.ptr, @intCast(c_int, field.data.len), null); | ||
| 1150 | return convertResultToError(result); | ||
| 1151 | }, | ||
| 1152 | ZeroBlob => { | ||
| 1153 | const result = c.sqlite3_bind_zeroblob64(self.stmt, column, field.length); | ||
| 1154 | return convertResultToError(result); | ||
| 1155 | }, | ||
| 1155 | else => switch (field_type_info) { | 1156 | else => switch (field_type_info) { |
| 1156 | .Int, .ComptimeInt => c.sqlite3_bind_int64(self.stmt, column, @intCast(c_longlong, field)), | 1157 | .Int, .ComptimeInt => { |
| 1157 | .Float, .ComptimeFloat => c.sqlite3_bind_double(self.stmt, column, field), | 1158 | const result = c.sqlite3_bind_int64(self.stmt, column, @intCast(c_longlong, field)); |
| 1158 | .Bool => c.sqlite3_bind_int64(self.stmt, column, @boolToInt(field)), | 1159 | return convertResultToError(result); |
| 1160 | }, | ||
| 1161 | .Float, .ComptimeFloat => { | ||
| 1162 | const result = c.sqlite3_bind_double(self.stmt, column, field); | ||
| 1163 | return convertResultToError(result); | ||
| 1164 | }, | ||
| 1165 | .Bool => { | ||
| 1166 | const result = c.sqlite3_bind_int64(self.stmt, column, @boolToInt(field)); | ||
| 1167 | return convertResultToError(result); | ||
| 1168 | }, | ||
| 1159 | .Pointer => |ptr| switch (ptr.size) { | 1169 | .Pointer => |ptr| switch (ptr.size) { |
| 1160 | .One => self.bindField(ptr.child, options, field_name, i, field.*), | 1170 | .One => { |
| 1171 | try self.bindField(ptr.child, options, field_name, i, field.*); | ||
| 1172 | }, | ||
| 1161 | .Slice => switch (ptr.child) { | 1173 | .Slice => switch (ptr.child) { |
| 1162 | u8 => c.sqlite3_bind_text(self.stmt, column, field.ptr, @intCast(c_int, field.len), null), | 1174 | u8 => { |
| 1175 | const result = c.sqlite3_bind_text(self.stmt, column, field.ptr, @intCast(c_int, field.len), null); | ||
| 1176 | return convertResultToError(result); | ||
| 1177 | }, | ||
| 1163 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), | 1178 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), |
| 1164 | }, | 1179 | }, |
| 1165 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), | 1180 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), |
| 1166 | }, | 1181 | }, |
| 1167 | .Array => |arr| switch (arr.child) { | 1182 | .Array => |arr| switch (arr.child) { |
| 1168 | u8 => u8arr: { | 1183 | u8 => { |
| 1169 | const data: []const u8 = field[0..field.len]; | 1184 | const data: []const u8 = field[0..field.len]; |
| 1170 | 1185 | ||
| 1171 | break :u8arr c.sqlite3_bind_text(self.stmt, column, data.ptr, @intCast(c_int, data.len), null); | 1186 | const result = c.sqlite3_bind_text(self.stmt, column, data.ptr, @intCast(c_int, data.len), null); |
| 1187 | return convertResultToError(result); | ||
| 1172 | }, | 1188 | }, |
| 1173 | else => @compileError("cannot bind field " ++ field_name ++ " of type array of " ++ @typeName(arr.child)), | 1189 | else => @compileError("cannot bind field " ++ field_name ++ " of type array of " ++ @typeName(arr.child)), |
| 1174 | }, | 1190 | }, |
| 1175 | .Optional => |opt| if (field) |non_null_field| { | 1191 | .Optional => |opt| if (field) |non_null_field| { |
| 1176 | return try self.bindField(opt.child, options, field_name, i, non_null_field); | 1192 | try self.bindField(opt.child, options, field_name, i, non_null_field); |
| 1177 | } else optional_null: { | 1193 | } else { |
| 1178 | break :optional_null c.sqlite3_bind_null(self.stmt, column); | 1194 | const result = c.sqlite3_bind_null(self.stmt, column); |
| 1195 | return convertResultToError(result); | ||
| 1196 | }, | ||
| 1197 | .Null => { | ||
| 1198 | const result = c.sqlite3_bind_null(self.stmt, column); | ||
| 1199 | return convertResultToError(result); | ||
| 1179 | }, | 1200 | }, |
| 1180 | .Null => c.sqlite3_bind_null(self.stmt, column), | ||
| 1181 | .Enum => { | 1201 | .Enum => { |
| 1182 | if (comptime std.meta.trait.isZigString(FieldType.BaseType)) { | 1202 | if (comptime std.meta.trait.isZigString(FieldType.BaseType)) { |
| 1183 | return try self.bindField(FieldType.BaseType, options, field_name, i, @tagName(field)); | 1203 | try self.bindField(FieldType.BaseType, options, field_name, i, @tagName(field)); |
| 1184 | } else if (@typeInfo(FieldType.BaseType) == .Int) { | 1204 | } else if (@typeInfo(FieldType.BaseType) == .Int) { |
| 1185 | return try self.bindField(FieldType.BaseType, options, field_name, i, @enumToInt(field)); | 1205 | try self.bindField(FieldType.BaseType, options, field_name, i, @enumToInt(field)); |
| 1206 | } else { | ||
| 1207 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int to bind"); | ||
| 1186 | } | 1208 | } |
| 1187 | // Above if-else tree should have return to bypass @compileError below. | ||
| 1188 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int to bind"); | ||
| 1189 | }, | 1209 | }, |
| 1190 | .Struct => { | 1210 | .Struct => { |
| 1191 | return try self.bindField(FieldType.BaseType, options, field_name, i, try field.bindField(options.allocator)); | 1211 | try self.bindField(FieldType.BaseType, options, field_name, i, try field.bindField(options.allocator)); |
| 1192 | }, | 1212 | }, |
| 1193 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), | 1213 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), |
| 1194 | }, | 1214 | }, |
| 1195 | }; | 1215 | } |
| 1196 | |||
| 1197 | return translateError(val); | ||
| 1198 | } | 1216 | } |
| 1199 | 1217 | ||
| 1200 | fn bind(self: *Self, options: anytype, values: anytype) !void { | 1218 | fn bind(self: *Self, options: anytype, values: anytype) !void { |