Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/gilzoide/sqlite-vfs-cpp

Single header with classes for easily implementing SQLite VFS shims in C++
https://github.com/gilzoide/sqlite-vfs-cpp

sqlite sqlite-vfs sqlite3 template vfs virtual-class

Last synced: 4 days ago
JSON representation

Single header with classes for easily implementing SQLite VFS shims in C++

Awesome Lists containing this project

README

        

# SQLiteVfs.hpp
Single header with classes for easily implementing [SQLite](https://sqlite.org/) [VFS](https://www.sqlite.org/vfs.html) shims in C++11.

## Features
- Single header: copy [SQLiteVfs.hpp](SQLiteVfs.hpp) to your project, `#include ` and that's it
- Supports C++11 and above
- Subclass `sqlite3vfs::SQLiteVfsImpl<>` to override any [VFS methods](https://www.sqlite.org/c3ref/vfs.html)
+ Default implementations forward execution to the default VFS.
This makes it easy to implement VFS shims.
- Subclass `sqlite3vfs::SQLiteFileImpl` to override any [File methods](https://www.sqlite.org/c3ref/io_methods.html)
+ Default implementations forward execution to the File opened by `SQLiteVfsImpl::xOpen`.
This makes it easy to implement File shims.

## Usage example
This sample code shows how to create a SQLite extension DLL that registers a simple VFS shim + File shim that logs read/write operations:

```cpp
// 1. Include header
// If you are building an extension DLL, make sure to include
// and call SQLITE_EXTENSION_INIT1 first.
#include
SQLITE_EXTENSION_INIT1
#include

#include

using namespace sqlitevfs;
using namespace std;

// 2. Implement your own `SQLiteFileImpl` subclass.
// Override any IO methods necessary. Reference: https://www.sqlite.org/c3ref/io_methods.html
// Default implementation will forward execution to the `original_file` opened by `SQLiteVfsImpl::xOpen`.
// Default constructor will be called before `SQLiteVfsImpl::xOpen`.
// Destructor will be called right after `xClose`, or after a failed `SQLiteVfsImpl::xOpen`.
struct LogIOFileShim : public SQLiteFileImpl {
LogIOFileShim() {
cout << "> Constructing file!" << endl;
}
int xRead(void *p, int iAmt, sqlite3_int64 iOfst) override {
cout << "> READ " << iAmt << " bytes starting at " << iOfst << endl;
return SQLiteFileImpl::xRead(p, iAmt, iOfst);
}
int xWrite(const void *p, int iAmt, sqlite3_int64 iOfst) override {
cout << "> WRITE " << iAmt << " bytes starting at " << iOfst << endl;
return SQLiteFileImpl::xWrite(p, iAmt, iOfst);
}
int xClose() override {
cout << "> CLOSE" << endl;
return SQLiteFileImpl::xClose();
}
~LogIOFileShim() {
cout << "> Destroying file!" << endl;
}
};

// 3. Implement your own `SQLiteVfsImpl<>` subclass.
// Pass your SQLiteFileImpl subclass as template parameter.
// Override any methods necessary. Reference: https://www.sqlite.org/c3ref/vfs.html
// Default implementation will forward execution to the `original_vfs` passed in `SQLiteVfs` construtor.
// Notice that `xOpen` receives a `SQLiteFile *` instead of `sqlite3_file`.
// `file` is guaranteed to be fully constructed before this method is called.
struct LogIOVfsShim : public SQLiteVfsImpl {
int xOpen(sqlite3_filename zName, SQLiteFile *file, int flags, int *pOutFlags) override {
int result = SQLiteVfsImpl::xOpen(zName, file, flags, pOutFlags);
if (result == SQLITE_OK) {
cout << "> OPENED '" << zName << "'" << endl;
}
else {
cout << "> ERROR OPENING '" << zName << "': " << sqlite3_errstr(result) << endl;
}
return result;
}
};

// If implementing an extension DLL, export the function as SQLite expects
extern "C" int sqlite3_logiovfs_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) {
SQLITE_EXTENSION_INIT2(pApi);

// 4. Create a `SQLiteVfs<>`.
// Pass your `SQLiteVfsImpl<>` subclass as template parameter.
static SQLiteVfs logiovfs("logiovfs");

// 5. Register your newly created VFS.
// Optionally make it the default VFS.
int rc = logiovfs.register_vfs(false);
if (rc == SQLITE_OK) {
rc = SQLITE_OK_LOAD_PERMANENTLY;
}
return rc;
}

// 6. (optional) Unregister your VFS using `my_vfs.unregister_vfs()`
```

## Samples
- [logiovfs](samples/logiovfs.cpp): shows how to create a SQLite extension DLL that registers a simple VFS shim + File shim that logs read/write operations

Building and running samples:
```sh
# build
mkdir build
cd build
cmake ..
make

# run from build folder
samples/logiovfs-sample
```