diff options
author | Daniel Burrows <dburrows@debian.org> | 2009-07-30 08:16:01 -0700 |
---|---|---|
committer | Daniel Burrows <dburrows@debian.org> | 2009-07-30 08:16:01 -0700 |
commit | 9c3497575ee632fd9ed57c92924ca42706490591 (patch) | |
tree | 5756ca45e8e0fbc403cf8a30e74dc15f30bead68 | |
parent | 31658b7927c97228bd902dd3817743ed3f7c7195 (diff) | |
download | aptitude-9c3497575ee632fd9ed57c92924ca42706490591.tar.gz |
Wrap sqlite3_blob_read and sqlite3_blob_write.
-rw-r--r-- | src/generic/util/sqlite.cc | 25 | ||||
-rw-r--r-- | src/generic/util/sqlite.h | 30 | ||||
-rw-r--r-- | tests/test_sqlite.cc | 60 |
3 files changed, 115 insertions, 0 deletions
diff --git a/src/generic/util/sqlite.cc b/src/generic/util/sqlite.cc index e4cbff37..0d138ae2 100644 --- a/src/generic/util/sqlite.cc +++ b/src/generic/util/sqlite.cc @@ -413,5 +413,30 @@ namespace aptitude sqlite3_blob_close(handle); parent.active_blobs.erase(this); } + + int blob::size() + { + return sqlite3_blob_bytes(handle); + } + + void blob::read(int offset, void *out, int length) + { + const int result = sqlite3_blob_read(handle, out, length, offset); + if(result != SQLITE_OK) + { + std::string msg(parent.get_error()); + throw exception(msg, result); + } + } + + void blob::write(int offset, const void *out, int length) + { + const int result = sqlite3_blob_write(handle, out, length, offset); + if(result != SQLITE_OK) + { + std::string msg(parent.get_error()); + throw exception(msg, result); + } + } } } diff --git a/src/generic/util/sqlite.h b/src/generic/util/sqlite.h index 884385d8..abe640f6 100644 --- a/src/generic/util/sqlite.h +++ b/src/generic/util/sqlite.h @@ -490,6 +490,36 @@ namespace aptitude sqlite3_int64 row, bool readWrite = true); + /** \brief Retrieve the size of the BLOB in bytes. */ + int size(); + + /** \brief Read some data from the BLOB. + * + * \param offset The byte offset at which to start reading. + * \param out The memory location at which to begin storing + * the data that was read. + * \param length The number of bytes of data to read. + * + * If there are fewer than "length" bytes following "offset" in + * the BLOB, this operation throws an exception. If the BLOB's + * row has been modified, this operation throws an exception + * with the error code SQLITE_ABORT. + */ + void read(int offset, void *out, int length); + + /** \brief Write some data into the BLOB. + * + * \param offset The byte offset at which to start writing. + * \param in The data to write into the BLOB. + * \param length The number of bytes of data to write. + * + * If there are fewer than "length" bytes following "offset" in + * the BLOB, this operation throws an exception. If the BLOB's + * row has been modified, this operation throws an exception + * with the error code SQLITE_ABORT. + */ + void write(int offset, const void *in, int length); + ~blob(); }; } diff --git a/tests/test_sqlite.cc b/tests/test_sqlite.cc index 1ff034bf..2a7e174f 100644 --- a/tests/test_sqlite.cc +++ b/tests/test_sqlite.cc @@ -429,3 +429,63 @@ BOOST_FIXTURE_TEST_CASE(testOpenBlob, test_blob_fixture) 100), exception); } + +BOOST_FIXTURE_TEST_CASE(testBlobSize, test_blob_fixture) +{ + boost::shared_ptr<blob> b = blob::open(*tmpdb, + "main", + "test", + "C", + blob_rowid); + + BOOST_CHECK_EQUAL(b->size(), 2); +} + +BOOST_FIXTURE_TEST_CASE(testBlobRead, test_blob_fixture) +{ + boost::shared_ptr<blob> b = blob::open(*tmpdb, + "main", + "test", + "C", + blob_rowid); + + char contents[3]; + const char expected[] = { 0x54, 0x12 }; + b->read(0, contents, 2); + BOOST_CHECK_EQUAL_COLLECTIONS(contents, contents + 2, + expected, expected + 2); + b->read(0, contents, 2); + BOOST_CHECK_EQUAL_COLLECTIONS(contents, contents + 2, + expected, expected + 2); + + BOOST_CHECK_THROW(b->read(0, contents, 3), exception); +} + +BOOST_FIXTURE_TEST_CASE(testBlobWrite, test_blob_fixture) +{ + const char data[2] = { 0x54, 0x11 }; + { + boost::shared_ptr<blob> b = blob::open(*tmpdb, + "main", + "test", + "C", + blob_rowid); + + b->write(1, data + 1, 1); + BOOST_CHECK_THROW(b->write(1, data, 2), exception); + } + + boost::shared_ptr<statement> stmt = + statement::prepare(*tmpdb, "select C from test where rowid = ?"); + stmt->bind_int64(1, blob_rowid); + BOOST_REQUIRE(stmt->step()); + + int len = -1; + const void *val = stmt->get_blob(0, len); + BOOST_CHECK_EQUAL(len, sizeof(data)); + BOOST_CHECK_EQUAL_COLLECTIONS(data, data + sizeof(data), + reinterpret_cast<const char *>(val), + reinterpret_cast<const char *>(val) + len); + + BOOST_CHECK(!stmt->step()); +} |