Repository navigation
feat: Add Database#serialize and Database#deserialize methods - #685
Conversation
|
@Maaarcocr The test suite failure seems legit. Let me know if you need assistance getting unblocked! |
sorry for the delay, getting to this only now. the issue I have is that I can't currently replicate. I run the test with no issues on my machine. could it be an OS issue? or a sqlite version issue? |
|
@Maaarcocr It was a SQLite version issue. The Older SQLite has a worse problem, too: before 3.54.0, The other changes I pushed on top of yours:
|
Add support for sqlite3_serialize() and sqlite3_deserialize() which allow serializing an in-memory database to a binary string and restoring it later. These methods are useful for: - Creating snapshots of in-memory databases - Transferring database contents between connections - Backing up and restoring database state The methods are only available when SQLite is compiled without SQLITE_OMIT_DESERIALIZE (requires SQLite >= 3.23.0).
SQLite's docs advise padding the buffer in case a malformed image makes
SQLite read past its end. A comment explains why the padding is only
defensive here, and why it also makes `deserialize("")` work.
The `Database#deserialize` docs said a transaction made it raise `BusyException`. That holds only for SQLite 3.54.0 or later, and only for an open read or write transaction or a backup; older versions free memory that an unfinished statement still uses. Correct that, and document the WAL-mode trap, the detach from a file-backed database, and the risk of untrusted data.
`Database#serialize` raised `NoMemoryError: failed to allocate -1 bytes`
for an unknown database name, or for "temp" before any temporary table
existed. Raise `SQLite3::Exception` naming the database instead.
Also test that `deserialize("")` produces an empty database. It raised
`NoMemoryError` until "Pad the deserialize buffer with 20 zeroed bytes".
Before SQLite 3.54.0, `sqlite3_deserialize()` returned `SQLITE_OK` while a statement was unfinished, and the next step of that statement read freed memory. Check the loaded version before defining the method.
`PRId64` expects `long` on LP64 Linux, but `sqlite3_int64` is `long long`. Format with `%lld` and a cast instead.
Add support for sqlite3_serialize() and sqlite3_deserialize() which
allow serializing an in-memory database to a binary string and
restoring it later.
These methods are useful for:
The methods are only available when SQLite is compiled without
SQLITE_OMIT_DESERIALIZE (requires SQLite >= 3.23.0).