summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sqlite.zig86
1 files changed, 52 insertions, 34 deletions
diff --git a/sqlite.zig b/sqlite.zig
index 337ea90..4f25aa3 100644
--- a/sqlite.zig
+++ b/sqlite.zig
@@ -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 {