diff options
Diffstat (limited to 'sqlite.zig')
| -rw-r--r-- | sqlite.zig | 33 |
1 files changed, 33 insertions, 0 deletions
| @@ -1355,6 +1355,37 @@ pub const DynamicStatement = struct { | |||
| 1355 | } | 1355 | } |
| 1356 | } | 1356 | } |
| 1357 | 1357 | ||
| 1358 | // bind iterates over the fields in `values` and binds them using `bindField`. | ||
| 1359 | // | ||
| 1360 | // Depending on the query and the type of `values` the binding behaviour differs in regards to the column used. | ||
| 1361 | // | ||
| 1362 | // If `values` is a tuple (and therefore doesn't have field names) then the field _index_ is used. | ||
| 1363 | // This means that if you have a query like this: | ||
| 1364 | // | ||
| 1365 | // SELECT id FROM user WHERE age = ? AND name = ? | ||
| 1366 | // | ||
| 1367 | // You must provide a tuple with the fields in the same order like this: | ||
| 1368 | // | ||
| 1369 | // var iter = try stmt.iterator(.{30, "Vincent"}); | ||
| 1370 | // | ||
| 1371 | // | ||
| 1372 | // If `values` is a struct (and therefore has field names) then we check sqlite to see if each field name might be a name bind marker. | ||
| 1373 | // This uses sqlite3_bind_parameter_index and supports bind markers prefixed with ":", "@" and "$". | ||
| 1374 | // For example if you have a query like this: | ||
| 1375 | // | ||
| 1376 | // SELECT id FROM user WHERE age = :age AND name = @name | ||
| 1377 | // | ||
| 1378 | // Then we can provide a struct with fields in any order, like this: | ||
| 1379 | // | ||
| 1380 | // var iter = try stmt.iterator(.{ .age = 30, .name = "Vincent" }); | ||
| 1381 | // | ||
| 1382 | // Or | ||
| 1383 | // | ||
| 1384 | // var iter = try stmt.iterator(.{ .name = "Vincent", .age = 30 }); | ||
| 1385 | // | ||
| 1386 | // Both will bind correctly. | ||
| 1387 | // | ||
| 1388 | // If however there are no name bind markers then the behaviour will revert to using the field index in the struct, and the fields order must be correct. | ||
| 1358 | fn bind(self: *Self, options: anytype, values: anytype) !void { | 1389 | fn bind(self: *Self, options: anytype, values: anytype) !void { |
| 1359 | const StructType = @TypeOf(values); | 1390 | const StructType = @TypeOf(values); |
| 1360 | const StructTypeInfo = @typeInfo(StructType).Struct; | 1391 | const StructTypeInfo = @typeInfo(StructType).Struct; |
| @@ -1372,6 +1403,8 @@ pub const DynamicStatement = struct { | |||
| 1372 | } | 1403 | } |
| 1373 | 1404 | ||
| 1374 | fn sqlite3BindParameterIndex(stmt: *c.sqlite3_stmt, comptime name: []const u8) c_int { | 1405 | fn sqlite3BindParameterIndex(stmt: *c.sqlite3_stmt, comptime name: []const u8) c_int { |
| 1406 | if (name.len == 0) return -1; | ||
| 1407 | |||
| 1375 | inline for (.{ ":", "@", "$" }) |prefix| { | 1408 | inline for (.{ ":", "@", "$" }) |prefix| { |
| 1376 | const id = prefix ++ name; | 1409 | const id = prefix ++ name; |
| 1377 | const i = c.sqlite3_bind_parameter_index(stmt, id); | 1410 | const i = c.sqlite3_bind_parameter_index(stmt, id); |