-
Notifications
You must be signed in to change notification settings - Fork 516
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add example using SQLiteCpp within implementation of a loadable exten…
…sion
- Loading branch information
Showing
5 changed files
with
98 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Example building a SQLite3 loadable extension that uses SQLiteCpp internally | ||
cmake_minimum_required(VERSION 3.1) # for "CMAKE_CXX_STANDARD" version | ||
project(SQLiteCpp_ExampleExtension VERSION 1.0) | ||
|
||
set(CMAKE_CXX_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
|
||
# KEY OPTION HERE: builds SQLiteCpp for use within the implementation of a loadable extension | ||
set(SQLITECPP_IN_EXTENSION ON CACHE BOOL "" FORCE) | ||
|
||
set(SQLITECPP_RUN_CPPCHECK OFF CACHE BOOL "" FORCE) | ||
set(SQLITECPP_RUN_CPPLINT OFF CACHE BOOL "" FORCE) | ||
set(SQLITECPP_USE_STATIC_RUNTIME OFF CACHE BOOL "" FORCE) | ||
set(SQLITECPP_USE_STATIC_RUNTIME OFF CACHE BOOL "" FORCE) | ||
add_subdirectory(../.. SQLiteCpp) # out-of-source build requires explicit subdir name for compilation artifacts | ||
|
||
add_library(example SHARED src/example_extension.cpp) | ||
target_link_libraries(example SQLiteCpp) | ||
|
||
# Compile driver program that'll load the extension. It links sqlite3 statically, so our extension library | ||
# mustn't itself link sqlite3, either statically or dynamically (that's one thing accomplished by | ||
# SQLITECPP_IN_EXTENSION) | ||
add_executable(example_driver src/main.cpp) | ||
target_link_libraries(example_driver -static sqlite3 dl pthread) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
This example demonstrates how to use SQLiteCpp *within the implementation* of a | ||
[SQLite3 loadable extension](https://sqlite.org/loadext.html). Change into this directory and | ||
|
||
``` | ||
cmake -B build . | ||
cmake --build build | ||
build/example_driver $(pwd)/build/libexample.so | ||
``` | ||
|
||
*(replace .so with .dylib or .dll if appropriate)* | ||
|
||
This should print `it works 42`. Here the `example_driver` program links SQLite3 *statically*, so | ||
it's important to ensure that SQLiteCpp inside the extension will use that "copy" of SQLite3 rather | ||
than trying to dynamically link another one. See [CMakeLists.txt](CMakeLists.txt) for the key CMake | ||
option that ensures this, and [src/example_extension.cpp](src/example_extension.cpp) for some | ||
necessary boilerplate. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Example using SQLiteCpp within the implementation of a SQLite3 run-time loadable extension | ||
// SEE: https://sqlite.org/loadext.html | ||
#include <sqlite3ext.h> | ||
// When SQLiteCpp is built with option SQLITECPP_IN_EXTENSION=ON, its compiled objects will expect | ||
// to find an extern "C" symbol declared by the following macro in the extension implementation. | ||
extern "C" { | ||
SQLITE_EXTENSION_INIT1 | ||
} | ||
#include <SQLiteCpp/SQLiteCpp.h> | ||
#include <iostream> | ||
|
||
extern "C" int sqlite3_example_init(sqlite3 *rawDb, char **pzErrMsg, | ||
const sqlite3_api_routines *pApi) { | ||
SQLITE_EXTENSION_INIT2(pApi); | ||
|
||
try { | ||
// temporarily wrap rawDb as a SQLite::Database so we can use SQLiteCpp's conveniences | ||
SQLite::Database db(rawDb); | ||
SQLite::Statement stmt(db, "SELECT 'it works ' || ?"); | ||
stmt.bind(1, 42); | ||
if (stmt.executeStep()) { | ||
std::cout << stmt.getColumn(0).getString() << std::endl; | ||
} | ||
// In a real extension we'd now register custom functions, virtual tables, or VFS objects, | ||
// any of which might also want to use SQLiteCpp wrappers for the raw connection. | ||
return SQLITE_OK; | ||
} catch (SQLite::Exception& exn) { | ||
std::cerr << exn.getErrorStr() << std::endl; | ||
return exn.getErrorCode(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// driver program to load a SQLite3 extension | ||
|
||
#include <sqlite3.h> | ||
#include <iostream> | ||
|
||
int main(int argc, char **argv) { | ||
if (argc < 2) { | ||
std::cerr << "Usage: example_driver EXTENSION_ABSOLUTE_PATH" << std::endl; | ||
return -1; | ||
} | ||
sqlite3 *db; | ||
if (sqlite3_open_v2(":memory:", &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, nullptr) != SQLITE_OK) { | ||
std::cerr << "sqlite3_open_v2() failed" << std::endl; | ||
return -1; | ||
} | ||
char *zErrMsg = nullptr; | ||
if (sqlite3_load_extension(db, argv[1], nullptr, &zErrMsg) != SQLITE_OK) { | ||
std::cerr << "sqlite3_load_extension() failed"; | ||
if (zErrMsg) { | ||
std::cerr << ": " << zErrMsg << std::endl; | ||
} | ||
std::cerr << std::endl; | ||
return -1; | ||
} | ||
return 0; | ||
} |