1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Redesign for better legacy compatibility. Add the sqlite3_uri_key() interface.

FossilOrigin-Name: bcb43d11c4d0be36888c9e968ccdf85e7d7fccd72a29866f85c014e0562d4b93
This commit is contained in:
drh
2020-01-11 16:08:31 +00:00
parent 8875b9e7b5
commit 8080403e44
10 changed files with 381 additions and 184 deletions

207
ext/misc/urifuncs.c Normal file
View File

@@ -0,0 +1,207 @@
/*
** 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 = sqlite3_filename_database(zFile);
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 = sqlite3_filename_journal(zFile);
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 = sqlite3_filename_wal(zFile);
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;
}

View File

@@ -4936,33 +4936,6 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
return rc; return rc;
} }
/*
** A main database named zName has just been opened. The following
** function returns a pointer to a buffer owned by SQLite that contains
** the name of the *-wal file this db connection will use. SQLite
** happens to pass a pointer to this buffer when using xAccess()
** or xOpen() to operate on the *-wal file.
*/
static const char *rbuMainToWal(const char *zName, int flags){
int n = (int)strlen(zName);
const char *z = &zName[n];
if( flags & SQLITE_OPEN_URI ){
int odd = 0;
while( 1 ){
if( z[0]==0 ){
odd = 1 - odd;
if( odd && z[1]==0 ) break;
}
z++;
}
z += 2;
}else{
while( *z==0 ) z++;
}
z += (n + 8 + 2);
return z;
}
/* /*
** Open an rbu file handle. ** Open an rbu file handle.
*/ */
@@ -5011,7 +4984,7 @@ static int rbuVfsOpen(
** the name of the *-wal file this db connection will use. SQLite ** the name of the *-wal file this db connection will use. SQLite
** happens to pass a pointer to this buffer when using xAccess() ** happens to pass a pointer to this buffer when using xAccess()
** or xOpen() to operate on the *-wal file. */ ** or xOpen() to operate on the *-wal file. */
pFd->zWal = rbuMainToWal(zName, flags); pFd->zWal = sqlite3_filename_wal(zName);
} }
else if( flags & SQLITE_OPEN_WAL ){ else if( flags & SQLITE_OPEN_WAL ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
@@ -5026,7 +4999,7 @@ static int rbuVfsOpen(
char *zCopy; char *zCopy;
if( rbuIsVacuum(pDb->pRbu) ){ if( rbuIsVacuum(pDb->pRbu) ){
zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main"); zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI); zBase = sqlite3_filename_wal(zBase);
} }
nCopy = strlen(zBase); nCopy = strlen(zBase);
zCopy = sqlite3_malloc64(nCopy+2); zCopy = sqlite3_malloc64(nCopy+2);

View File

@@ -1,5 +1,5 @@
C Rearchitect\sthe\sway\sin\swhich\sfilenames\sare\sstored\sin\sthe\sPager\sobject\sso\sthat\nthe\ssqlite3_uri_parameter()\sinterface\swill\swork\sfrom\sjournal\sand\sWAL\sfilenames\ntoo.\s\sThis\scheck-in\simplements\sthe\scentral\sidea,\sand\scompile\sand\sruns\ssomewhat,\nbut\scrashes\son\san\sextended\stest. C Redesign\sfor\sbetter\slegacy\scompatibility.\s\sAdd\sthe\ssqlite3_uri_key()\sinterface.
D 2020-01-10T18:05:55.320 D 2020-01-11T16:08:31.366
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -321,6 +321,7 @@ F ext/misc/stmt.c 8a8dc4675042e4551e4afe99b8d0cc7a4a2fc1a8dacc0a9ce1b1bbff145da9
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4 F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b
F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9 F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9
F ext/misc/urifuncs.c a0b02a607b4170552deeff26812bb2f09eed1cc72d1056a4296ae6be0c19d100
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be0d35 F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be0d35
F ext/misc/vfsstat.c 77b5b4235c9f7f11eddf82487c0a422944ac2f132dafd5af3be7a68a057b1cdb F ext/misc/vfsstat.c 77b5b4235c9f7f11eddf82487c0a422944ac2f132dafd5af3be7a68a057b1cdb
@@ -369,7 +370,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697
F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b
F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc
F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10 F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10
F ext/rbu/sqlite3rbu.c 4e9a59aa80c03350a0ca5faa454dec894906537fbd98b3231604cc33baf174c8 F ext/rbu/sqlite3rbu.c 77a47f3231f5f363b2c584dba3e310a7efdaf073ad8c18728ab846b38de2879c
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -493,8 +494,8 @@ F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 5ba8fd376f539240939ae76b5bc9fa7ad9a0d86e9914ecd11eb7002204138c11 F src/insert.c 5ba8fd376f539240939ae76b5bc9fa7ad9a0d86e9914ecd11eb7002204138c11
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da F src/loadext.c 8cd803f1747c03a50b32fe87ebfb5851998d0cdafefe02737daa95e0616b42bb
F src/main.c abc034557685db2bead003e7d6b2bd74bf1a44c4d3bfe9ddcf35dc90524a8c21 F src/main.c 347687f4d843cb1660ec4bafe17fd3a9444d1208900308fddf6b6a418f091171
F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -517,8 +518,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c ad7640c04eed946052a3b12856362a773d0a717696707313037186df0e2b59f2 F src/os_unix.c ad7640c04eed946052a3b12856362a773d0a717696707313037186df0e2b59f2
F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 14ae8110bcb65a703d91131586848fe256c1a3cbbbc3eb1791090dbf925aa742 F src/pager.c 52a2923ebd6ca0e2ce917b5860ffe893a344481b5fa4c2a2568ad156168bc558
F src/pager.h e541ff7e1931e6e2165c38c7ff38cd1af8df0e20472ee8596479fd53c6aa149d F src/pager.h 71fe1d5016ec54d0cc5d344cd474e563450b438c59f535e8c1ec8a13b1373f14
F src/parse.y c8d2de64db469fd56e0fa24da46cd8ec8523eb98626567d2708df371b47fdc3f F src/parse.y c8d2de64db469fd56e0fa24da46cd8ec8523eb98626567d2708df371b47fdc3f
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
@@ -532,9 +533,9 @@ F src/resolve.c 1139e3157c710c6e6f04fe726f4e0d8bdb1ae89a276d3b0ca4975af163141c9c
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c 924b61cef57033a8ca1ed3dcffd02445a7dd0c837cc849b2e4117251cac831f5 F src/select.c 924b61cef57033a8ca1ed3dcffd02445a7dd0c837cc849b2e4117251cac831f5
F src/shell.c.in 43d3cfbee97d78ca5782dc53e4c1e22d3cc15c91beff20889dc60551f47eab9f F src/shell.c.in 43d3cfbee97d78ca5782dc53e4c1e22d3cc15c91beff20889dc60551f47eab9f
F src/sqlite.h.in 4022f00351aec1ad99b9dcadc4fbe70a1db0e306e84fee509daf97a82ef044a4 F src/sqlite.h.in c4713ccfa76dda5a96176d315ef5861d47f8d4815cc192d893b282a7f35669e9
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2 F src/sqlite3ext.h b0f776a0d042b23b6bcbb6b0943e8a3768c7f0b438a275e7168f0204e223a4db
F src/sqliteInt.h 7a29ba700a51eeb925731749a570cf3859f6a58ed94797ecf47508875b0ba279 F src/sqliteInt.h 7a29ba700a51eeb925731749a570cf3859f6a58ed94797ecf47508875b0ba279
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
@@ -1856,10 +1857,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 0a500da6aa659a8e73206e6d22ddbf2da5e4f1d1d551eeb66433163a3e13109d P 2ae77bd2335708343bce4541b4d2cf16edfe3fd5bc2dfb93757238c926aa960b
R dd17ff42793e7be350eec0c77a1551ba R 3c2b1115f362d773ce1134af1c5678e6
T *branch * enhanced-uri
T *sym-enhanced-uri *
T -sym-trunk *
U drh U drh
Z a098e9553bba752fd93040dc261a9c76 Z d49a59ecf45703e7c01f38027d23c9e9

View File

@@ -1 +1 @@
2ae77bd2335708343bce4541b4d2cf16edfe3fd5bc2dfb93757238c926aa960b bcb43d11c4d0be36888c9e968ccdf85e7d7fccd72a29866f85c014e0562d4b93

View File

@@ -470,6 +470,10 @@ static const sqlite3_api_routines sqlite3Apis = {
#endif #endif
/* Version 3.31.0 and later */ /* Version 3.31.0 and later */
sqlite3_hard_heap_limit64, sqlite3_hard_heap_limit64,
sqlite3_uri_key,
sqlite3_filename_database,
sqlite3_filename_journal,
sqlite3_filename_wal,
}; };
/* /*

View File

@@ -4241,25 +4241,6 @@ int sqlite3_test_control(int op, ...){
return rc; return rc;
} }
#ifdef SQLITE_DEBUG
/*
** This routine appears inside assert() statements only.
**
** Return the number of URI parameters that follow the filename.
*/
int sqlite3UriCount(const char *z){
int n = 0;
if( z==0 ) return 0;
z += strlen(z)+1;
while( z[0] ){
z += strlen(z)+1;
z += strlen(z)+1;
n++;
}
return n;
}
#endif /* SQLITE_DEBUG */
/* /*
** This is a utility routine, useful to VFS implementations, that checks ** This is a utility routine, useful to VFS implementations, that checks
** to see if a database file was a URI that contained a specific query ** to see if a database file was a URI that contained a specific query
@@ -4272,21 +4253,30 @@ int sqlite3UriCount(const char *z){
** returns a NULL pointer. ** returns a NULL pointer.
*/ */
const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
const Pager *pPager;
const char *z;
if( zFilename==0 || zParam==0 ) return 0; if( zFilename==0 || zParam==0 ) return 0;
pPager = sqlite3PagerFromFilename(zFilename); zFilename += sqlite3Strlen30(zFilename) + 1;
assert( pPager!=0 ); while( zFilename[0] ){
z = sqlite3PagerQueryParameters(pPager); int x = strcmp(zFilename, zParam);
while( z[0] ){ zFilename += sqlite3Strlen30(zFilename) + 1;
int x = strcmp(z, zParam); if( x==0 ) return zFilename;
z += sqlite3Strlen30(z) + 1; zFilename += sqlite3Strlen30(zFilename) + 1;
if( x==0 ) return z;
z += sqlite3Strlen30(z) + 1;
} }
return 0; return 0;
} }
/*
** Return a pointer to the name of Nth query parameter of the filename.
*/
const char *sqlite3_uri_key(const char *zFilename, int N){
if( zFilename==0 || N<0 ) return 0;
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] && (N--)>0 ){
zFilename += sqlite3Strlen30(zFilename) + 1;
zFilename += sqlite3Strlen30(zFilename) + 1;
}
return zFilename[0] ? zFilename : 0;
}
/* /*
** Return a boolean value for a query parameter. ** Return a boolean value for a query parameter.
*/ */
@@ -4312,6 +4302,25 @@ sqlite3_int64 sqlite3_uri_int64(
return bDflt; return bDflt;
} }
/*
** The Pager stores the Journal filename, WAL filename, and Database filename
** consecutively in memory, in that order, with prefixes \000\001\000,
** \002\000, and \003\000, in that order. Thus the three names look like query
** parameters if you start at the first prefix.
**
** This routine backs up a filename to the start of the first prefix.
**
** This only works if the filenamed passed in was obtained from the Pager.
*/
static const char *startOfNameList(const char *zName){
while( zName[0]!='\001' || zName[1]!=0 ){
zName -= 3;
while( zName[0]!='\000' ){ zName--; }
zName++;
}
return zName-1;
}
/* /*
** Translate a filename that was handed to a VFS routine into the corresponding ** Translate a filename that was handed to a VFS routine into the corresponding
** database, journal, or WAL file. ** database, journal, or WAL file.
@@ -4323,19 +4332,13 @@ sqlite3_int64 sqlite3_uri_int64(
** corruption. ** corruption.
*/ */
const char *sqlite3_filename_database(const char *zFilename){ const char *sqlite3_filename_database(const char *zFilename){
const Pager *pPager = sqlite3PagerFromFilename(zFilename); return sqlite3_uri_parameter(zFilename - 3, "\003");
assert( pPager!=0 );
return sqlite3PagerFilename(pPager, 0);
} }
const char *sqlite3_filename_journal(const char *zFilename){ const char *sqlite3_filename_journal(const char *zFilename){
const Pager *pPager = sqlite3PagerFromFilename(zFilename); return sqlite3_uri_parameter(startOfNameList(zFilename), "\001");
assert( pPager!=0 );
return sqlite3PagerJournalFilename(pPager);
} }
const char *sqlite3_filename_wal(const char *zFilename){ const char *sqlite3_filename_wal(const char *zFilename){
const Pager *pPager = sqlite3PagerFromFilename(zFilename); return sqlite3_uri_parameter(startOfNameList(zFilename), "\002");
assert( pPager!=0 );
return sqlite3PagerWalFilename(pPager);
} }
/* /*

View File

@@ -696,7 +696,6 @@ struct Pager {
Pgno mxPgno; /* Maximum allowed size of the database */ Pgno mxPgno; /* Maximum allowed size of the database */
i64 journalSizeLimit; /* Size limit for persistent journal files */ i64 journalSizeLimit; /* Size limit for persistent journal files */
char *zFilename; /* Name of the database file */ char *zFilename; /* Name of the database file */
char *zQueryParam; /* URI query parameters on the filename */
char *zJournal; /* Name of the journal file */ char *zJournal; /* Name of the journal file */
int (*xBusyHandler)(void*); /* Function to call when busy */ int (*xBusyHandler)(void*); /* Function to call when busy */
void *pBusyHandlerArg; /* Context argument for xBusyHandler */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */
@@ -4839,30 +4838,30 @@ int sqlite3PagerOpen(
** Database file handle (pVfs->szOsFile bytes) ** Database file handle (pVfs->szOsFile bytes)
** Sub-journal file handle (journalFileSize bytes) ** Sub-journal file handle (journalFileSize bytes)
** Main journal file handle (journalFileSize bytes) ** Main journal file handle (journalFileSize bytes)
** Pointer back to self (sizeof(*Pager) bytes) ** \0\1\0 journal prefix (3 bytes)
** Journal filename (nPathname+8+1 bytes)
** \2\0 WAL prefix (2 bytes)
** WAL filename (nPathname+4+1 bytes)
** \3\0 database prefix (2 bytes)
** Database file name (nPathname+1 bytes) ** Database file name (nPathname+1 bytes)
** URI query parameters (nUriByte bytes) ** URI query parameters (nUriByte bytes)
** padding for 8-byte alignment ** \0\0 terminator (2 bytes)
** Pointer back to self (sizeof(*Pager) bytes)
** WAL filename (nPathname+4+1 bytes)
** padding for 8-byte alignment
** Pointer back to self (sizeof(*Pager) bytes)
** Journal file name (nPathname+8+1 bytes)
*/ */
pPtr = (u8 *)sqlite3MallocZero( pPtr = (u8 *)sqlite3MallocZero(
ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(sizeof(*pPager)) + /* Pager structure */
ROUND8(pcacheSize) + /* PCache object */ ROUND8(pcacheSize) + /* PCache object */
ROUND8(pVfs->szOsFile) + /* The main db file */ ROUND8(pVfs->szOsFile) + /* The main db file */
journalFileSize * 2 + /* The two journal files */ journalFileSize * 2 + /* The two journal files */
sizeof(Pager*) + /* Self-pointer for database */ 3 + /* Journal prefix */
ROUND8(nPathname + 1 + nUriByte) + /* database filename + query params */ nPathname + 8 + 1 + /* Journal filename */
sizeof(Pager*) + /* Self-pointer for journal */
ROUND8(nPathname + 8 + 2) + /* zJournal */
#ifndef SQLITE_OMIT_WAL #ifndef SQLITE_OMIT_WAL
sizeof(Pager*) + /* Self-pointer for zWal */ 2 + /* WAL prefix */
ROUND8(nPathname + 4 + 2) + /* zWal */ nPathname + 4 + 1 + /* WAL filename */
#endif #endif
0 2 + /* Database prefix */
nPathname + 1 + /* database filename */
nUriByte + /* query parameters */
2 /* Terminator */
); );
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){ if( !pPtr ){
@@ -4876,33 +4875,47 @@ int sqlite3PagerOpen(
pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
/* Fill in the Pager.zFilename and pPager.zQueryParam fields */
assert( EIGHT_BYTE_ALIGNMENT(pPtr) ); /* Fill in Pager.zJournal */
memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); pPtr[1] = '\001'; pPtr += 3;
pPager->zFilename = (char*)pPtr; if( nPathname>0 ){
if( nPathname==0 ) zPathname = ""; pPager->zJournal = (char*)pPtr;
memcpy(pPtr, zPathname, nPathname); memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
pPager->zQueryParam = pPager->zFilename + nPathname + 1; memcpy(pPtr, "-journal",8); pPtr += 8 + 1;
if( zUri ) memcpy(pPager->zQueryParam, zUri, nUriByte); #ifdef SQLITE_ENABLE_8_3_NAMES
assert( nUriByte>=1 ); sqlite3FileSuffix3(zFilename,pPager->zJournal);
assert( nUriByte >= nUri*3 + 1 ); pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1);
pPtr += ROUND8(nPathname + 1 + nUriByte); #endif
}else{
pPager->zJournal = 0;
pPtr++;
}
#ifndef SQLITE_OMIT_WAL #ifndef SQLITE_OMIT_WAL
/* Fill in Pager.zWal */ /* Fill in Pager.zWal */
assert( EIGHT_BYTE_ALIGNMENT(pPtr) ); pPtr[0] = '\002'; pPtr[1] = 0; pPtr += 2;
memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); if( nPathname>0 ){
pPager->zWal = (char*)pPtr; pPager->zWal = (char*)pPtr;
memcpy(pPtr, zPathname, nPathname); memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
memcpy(pPtr+nPathname, "-wal", 4); pPtr += ROUND8(nPathname + 4 + 2); memcpy(pPtr, "-wal", 4); pPtr += 4 + 1;
#ifdef SQLITE_ENABLE_8_3_NAMES
sqlite3FileSuffix3(zFilename, pPager->zWal);
pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1);
#endif
}else{
pPager->zWal = 0;
pPtr++;
}
#endif #endif
/* Fill in Pager.zJournal */ /* Fill in the Pager.zFilename and pPager.zQueryParam fields */
assert( EIGHT_BYTE_ALIGNMENT(pPtr) ); pPtr[0] = '\003'; pPtr[1] = 0; pPtr += 2;
memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); pPager->zFilename = (char*)pPtr;
pPager->zJournal = (char*)pPtr; memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1;
memcpy(pPtr, zPathname, nPathname); if( zUri ){
memcpy(pPtr+nPathname, "-journal",8); /*pPtr += ROUND8(nPathname + 8 + 2);*/ memcpy(pPtr, zUri, nUriByte); /* pPtr += nUriByte; // not needed */
}
/* Double-zero terminator implied by the sqlite3MallocZero */
if( nPathname ) sqlite3DbFree(0, zPathname); if( nPathname ) sqlite3DbFree(0, zPathname);
pPager->pVfs = pVfs; pPager->pVfs = pVfs;
@@ -7018,50 +7031,13 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
** behavior. But when the Btree needs to know the filename for matching to ** behavior. But when the Btree needs to know the filename for matching to
** shared cache, it uses nullIfMemDb==0 so that in-memory databases can ** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
** participate in shared-cache. ** participate in shared-cache.
**
** The return value to this routine is always safe to use with
** sqlite3_uri_parameter() and sqlite3_filename_database() and friends.
*/ */
const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){
return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename; static const char zFake[] = { 0x01, 0x00, 0x00, 0x00 };
} return (nullIfMemDb && pPager->memDb) ? &zFake[2] : pPager->zFilename;
/*
** Return the name of the Journal file or WAL file of the given pager.
*/
const char *sqlite3PagerJournalFilename(const Pager *pPager){
assert( pPager!=0 );
return pPager->zJournal;
}
#ifndef SQLITE_OMIT_WAL
const char *sqlite3PagerWalFilename(const Pager *pPager){
assert( pPager!=0 );
return pPager->zWal;
}
#endif /* SQLITE_OMIT_WAL */
/* Return a pointer to the URI query parameters associated with the
** pager.
**
** The query parameters are a sequence of strings pairs. The first
** string of each pair is the key and the second string is the value.
** All strings are terminated by a single 0x00 byte. The list is
** terminated by the first empty-string key.
*/
const char *sqlite3PagerQueryParameters(const Pager *pPager){
assert( pPager!=0 );
return pPager->zQueryParam;
}
/* If zFilename is a filename passed to the xOpen method of the VFS -
** either the main database file, the WAL file, or the journal file -
** then this routine returns a pointer to the Pager object associated
** with that file.
*/
const Pager *sqlite3PagerFromFilename(const char *zFilename){
const Pager **pp = (const Pager**)zFilename;
pp--;
assert( (*pp)->zFilename==zFilename
|| (*pp)->zJournal==zFilename
|| (*pp)->zWal==zFilename );
return *pp;
} }
/* /*

View File

@@ -204,10 +204,6 @@ u32 sqlite3PagerDataVersion(Pager*);
#endif #endif
int sqlite3PagerMemUsed(Pager*); int sqlite3PagerMemUsed(Pager*);
const char *sqlite3PagerFilename(const Pager*, int); const char *sqlite3PagerFilename(const Pager*, int);
const char *sqlite3PagerWalFilename(const Pager*);
const char *sqlite3PagerJournalFilename(const Pager*);
const char *sqlite3PagerQueryParameters(const Pager*);
const Pager *sqlite3PagerFromFilename(const char*);
sqlite3_vfs *sqlite3PagerVfs(Pager*); sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*); sqlite3_file *sqlite3PagerFile(Pager*);
sqlite3_file *sqlite3PagerJrnlFile(Pager*); sqlite3_file *sqlite3PagerJrnlFile(Pager*);

View File

@@ -2794,7 +2794,7 @@ char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** **
** The SQLite core uses these three routines for all of its own ** The SQLite core uses these three routines for all of its own
** internal memory allocation needs. "Core" in the previous sentence ** internal memory allocation needs. "Core" in the previous sentence
** does not include operating-system specific VFS implementation. The ** does not include operating-system specific [VFS] implementation. The
** Windows VFS uses native malloc() and free() for some operations. ** Windows VFS uses native malloc() and free() for some operations.
** **
** ^The sqlite3_malloc() routine returns a pointer to a block ** ^The sqlite3_malloc() routine returns a pointer to a block
@@ -3494,14 +3494,13 @@ int sqlite3_open_v2(
/* /*
** CAPI3REF: Obtain Values For URI Parameters ** CAPI3REF: Obtain Values For URI Parameters
** **
** These are utility routines, useful to VFS implementations, that check ** These are utility routines, useful to [VFS|custom VFS implementations],
** to see if a database file was a URI that contained a specific query ** that check if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of that query parameter. ** parameter, and if so obtains the value of that query parameter.
** **
** If F is the database filename pointer passed into the xOpen() method of ** If F is the database filename pointer passed into the xOpen() method of
** a VFS implementation when the flags parameter to xOpen() has one or ** a VFS implementation or it is the return value of [sqlite3_db_filename()]
** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and ** and if P is the name of the query parameter, then
** P is the name of the query parameter, then
** sqlite3_uri_parameter(F,P) returns the value of the P ** sqlite3_uri_parameter(F,P) returns the value of the P
** parameter if it exists or a NULL pointer if P does not appear as a ** parameter if it exists or a NULL pointer if P does not appear as a
** query parameter on F. If P is a query parameter of F and it ** query parameter on F. If P is a query parameter of F and it
@@ -3523,40 +3522,60 @@ int sqlite3_open_v2(
** 64-bit signed integer and returns that integer, or D if P does not ** 64-bit signed integer and returns that integer, or D if P does not
** exist. If the value of P is something other than an integer, then ** exist. If the value of P is something other than an integer, then
** zero is returned. ** zero is returned.
**
** The sqlite3_uri_key(F,N) returns a pointer to the name (not
** the value) of the N-th query parameter for filename F, or a NULL
** pointer if N is less than zero or greater than the number of query
** parameters minus 1. The N value is zero-based so N should be 0 to obtain
** the name of the first query parameter, 1 for the second parameter, and
** so forth.
** **
** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and ** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and
** is not a database file pathname pointer that SQLite passed into the xOpen ** is not a database file pathname pointer that the SQLite core passed
** VFS method, then the behavior of this routine is undefined and probably ** into the xOpen VFS method, then the behavior of this routine is undefined
** undesirable. ** and probably undesirable.
**
** Beginning with SQLite [version 3.31.0] ([dateof:3.31.0]) the input F
** parameter can also be the name of a rollback journal file or WAL file
** in addition to the main database file. Prior to version 3.31.0, these
** routines would only work if F was the name of the main database file.
** When the F parameter is the name of the rollback journal or WAL file,
** it has access to all the same query parameters as were found on the
** main database file.
** **
** See the [URI filename] documentation for additional information. ** See the [URI filename] documentation for additional information.
*/ */
const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
const char *sqlite3_uri_key(const char *zFilename, int N);
/* /*
** CAPI3REF: Translate filenames ** CAPI3REF: Translate filenames
** **
** These routines are available to VFS implementations for translating ** These routines are available to [VFS|custom VFS implementations] for
** filenames between the main database file, the journal file, and the ** translating filenames between the main database file, the journal file,
** WAL file. ** and the WAL file.
** **
** If F is the name of an sqlite database file, journal file, or WAL file ** If F is the name of an sqlite database file, journal file, or WAL file
** then sqlite3_filename_database(F) returns the name of the corresponding ** passed by the SQLite core into the VFS, then sqlite3_filename_database(F)
** database file. ** returns the name of the corresponding database file.
** **
** If F is the name of an sqlite database file, journal file, or WAL file ** If F is the name of an sqlite database file, journal file, or WAL file
** then sqlite3_filename_journal(F) returns the name of the corresponding ** passed by the SQLite core into the VFS, or if F is a database filename
** rollback journal file. ** obtained from [sqlite3_db_filename()], then sqlite3_filename_journal(F)
** returns the name of the corresponding rollback journal file.
** **
** If F is the name of an sqlite database file, journal file, or WAL file ** If F is the name of an sqlite database file, journal file, or WAL file
** then sqlite3_filename_wal(F) returns the name of the corresponding ** that was passed by the SQLite core into the VFS, or if F is a database
** filename obtained from [sqlite3_db_filename()], then
** sqlite3_filename_wal(F) returns the name of the corresponding
** WAL file. ** WAL file.
** **
** In all of the above, if F is not the name of a database, journal or WAL ** In all of the above, if F is not the name of a database, journal or WAL
** filename passed into the VFS from the SQLite core, then the result is ** filename passed into the VFS from the SQLite core and F is not the
** return value from [sqlite3_db_filename()], then the result is
** undefined and is likely a memory access violation. ** undefined and is likely a memory access violation.
*/ */
const char *sqlite3_filename_database(const char*); const char *sqlite3_filename_database(const char*);
@@ -6006,6 +6025,17 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** xFullPathname method of the [VFS]. ^In other words, the filename ** xFullPathname method of the [VFS]. ^In other words, the filename
** will be an absolute pathname, even if the filename used ** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname. ** to open the database originally was a URI or relative pathname.
**
** If the filename pointer returned by this routine is not NULL, then it
** can be used as the filename input parameter to these routines:
** <ul>
** <li> [sqlite3_uri_parameter()]
** <li> [sqlite3_uri_boolean()]
** <li> [sqlite3_uri_int64()]
** <li> [sqlite3_filename_database()]
** <li> [sqlite3_filename_journal()]
** <li> [sqlite3_filename_wal()]
** </ul>
*/ */
const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);

View File

@@ -324,7 +324,12 @@ struct sqlite3_api_routines {
int (*value_frombind)(sqlite3_value*); int (*value_frombind)(sqlite3_value*);
/* Version 3.30.0 and later */ /* Version 3.30.0 and later */
int (*drop_modules)(sqlite3*,const char**); int (*drop_modules)(sqlite3*,const char**);
/* Version 3.31.0 and later */
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64); sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
const char *(*uri_key)(const char*,int);
const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*);
}; };
/* /*
@@ -619,7 +624,12 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_value_frombind sqlite3_api->frombind #define sqlite3_value_frombind sqlite3_api->frombind
/* Version 3.30.0 and later */ /* Version 3.30.0 and later */
#define sqlite3_drop_modules sqlite3_api->drop_modules #define sqlite3_drop_modules sqlite3_api->drop_modules
/* Version 3.31.0 andn later */
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64 #define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
#define sqlite3_uri_key sqlite3_api->uri_key
#define sqlite3_filename_database sqlite3_api->filename_database
#define sqlite3_filename_journal sqlite3_api->filename_journal
#define sqlite3_filename_wal sqlite3_api->filename_wal
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)