From 3f4da0ac6297a98b04cc4d7944c5ba8e1b2db1ab Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Sun, 31 Jan 2021 16:18:59 +0100 Subject: add Blob.reopen --- sqlite.zig | 70 +++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 17 deletions(-) (limited to 'sqlite.zig') diff --git a/sqlite.zig b/sqlite.zig index 82190ba..e1e3216 100644 --- a/sqlite.zig +++ b/sqlite.zig @@ -114,6 +114,24 @@ pub const Blob = struct { return data.len; } + /// Reset the offset used for reading and writing. + pub fn reset(self: *Self) void { + self.offset = 0; + } + + /// reopen moves this blob to another row of the same table. + /// + /// See https://sqlite.org/c3ref/blob_reopen.html. + pub fn reopen(self: *Self, row: i64) !void { + const result = c.sqlite3_blob_reopen(self.handle, row); + if (result != c.SQLITE_OK) { + return error.CannotReopenBlob; + } + + self.size = c.sqlite3_blob_bytes(self.handle); + self.offset = 0; + } + /// open opens a blob for incremental i/o. /// /// You can get a std.io.Writer to write data to the blob: @@ -1711,7 +1729,7 @@ test "sqlite: statement iterator" { } } -test "sqlite: blob open" { +test "sqlite: blob open, reopen" { var arena = std.heap.ArenaAllocator.init(testing.allocator); defer arena.deinit(); var allocator = &arena.allocator; @@ -1719,37 +1737,55 @@ test "sqlite: blob open" { var db = try getTestDb(); defer db.deinit(); - const blob_data = "\xDE\xAD\xBE\xEFabcdefghijklmnopqrstuvwxyz0123456789"; + const blob_data1 = "\xDE\xAD\xBE\xEFabcdefghijklmnopqrstuvwxyz0123456789"; + const blob_data2 = "\xCA\xFE\xBA\xBEfoobar"; - // Insert a new blob with a set length + // Insert two blobs with a set length try db.exec("CREATE TABLE test_blob(id integer primary key, data blob)", .{}); try db.exec("INSERT INTO test_blob(data) VALUES(?)", .{ - .data = ZeroBlob{ .length = blob_data.len * 2 }, + .data = ZeroBlob{ .length = blob_data1.len * 2 }, + }); + const rowid1 = db.getLastInsertRowID(); + + try db.exec("INSERT INTO test_blob(data) VALUES(?)", .{ + .data = ZeroBlob{ .length = blob_data2.len * 2 }, }); + const rowid2 = db.getLastInsertRowID(); - const rowid = db.getLastInsertRowID(); + // Open the blob in the first row + var blob = try db.openBlob(.main, "test_blob", "data", rowid1, .{ .write = true }); - // Open the blob for writing { - var blob = try db.openBlob(.main, "test_blob", "data", rowid, .{ .write = true }); + // Write the first blob data + var blob_writer = blob.writer(); + try blob_writer.writeAll(blob_data1); + try blob_writer.writeAll(blob_data1); - // Write the data + blob.reset(); - var blob_writer = blob.writer(); - try blob_writer.writeAll(blob_data); - try blob_writer.writeAll(blob_data); + var blob_reader = blob.reader(); + const data = try blob_reader.readAllAlloc(allocator, 8192); - try blob.close(); + testing.expectEqualSlices(u8, blob_data1 ** 2, data); } - // Now read the data and check the results - var blob = try db.openBlob(.main, "test_blob", "data", rowid, .{}); + // Reopen the blob in the second row + try blob.reopen(rowid2); - var blob_reader = blob.reader(); - const data = try blob_reader.readAllAlloc(allocator, 8192); + { + // Write the second blob data + var blob_writer = blob.writer(); + try blob_writer.writeAll(blob_data2); + try blob_writer.writeAll(blob_data2); + + blob.reset(); - testing.expectEqualSlices(u8, blob_data ** 2, data); + var blob_reader = blob.reader(); + const data = try blob_reader.readAllAlloc(allocator, 8192); + + testing.expectEqualSlices(u8, blob_data2 ** 2, data); + } try blob.close(); } -- cgit v1.2.3