diff options
| author | 2021-01-31 16:18:59 +0100 | |
|---|---|---|
| committer | 2021-01-31 16:18:59 +0100 | |
| commit | 3f4da0ac6297a98b04cc4d7944c5ba8e1b2db1ab (patch) | |
| tree | b6ee271ed1fc4a9edad638ebe2c20b8989d2469e /sqlite.zig | |
| parent | build: add the dbfile option (diff) | |
| download | zig-sqlite-3f4da0ac6297a98b04cc4d7944c5ba8e1b2db1ab.tar.gz zig-sqlite-3f4da0ac6297a98b04cc4d7944c5ba8e1b2db1ab.tar.xz zig-sqlite-3f4da0ac6297a98b04cc4d7944c5ba8e1b2db1ab.zip | |
add Blob.reopen
Diffstat (limited to 'sqlite.zig')
| -rw-r--r-- | sqlite.zig | 70 |
1 files changed, 53 insertions, 17 deletions
| @@ -114,6 +114,24 @@ pub const Blob = struct { | |||
| 114 | return data.len; | 114 | return data.len; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | /// Reset the offset used for reading and writing. | ||
| 118 | pub fn reset(self: *Self) void { | ||
| 119 | self.offset = 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | /// reopen moves this blob to another row of the same table. | ||
| 123 | /// | ||
| 124 | /// See https://sqlite.org/c3ref/blob_reopen.html. | ||
| 125 | pub fn reopen(self: *Self, row: i64) !void { | ||
| 126 | const result = c.sqlite3_blob_reopen(self.handle, row); | ||
| 127 | if (result != c.SQLITE_OK) { | ||
| 128 | return error.CannotReopenBlob; | ||
| 129 | } | ||
| 130 | |||
| 131 | self.size = c.sqlite3_blob_bytes(self.handle); | ||
| 132 | self.offset = 0; | ||
| 133 | } | ||
| 134 | |||
| 117 | /// open opens a blob for incremental i/o. | 135 | /// open opens a blob for incremental i/o. |
| 118 | /// | 136 | /// |
| 119 | /// You can get a std.io.Writer to write data to the blob: | 137 | /// You can get a std.io.Writer to write data to the blob: |
| @@ -1711,7 +1729,7 @@ test "sqlite: statement iterator" { | |||
| 1711 | } | 1729 | } |
| 1712 | } | 1730 | } |
| 1713 | 1731 | ||
| 1714 | test "sqlite: blob open" { | 1732 | test "sqlite: blob open, reopen" { |
| 1715 | var arena = std.heap.ArenaAllocator.init(testing.allocator); | 1733 | var arena = std.heap.ArenaAllocator.init(testing.allocator); |
| 1716 | defer arena.deinit(); | 1734 | defer arena.deinit(); |
| 1717 | var allocator = &arena.allocator; | 1735 | var allocator = &arena.allocator; |
| @@ -1719,37 +1737,55 @@ test "sqlite: blob open" { | |||
| 1719 | var db = try getTestDb(); | 1737 | var db = try getTestDb(); |
| 1720 | defer db.deinit(); | 1738 | defer db.deinit(); |
| 1721 | 1739 | ||
| 1722 | const blob_data = "\xDE\xAD\xBE\xEFabcdefghijklmnopqrstuvwxyz0123456789"; | 1740 | const blob_data1 = "\xDE\xAD\xBE\xEFabcdefghijklmnopqrstuvwxyz0123456789"; |
| 1741 | const blob_data2 = "\xCA\xFE\xBA\xBEfoobar"; | ||
| 1723 | 1742 | ||
| 1724 | // Insert a new blob with a set length | 1743 | // Insert two blobs with a set length |
| 1725 | try db.exec("CREATE TABLE test_blob(id integer primary key, data blob)", .{}); | 1744 | try db.exec("CREATE TABLE test_blob(id integer primary key, data blob)", .{}); |
| 1726 | 1745 | ||
| 1727 | try db.exec("INSERT INTO test_blob(data) VALUES(?)", .{ | 1746 | try db.exec("INSERT INTO test_blob(data) VALUES(?)", .{ |
| 1728 | .data = ZeroBlob{ .length = blob_data.len * 2 }, | 1747 | .data = ZeroBlob{ .length = blob_data1.len * 2 }, |
| 1748 | }); | ||
| 1749 | const rowid1 = db.getLastInsertRowID(); | ||
| 1750 | |||
| 1751 | try db.exec("INSERT INTO test_blob(data) VALUES(?)", .{ | ||
| 1752 | .data = ZeroBlob{ .length = blob_data2.len * 2 }, | ||
| 1729 | }); | 1753 | }); |
| 1754 | const rowid2 = db.getLastInsertRowID(); | ||
| 1730 | 1755 | ||
| 1731 | const rowid = db.getLastInsertRowID(); | 1756 | // Open the blob in the first row |
| 1757 | var blob = try db.openBlob(.main, "test_blob", "data", rowid1, .{ .write = true }); | ||
| 1732 | 1758 | ||
| 1733 | // Open the blob for writing | ||
| 1734 | { | 1759 | { |
| 1735 | var blob = try db.openBlob(.main, "test_blob", "data", rowid, .{ .write = true }); | 1760 | // Write the first blob data |
| 1761 | var blob_writer = blob.writer(); | ||
| 1762 | try blob_writer.writeAll(blob_data1); | ||
| 1763 | try blob_writer.writeAll(blob_data1); | ||
| 1736 | 1764 | ||
| 1737 | // Write the data | 1765 | blob.reset(); |
| 1738 | 1766 | ||
| 1739 | var blob_writer = blob.writer(); | 1767 | var blob_reader = blob.reader(); |
| 1740 | try blob_writer.writeAll(blob_data); | 1768 | const data = try blob_reader.readAllAlloc(allocator, 8192); |
| 1741 | try blob_writer.writeAll(blob_data); | ||
| 1742 | 1769 | ||
| 1743 | try blob.close(); | 1770 | testing.expectEqualSlices(u8, blob_data1 ** 2, data); |
| 1744 | } | 1771 | } |
| 1745 | 1772 | ||
| 1746 | // Now read the data and check the results | 1773 | // Reopen the blob in the second row |
| 1747 | var blob = try db.openBlob(.main, "test_blob", "data", rowid, .{}); | 1774 | try blob.reopen(rowid2); |
| 1748 | 1775 | ||
| 1749 | var blob_reader = blob.reader(); | 1776 | { |
| 1750 | const data = try blob_reader.readAllAlloc(allocator, 8192); | 1777 | // Write the second blob data |
| 1778 | var blob_writer = blob.writer(); | ||
| 1779 | try blob_writer.writeAll(blob_data2); | ||
| 1780 | try blob_writer.writeAll(blob_data2); | ||
| 1781 | |||
| 1782 | blob.reset(); | ||
| 1751 | 1783 | ||
| 1752 | testing.expectEqualSlices(u8, blob_data ** 2, data); | 1784 | var blob_reader = blob.reader(); |
| 1785 | const data = try blob_reader.readAllAlloc(allocator, 8192); | ||
| 1786 | |||
| 1787 | testing.expectEqualSlices(u8, blob_data2 ** 2, data); | ||
| 1788 | } | ||
| 1753 | 1789 | ||
| 1754 | try blob.close(); | 1790 | try blob.close(); |
| 1755 | } | 1791 | } |