sqlite/ext/misc/urifuncs.c
drh be22a85406 Fix the urifuncs.c extension (used for testing and debugging only) so that
the sqlite3_filename_database() SQL function and its siblings correctly handle
an invalid schema name passed in as the argument.

FossilOrigin-Name: 3d7434a9d85dae9135473d1c58c22ac01a282e654807aa10be9b39f127291594
2020-01-14 16:50:09 +00:00

210 lines
6.3 KiB
C

/*
** 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 <assert.h>
#include <string.h>
/*
** 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<sizeof(aFunc)/sizeof(aFunc[0]); i++){
rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg,
SQLITE_UTF8, 0,
aFunc[i].xFunc, 0, 0);
}
return rc;
}