SQLite: demo modul – rozšíření přidávající pár funkcí do SQL
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 12 May 2020 21:30:46 +0200
changeset 05c6ff8cd880b
child 1 d7e35f20b1a5
SQLite: demo modul – rozšíření přidávající pár funkcí do SQL
.hgignore
Makefile
demo.cpp
     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 +}