diff options
| author | 2020-12-21 01:51:59 +0100 | |
|---|---|---|
| committer | 2020-12-21 01:51:59 +0100 | |
| commit | fe80b3ec7a95ea0bd73823fbfe0dfa2d478874f1 (patch) | |
| tree | d3b08ebaf66e300deb71e789628261de4a3f4a60 /sqlite.zig | |
| parent | make readBytes read Blob, Text as well as []const u8, []u8 (diff) | |
| download | zig-sqlite-fe80b3ec7a95ea0bd73823fbfe0dfa2d478874f1.tar.gz zig-sqlite-fe80b3ec7a95ea0bd73823fbfe0dfa2d478874f1.tar.xz zig-sqlite-fe80b3ec7a95ea0bd73823fbfe0dfa2d478874f1.zip | |
add comments
Diffstat (limited to 'sqlite.zig')
| -rw-r--r-- | sqlite.zig | 44 |
1 files changed, 42 insertions, 2 deletions
| @@ -237,7 +237,13 @@ pub fn Iterator(comptime Type: type) type { | |||
| 237 | } | 237 | } |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | fn readArray(self: *Self, comptime ArrayType: type, _i: usize) !ArrayType { | 240 | // readArray reads a sqlite BLOB or TEXT column into an array of u8. |
| 241 | // | ||
| 242 | // We also require the array to have a sentinel because otherwise we have no way | ||
| 243 | // of communicating the end of the data to the caller. | ||
| 244 | // | ||
| 245 | // If the array is too small for the data an error will be returned. | ||
| 246 | fn readArray(self: *Self, comptime ArrayType: type, _i: usize) error{ArrayTooSmall}!ArrayType { | ||
| 241 | const i = @intCast(c_int, _i); | 247 | const i = @intCast(c_int, _i); |
| 242 | const array_type_info = @typeInfo(ArrayType); | 248 | const array_type_info = @typeInfo(ArrayType); |
| 243 | 249 | ||
| @@ -268,16 +274,19 @@ pub fn Iterator(comptime Type: type) type { | |||
| 268 | return ret; | 274 | return ret; |
| 269 | } | 275 | } |
| 270 | 276 | ||
| 277 | // readInt reads a sqlite INTEGER column into an integer. | ||
| 271 | fn readInt(self: *Self, comptime IntType: type, i: usize, options: anytype) !IntType { | 278 | fn readInt(self: *Self, comptime IntType: type, i: usize, options: anytype) !IntType { |
| 272 | const n = c.sqlite3_column_int64(self.stmt, @intCast(c_int, i)); | 279 | const n = c.sqlite3_column_int64(self.stmt, @intCast(c_int, i)); |
| 273 | return @intCast(IntType, n); | 280 | return @intCast(IntType, n); |
| 274 | } | 281 | } |
| 275 | 282 | ||
| 283 | // readFloat reads a sqlite REAL column into a float. | ||
| 276 | fn readFloat(self: *Self, comptime FloatType: type, i: usize, options: anytype) !FloatType { | 284 | fn readFloat(self: *Self, comptime FloatType: type, i: usize, options: anytype) !FloatType { |
| 277 | const d = c.sqlite3_column_double(self.stmt, @intCast(c_int, i)); | 285 | const d = c.sqlite3_column_double(self.stmt, @intCast(c_int, i)); |
| 278 | return @floatCast(FloatType, d); | 286 | return @floatCast(FloatType, d); |
| 279 | } | 287 | } |
| 280 | 288 | ||
| 289 | // readFloat reads a sqlite INTEGER column into a bool (true is anything > 0, false is anything <= 0). | ||
| 281 | fn readBool(self: *Self, i: usize, options: anytype) !bool { | 290 | fn readBool(self: *Self, i: usize, options: anytype) !bool { |
| 282 | const d = c.sqlite3_column_int64(self.stmt, @intCast(c_int, i)); | 291 | const d = c.sqlite3_column_int64(self.stmt, @intCast(c_int, i)); |
| 283 | return d > 0; | 292 | return d > 0; |
| @@ -288,12 +297,22 @@ pub fn Iterator(comptime Type: type) type { | |||
| 288 | Text, | 297 | Text, |
| 289 | }; | 298 | }; |
| 290 | 299 | ||
| 300 | // readBytes reads a sqlite BLOB or TEXT column. | ||
| 301 | // | ||
| 302 | // The mode controls which sqlite function is used to retrieve the data: | ||
| 303 | // * .Blob uses sqlite3_column_blob | ||
| 304 | // * .Text uses sqlite3_column_text | ||
| 305 | // | ||
| 306 | // When using .Blob you can only read into either []const u8, []u8 or Blob. | ||
| 307 | // When using .Text you can only read into either []const u8, []u8 or Text. | ||
| 308 | // | ||
| 309 | // The options must contain an `allocator` field which will be used to create a copy of the data. | ||
| 291 | fn readBytes(self: *Self, comptime BytesType: type, _i: usize, comptime mode: ReadBytesMode, options: anytype) !BytesType { | 310 | fn readBytes(self: *Self, comptime BytesType: type, _i: usize, comptime mode: ReadBytesMode, options: anytype) !BytesType { |
| 292 | const i = @intCast(c_int, _i); | 311 | const i = @intCast(c_int, _i); |
| 293 | 312 | ||
| 294 | var ret: BytesType = switch (BytesType) { | 313 | var ret: BytesType = switch (BytesType) { |
| 295 | Text, Blob => .{ .data = "" }, | 314 | Text, Blob => .{ .data = "" }, |
| 296 | else => "", | 315 | else => "", // TODO(vincent): I think with a []u8 this will crash if the caller attempts to modify it... |
| 297 | }; | 316 | }; |
| 298 | 317 | ||
| 299 | switch (mode) { | 318 | switch (mode) { |
| @@ -334,6 +353,27 @@ pub fn Iterator(comptime Type: type) type { | |||
| 334 | } | 353 | } |
| 335 | } | 354 | } |
| 336 | 355 | ||
| 356 | // readStruct reads an entire sqlite row into a struct. | ||
| 357 | // | ||
| 358 | // Each field correspond to a column; its position in the struct determines the column used for it. | ||
| 359 | // For example, given the following query: | ||
| 360 | // | ||
| 361 | // SELECT id, name, age FROM user | ||
| 362 | // | ||
| 363 | // The struct must have the following fields: | ||
| 364 | // | ||
| 365 | // struct { | ||
| 366 | // id: usize, | ||
| 367 | // name: []const u8, | ||
| 368 | // age: u16, | ||
| 369 | // } | ||
| 370 | // | ||
| 371 | // The field `id` will be associated with the column `id` and so on. | ||
| 372 | // | ||
| 373 | // This function relies on the fact that there are the same number of fields than columns and | ||
| 374 | // that the order is correct. | ||
| 375 | // | ||
| 376 | // TODO(vincent): add comptime checks for the fields/columns. | ||
| 337 | fn readStruct(self: *Self, options: anytype) !Type { | 377 | fn readStruct(self: *Self, options: anytype) !Type { |
| 338 | var value: Type = undefined; | 378 | var value: Type = undefined; |
| 339 | 379 | ||