/* ** 2020-01-11 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This SQLite extension implements various SQL functions used to access ** the following SQLite C-language APIs: ** ** sqlite3_uri_parameter() ** sqlite3_uri_boolean() ** sqlite3_uri_int64() ** sqlite3_uri_key() ** sqlite3_filename_database() ** sqlite3_filename_journal() ** sqlite3_filename_wal() ** sqlite3_db_filename() ** ** These SQL functions are for testing and demonstration purposes only. ** ** */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #include #include /* ** SQL function: sqlite3_db_filename(SCHEMA) ** ** Return the filename corresponding to SCHEMA. */ static void func_db_filename( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSchema = (const char*)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); const char *zFile = sqlite3_db_filename(db, zSchema); sqlite3_result_text(context, zFile, -1, SQLITE_TRANSIENT); } /* ** SQL function: sqlite3_uri_parameter(SCHEMA,NAME) ** ** Return the value of the NAME query parameter to the database for SCHEMA */ static void func_uri_parameter( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSchema = (const char*)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); const char *zName = (const char*)sqlite3_value_text(argv[1]); const char *zFile = sqlite3_db_filename(db, zSchema); const char *zRes = sqlite3_uri_parameter(zFile, zName); sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); } /* ** SQL function: sqlite3_uri_boolean(SCHEMA,NAME,DEFAULT) ** ** Return the boolean value of the NAME query parameter to ** the database for SCHEMA */ static void func_uri_boolean( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSchema = (const char*)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); const char *zName = (const char*)sqlite3_value_text(argv[1]); const char *zFile = sqlite3_db_filename(db, zSchema); int iDflt = sqlite3_value_int(argv[2]); int iRes = sqlite3_uri_boolean(zFile, zName, iDflt); sqlite3_result_int(context, iRes); } /* ** SQL function: sqlite3_uri_key(SCHEMA,N) ** ** Return the name of the Nth query parameter */ static void func_uri_key( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSchema = (const char*)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); int N = sqlite3_value_int(argv[1]); const char *zFile = sqlite3_db_filename(db, zSchema); const char *zRes = sqlite3_uri_key(zFile, N); sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); } /* ** SQL function: sqlite3_uri_int64(SCHEMA,NAME,DEFAULT) ** ** Return the int64 value of the NAME query parameter to ** the database for SCHEMA */ static void func_uri_int64( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSchema = (const char*)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); const char *zName = (const char*)sqlite3_value_text(argv[1]); const char *zFile = sqlite3_db_filename(db, zSchema); sqlite3_int64 iDflt = sqlite3_value_int64(argv[2]); sqlite3_int64 iRes = sqlite3_uri_int64(zFile, zName, iDflt); sqlite3_result_int64(context, iRes); } /* ** SQL function: sqlite3_filename_database(SCHEMA) ** ** Return the database filename for SCHEMA */ static void func_filename_database( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSchema = (const char*)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); const char *zFile = sqlite3_db_filename(db, zSchema); const char *zRes = zFile ? sqlite3_filename_database(zFile) : 0; sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); } /* ** SQL function: sqlite3_filename_journal(SCHEMA) ** ** Return the rollback journal filename for SCHEMA */ static void func_filename_journal( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSchema = (const char*)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); const char *zFile = sqlite3_db_filename(db, zSchema); const char *zRes = zFile ? sqlite3_filename_journal(zFile) : 0; sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); } /* ** SQL function: sqlite3_filename_wal(SCHEMA) ** ** Return the WAL filename for SCHEMA */ static void func_filename_wal( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSchema = (const char*)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); const char *zFile = sqlite3_db_filename(db, zSchema); const char *zRes = zFile ? sqlite3_filename_wal(zFile) : 0; sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); } #ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_urifuncs_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ static const struct { const char *zFuncName; int nArg; void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } aFunc[] = { { "sqlite3_db_filename", 1, func_db_filename }, { "sqlite3_uri_parameter", 2, func_uri_parameter }, { "sqlite3_uri_boolean", 3, func_uri_boolean }, { "sqlite3_uri_int64", 3, func_uri_int64 }, { "sqlite3_uri_key", 2, func_uri_key }, { "sqlite3_filename_database", 1, func_filename_database }, { "sqlite3_filename_journal", 1, func_filename_journal }, { "sqlite3_filename_wal", 1, func_filename_wal }, }; int rc = SQLITE_OK; int i; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ for(i=0; rc==SQLITE_OK && i