diff options
| -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 { |