# HG changeset patch # User František Kučera # Date 1588888925 -7200 # Node ID 1b21c78d87066f9f65438a378b0ce42066a1988c # Parent 813b44590d070c25d3fd79eddfa00dbbd594a2cf SQLite: demo modul – rozšíření přidávající pár funkcí do SQL Vzniklo v rámci práce na článku: https://blog.frantovo.cz/c/383/Komplexita%3A%20%C5%99e%C5%A1en%C3%AD%20a%C2%A0prevence diff -r 813b44590d07 -r 1b21c78d8706 c++/sqlite-demo-modul/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c++/sqlite-demo-modul/Makefile Fri May 08 00:02:05 2020 +0200 @@ -0,0 +1,20 @@ +all: libdemo.so + +libdemo.so: demo.cpp + g++ -g -shared -fPIC demo.cpp -o libdemo.so + +clean: + rm -f libdemo.so + +run: libdemo.so + echo "\ + SELECT 'load_extension', load_extension('./libdemo.so'); \ + SELECT 'get_pid', get_pid(); \ + SELECT 'value_count', value_count(), value_count('a'), value_count('a', 'b'), value_count(1,2,3); \ + SELECT 'multiply', multiply(2, 4); \ + " | sqlite3 + +info: libdemo.so + nm libdemo.so + ldd libdemo.so + file libdemo.so diff -r 813b44590d07 -r 1b21c78d8706 c++/sqlite-demo-modul/demo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c++/sqlite-demo-modul/demo.cpp Fri May 08 00:02:05 2020 +0200 @@ -0,0 +1,50 @@ +#include +#include +#include + +/** + * This is just an example – use official documentation: https://www.sqlite.org/loadext.html + */ + +#define C_API extern "C" +#define SQL_FN(functionName) C_API void functionName (sqlite3_context* ctx, int valueCount, sqlite3_value** values) + +SQLITE_EXTENSION_INIT1 + +/** + * Returns number of values passed to the SQL function. + */ +SQL_FN(valueCount) { + sqlite3_result_int(ctx, valueCount); +} + +/** + * Returns current PID (process id). + */ +SQL_FN(getPID) { + sqlite3_result_int(ctx, getpid()); +} + +/** + * Returns multiplication of all arguments or zero, if there are no arguments. + */ +SQL_FN(multiply) { + sqlite3_int64 result = valueCount == 0 ? 0 : 1; + for (int i = 0; i < valueCount; i++) result *= sqlite3_value_int64(values[i]); + sqlite3_result_int64(ctx, result); +} + +/** + * Function name should match the library file name: libdemo.so → sqlite3_demo_init. + * Or we can specify different entry point when loading the module. + */ +C_API int sqlite3_demo_init(sqlite3* db, char** error, const sqlite3_api_routines* api) { + SQLITE_EXTENSION_INIT2(api); + + sqlite3_create_function(db, "value_count", -1, SQLITE_UTF8, nullptr, valueCount, nullptr, nullptr); + sqlite3_create_function(db, "get_pid", 0, SQLITE_UTF8, nullptr, getPID, nullptr, nullptr); + sqlite3_create_function(db, "multiply", -1, SQLITE_UTF8, nullptr, multiply, nullptr, nullptr); + // -1 = function accepts arbitrary number of arguments + + return SQLITE_OK; +}