1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/.hgignore Tue May 12 21:30:46 2020 +0200
1.3 @@ -0,0 +1,2 @@
1.4 +syntax: glob
1.5 +*.so
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/Makefile Tue May 12 21:30:46 2020 +0200
2.3 @@ -0,0 +1,20 @@
2.4 +all: libdemo.so
2.5 +
2.6 +libdemo.so: demo.cpp
2.7 + g++ -g -shared -fPIC demo.cpp -o libdemo.so
2.8 +
2.9 +clean:
2.10 + rm -f libdemo.so
2.11 +
2.12 +run: libdemo.so
2.13 + echo "\
2.14 + SELECT 'load_extension', load_extension('./libdemo.so'); \
2.15 + SELECT 'get_pid', get_pid(); \
2.16 + SELECT 'value_count', value_count(), value_count('a'), value_count('a', 'b'), value_count(1,2,3); \
2.17 + SELECT 'multiply', multiply(2, 4); \
2.18 + " | sqlite3
2.19 +
2.20 +info: libdemo.so
2.21 + nm libdemo.so
2.22 + ldd libdemo.so
2.23 + file libdemo.so
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/demo.cpp Tue May 12 21:30:46 2020 +0200
3.3 @@ -0,0 +1,50 @@
3.4 +#include <cstdio>
3.5 +#include <sqlite3ext.h>
3.6 +#include <unistd.h>
3.7 +
3.8 +/**
3.9 + * This is just an example – use official documentation: https://www.sqlite.org/loadext.html
3.10 + */
3.11 +
3.12 +#define C_API extern "C"
3.13 +#define SQL_FN(functionName) void functionName (sqlite3_context* ctx, int valueCount, sqlite3_value** values)
3.14 +
3.15 +SQLITE_EXTENSION_INIT1
3.16 +
3.17 +/**
3.18 + * Returns number of values passed to the SQL function.
3.19 + */
3.20 +SQL_FN(valueCount) {
3.21 + sqlite3_result_int(ctx, valueCount);
3.22 +}
3.23 +
3.24 +/**
3.25 + * Returns current PID (process id).
3.26 + */
3.27 +SQL_FN(getPID) {
3.28 + sqlite3_result_int(ctx, getpid());
3.29 +}
3.30 +
3.31 +/**
3.32 + * Returns multiplication of all arguments or zero, if there are no arguments.
3.33 + */
3.34 +SQL_FN(multiply) {
3.35 + sqlite3_int64 result = valueCount == 0 ? 0 : 1;
3.36 + for (int i = 0; i < valueCount; i++) result *= sqlite3_value_int64(values[i]);
3.37 + sqlite3_result_int64(ctx, result);
3.38 +}
3.39 +
3.40 +/**
3.41 + * Function name should match the library file name: libdemo.so → sqlite3_demo_init.
3.42 + * Or we can specify different entry point when loading the module.
3.43 + */
3.44 +C_API int sqlite3_demo_init(sqlite3* db, char** error, const sqlite3_api_routines* api) {
3.45 + SQLITE_EXTENSION_INIT2(api);
3.46 +
3.47 + sqlite3_create_function(db, "value_count", -1, SQLITE_UTF8, nullptr, valueCount, nullptr, nullptr);
3.48 + sqlite3_create_function(db, "get_pid", 0, SQLITE_UTF8, nullptr, getPID, nullptr, nullptr);
3.49 + sqlite3_create_function(db, "multiply", -1, SQLITE_UTF8, nullptr, multiply, nullptr, nullptr);
3.50 + // -1 = function accepts arbitrary number of arguments
3.51 +
3.52 + return SQLITE_OK;
3.53 +}