diff options
Diffstat (limited to 'sqlite.zig')
| -rw-r--r-- | sqlite.zig | 70 |
1 files changed, 52 insertions, 18 deletions
| @@ -14,6 +14,23 @@ usingnamespace @import("error.zig"); | |||
| 14 | 14 | ||
| 15 | const logger = std.log.scoped(.sqlite); | 15 | const logger = std.log.scoped(.sqlite); |
| 16 | 16 | ||
| 17 | /// ZeroBlob is a blob with a fixed length containing only zeroes. | ||
| 18 | /// | ||
| 19 | /// A ZeroBlob is intended to serve as a placeholder; content can later be written with incremental i/o. | ||
| 20 | /// | ||
| 21 | /// Here is an example allowing you to write up to 1024 bytes to a blob with incremental i/o. | ||
| 22 | /// | ||
| 23 | /// try db.exec("INSERT INTO user VALUES(1, ?)", .{}, .{sqlite.ZeroBlob{ .length = 1024 }}); | ||
| 24 | /// const row_id = db.getLastInsertRowID(); | ||
| 25 | /// | ||
| 26 | /// var blob = try db.openBlob(.main, "user", "data", row_id, .{ .write = true }); | ||
| 27 | /// | ||
| 28 | /// var blob_writer = blob.writer(); | ||
| 29 | /// try blob_writer.writeAll("foobar"); | ||
| 30 | /// | ||
| 31 | /// try blob.close(); | ||
| 32 | /// | ||
| 33 | /// Search for "zeroblob" on https://sqlite.org/c3ref/blob_open.html for more details. | ||
| 17 | pub const ZeroBlob = struct { | 34 | pub const ZeroBlob = struct { |
| 18 | length: usize, | 35 | length: usize, |
| 19 | }; | 36 | }; |
| @@ -133,23 +150,6 @@ pub const Blob = struct { | |||
| 133 | } | 150 | } |
| 134 | 151 | ||
| 135 | /// open opens a blob for incremental i/o. | 152 | /// open opens a blob for incremental i/o. |
| 136 | /// | ||
| 137 | /// You can get a std.io.Writer to write data to the blob: | ||
| 138 | /// | ||
| 139 | /// var blob = try db.openBlob(.main, "mytable", "mycolumn", 1, .{ .write = true }); | ||
| 140 | /// var blob_writer = blob.writer(); | ||
| 141 | /// | ||
| 142 | /// try blob_writer.writeAll(my_data); | ||
| 143 | /// | ||
| 144 | /// Note that a blob is not extensible, if you want to change the blob size you must use an UPDATE statement. | ||
| 145 | /// | ||
| 146 | /// You can get a std.io.Reader to read the blob data: | ||
| 147 | /// | ||
| 148 | /// var blob = try db.openBlob(.main, "mytable", "mycolumn", 1, .{}); | ||
| 149 | /// var blob_reader = blob.reader(); | ||
| 150 | /// | ||
| 151 | /// const data = try blob_reader.readAlloc(allocator); | ||
| 152 | /// | ||
| 153 | fn open(db: *c.sqlite3, db_name: DatabaseName, table: [:0]const u8, column: [:0]const u8, row: i64, comptime flags: OpenFlags) !Blob { | 153 | fn open(db: *c.sqlite3, db_name: DatabaseName, table: [:0]const u8, column: [:0]const u8, row: i64, comptime flags: OpenFlags) !Blob { |
| 154 | comptime if (!flags.read and !flags.write) { | 154 | comptime if (!flags.read and !flags.write) { |
| 155 | @compileError("must open a blob for either read, write or both"); | 155 | @compileError("must open a blob for either read, write or both"); |
| @@ -291,12 +291,21 @@ pub const Db = struct { | |||
| 291 | db: *c.sqlite3, | 291 | db: *c.sqlite3, |
| 292 | 292 | ||
| 293 | /// Mode determines how the database will be opened. | 293 | /// Mode determines how the database will be opened. |
| 294 | /// | ||
| 295 | /// * File means opening the database at this path with sqlite3_open_v2. | ||
| 296 | /// * Memory means opening the database in memory. | ||
| 297 | /// This works by opening the :memory: path with sqlite3_open_v2 with the flag SQLITE_OPEN_MEMORY. | ||
| 294 | pub const Mode = union(enum) { | 298 | pub const Mode = union(enum) { |
| 295 | File: [:0]const u8, | 299 | File: [:0]const u8, |
| 296 | Memory, | 300 | Memory, |
| 297 | }; | 301 | }; |
| 298 | 302 | ||
| 299 | /// OpenFlags contains various flags used when opening a SQLite databse. | 303 | /// OpenFlags contains various flags used when opening a SQLite databse. |
| 304 | /// | ||
| 305 | /// These flags partially map to the flags defined in https://sqlite.org/c3ref/open.html | ||
| 306 | /// * write=false and create=false means SQLITE_OPEN_READONLY | ||
| 307 | /// * write=true and create=false means SQLITE_OPEN_READWRITE | ||
| 308 | /// * write=true and create=true means SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE | ||
| 300 | pub const OpenFlags = struct { | 309 | pub const OpenFlags = struct { |
| 301 | write: bool = false, | 310 | write: bool = false, |
| 302 | create: bool = false, | 311 | create: bool = false, |
| @@ -483,7 +492,32 @@ pub const Db = struct { | |||
| 483 | return @intCast(usize, c.sqlite3_changes(self.db)); | 492 | return @intCast(usize, c.sqlite3_changes(self.db)); |
| 484 | } | 493 | } |
| 485 | 494 | ||
| 486 | /// openBlob opens a blob. | 495 | /// openBlob opens a blob for incremental i/o. |
| 496 | /// | ||
| 497 | /// Incremental i/o enables writing and reading data using a std.io.Writer and std.io.Reader: | ||
| 498 | /// * the writer type wraps sqlite3_blob_write, see https://sqlite.org/c3ref/blob_write.html | ||
| 499 | /// * the reader type wraps sqlite3_blob_read, see https://sqlite.org/c3ref/blob_read.html | ||
| 500 | /// | ||
| 501 | /// Note that: | ||
| 502 | /// * the blob must exist before writing; you must use INSERT to create one first (either with data or using a placeholder with ZeroBlob). | ||
| 503 | /// * the blob is not extensible, if you want to change the blob size you must use an UPDATE statement. | ||
| 504 | /// | ||
| 505 | /// You can get a std.io.Writer to write data to the blob: | ||
| 506 | /// | ||
| 507 | /// var blob = try db.openBlob(.main, "mytable", "mycolumn", 1, .{ .write = true }); | ||
| 508 | /// var blob_writer = blob.writer(); | ||
| 509 | /// | ||
| 510 | /// try blob_writer.writeAll(my_data); | ||
| 511 | /// | ||
| 512 | /// You can get a std.io.Reader to read the blob data: | ||
| 513 | /// | ||
| 514 | /// var blob = try db.openBlob(.main, "mytable", "mycolumn", 1, .{}); | ||
| 515 | /// var blob_reader = blob.reader(); | ||
| 516 | /// | ||
| 517 | /// const data = try blob_reader.readAlloc(allocator); | ||
| 518 | /// | ||
| 519 | /// See https://sqlite.org/c3ref/blob_open.html for more details on incremental i/o. | ||
| 520 | /// | ||
| 487 | pub fn openBlob(self: *Self, db_name: Blob.DatabaseName, table: [:0]const u8, column: [:0]const u8, row: i64, comptime flags: Blob.OpenFlags) !Blob { | 521 | pub fn openBlob(self: *Self, db_name: Blob.DatabaseName, table: [:0]const u8, column: [:0]const u8, row: i64, comptime flags: Blob.OpenFlags) !Blob { |
| 488 | return Blob.open(self.db, db_name, table, column, row, flags); | 522 | return Blob.open(self.db, db_name, table, column, row, flags); |
| 489 | } | 523 | } |