]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the new sqlite3_create_filename() and sqlite3_free_filename() interfaces
authordrh <drh@noemail.net>
Tue, 18 Feb 2020 19:49:48 +0000 (19:49 +0000)
committerdrh <drh@noemail.net>
Tue, 18 Feb 2020 19:49:48 +0000 (19:49 +0000)
for use by Shims.  Use these interfaces inside the multiplexor.

FossilOrigin-Name: 9469f36ac89e4b75d0ab25fefbeff25201992c53141da915dcaa017083cab6db

manifest
manifest.uuid
src/loadext.c
src/main.c
src/pager.c
src/sqlite.h.in
src/sqlite3ext.h
src/test_multiplex.c

index bb1d336591b718d9f2b26e7906f0692610d9c7e8..8f6fde08614b9e52f0a64861eda6955641947270 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Convert\sinvalid\ssurrogates\sto\s0xfffd\swhen\stranslating\sUTF.
-D 2020-02-17T23:08:16.564
+C Add\sthe\snew\ssqlite3_create_filename()\sand\ssqlite3_free_filename()\sinterfaces\nfor\suse\sby\sShims.\s\sUse\sthese\sinterfaces\sinside\sthe\smultiplexor.
+D 2020-02-18T19:49:48.083
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -494,8 +494,8 @@ F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
 F src/insert.c 9b487eb4b756a2bab16fa5ba19d207375551f7d0b8da3f4dff769f3035dc6bab
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
-F src/loadext.c 8cd803f1747c03a50b32fe87ebfb5851998d0cdafefe02737daa95e0616b42bb
-F src/main.c 12d42b43c331778f6e3a1ebc57b63470f1951350efbea377e03cac6660e03b57
+F src/loadext.c b179df50e6e8bb0c36c149e95d958d49bd8c6c7469e59c01b53d164360bc6c32
+F src/main.c 42577fa09d195dd0f09d4a3d95158ff7f4a677dc83ccb0d6d7e73ff86c2dc6f1
 F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -518,7 +518,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
 F src/os_unix.c 238ad16109b4160d0fba2597ef71459995ab5e304b3d8bbe290a8d5d6d6000e0
 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
-F src/pager.c b1e79698f3903e64d7a8ab5f4b3163aa39ed25686289a68de20b6b5734de70e6
+F src/pager.c f1c92d05440f0f6826430b56e29addf453785f5c5651b8510d17d6310ba5df04
 F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3
 F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c
 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
@@ -533,9 +533,9 @@ F src/resolve.c f0781c9e180028b279bc4ff079ad54f4727223d470c8d2343643fcaf79b67740
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
 F src/select.c 9e5b357f1c0952ff699effe3640be58a7e16497be6b74a2637495f5ef13859f0
 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa
-F src/sqlite.h.in 0d9ef312509cb7c8445f4dc25fedfe103c147668a78a36a607a1064f1e0612a4
+F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
-F src/sqlite3ext.h 27951f294f29cd875c6027f2707d644ef99f469bd97514568b5a8581a114db8c
+F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
 F src/sqliteInt.h d736043dc6291d3af289d911237da0801b6c05be086ae322eedd47a089ae8d2f
 F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
@@ -570,7 +570,7 @@ F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f
 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
 F src/test_malloc.c dec0aa821b230773aeb3dd11d652c1193f7cedb18a20b25659bc672288115242
 F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c
-F src/test_multiplex.c e5fac104a0eebf935e6732cda6abce79ea0b4b10949518d5dac7b0293173a40f
+F src/test_multiplex.c 46e278397bef99b10530c1a695b4f6f23823fde6d6589b182f14e9bd43440b57
 F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
 F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a
 F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4
@@ -1858,7 +1858,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P abc473fb8fb999005dc79a360e34f97b3b25429decf1820dd2afa5c19577753d
-R 4bf2952c1b8e70d0751661faff1674f3
+P 7fab1393c2b22b1f3b159b631e06e7e0d3900850ee249c38e4d3cdd0aacf637e
+R 47e79e218da814ff1e7c3c3b23eeb83f
 U drh
-Z 268df0dffaa8fc33ed45d27c33b3bdad
+Z 32b0e509161127f47e57d0b5e1c85750
index 5af135d1b8ddc02f004ad0ffcaa163785bf6b45a..3e36b9046bb8c8513c8e5efabeac4a8e05dd7f68 100644 (file)
@@ -1 +1 @@
-7fab1393c2b22b1f3b159b631e06e7e0d3900850ee249c38e4d3cdd0aacf637e
\ No newline at end of file
+9469f36ac89e4b75d0ab25fefbeff25201992c53141da915dcaa017083cab6db
\ No newline at end of file
index 245e9b004dbf7afe796c0888e6babda7cc79ab9f..06297e6bb67de901d6e16dc295288e56696dfe57 100644 (file)
@@ -474,6 +474,9 @@ static const sqlite3_api_routines sqlite3Apis = {
   sqlite3_filename_database,
   sqlite3_filename_journal,
   sqlite3_filename_wal,
+  /* Version 3.32.0 and later */
+  sqlite3_create_filename,
+  sqlite3_free_filename,
 };
 
 /*
index 3eccd08ea74b24ce6c6d6c5b9f833d9f64ba02b5..4bfd943464ed30894f7f325c44eebcc97f7114c5 100644 (file)
@@ -4242,6 +4242,68 @@ static const char *databaseName(const char *zName){
   return zName;
 }
 
+/*
+** Append text z[] to the end of p[].  Return a pointer to the first
+** character after then zero terminator on the new text in p[].
+*/
+static char *appendText(char *p, const char *z){
+  size_t n = strlen(z);
+  memcpy(p, z, n+1);
+  return p+n+1;
+}
+
+/*
+** Allocate memory to hold names for a database, journal file, WAL file,
+** and query parameters.  The pointer returned is valid for use by
+** sqlite3_filename_database() and sqlite3_uri_parameter() and related
+** functions.
+**
+** Memory layout must be compatible with that generated by the pager
+** and expected by sqlite3_uri_parameter() and databaseName().
+*/
+char *sqlite3_create_filename(
+  const char *zDatabase,
+  const char *zJournal,
+  const char *zWal,
+  int nParam,
+  const char **azParam
+){
+  sqlite3_int64 nByte;
+  int i;
+  char *pResult, *p;
+  nByte = strlen(zDatabase) + strlen(zJournal) + strlen(zWal) + 10;
+  for(i=0; i<nParam*2; i++){
+    nByte += strlen(azParam[i])+1;
+  }
+  pResult = p = sqlite3_malloc64( nByte );
+  if( p==0 ) return 0;
+  memset(p, 0, 4);
+  p += 4;
+  p = appendText(p, zDatabase);
+  for(i=0; i<nParam*2; i++){
+    p = appendText(p, azParam[i]);
+  }
+  *(p++) = 0;
+  p = appendText(p, zJournal);
+  p = appendText(p, zWal);
+  *(p++) = 0;
+  *(p++) = 0;
+  assert( (sqlite3_int64)(p - pResult)==nByte );
+  return pResult + 4;
+}
+
+/*
+** Free memory obtained from sqlite3_create_filename().  It is a severe
+** error to call this routine with any parameter other than a pointer
+** previously obtained from sqlite3_create_filename() or a NULL pointer.
+*/
+void sqlite3_free_filename(char *p){
+  if( p==0 ) return;
+  p = (char*)databaseName(p);
+  sqlite3_free(p - 4);
+}
+
+
 /*
 ** 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 
index ff62926e742a347a4a867a82f0b7a326ecbec4ed..21473bf25356417850da542234a22cbcfdf4e8d8 100644 (file)
@@ -4770,6 +4770,11 @@ int sqlite3PagerOpen(
   **   - \0
   **   - WAL Path (zWALName)
   **   - \0
+  **
+  ** The sqlite3_create_filename() interface and the databaseFilename() utility
+  ** that is used by sqlite3_filename_database() and kin also depend on the
+  ** specific formatting and order of the various filenames, so if the format
+  ** changes here, be sure to change it there as well.
   */
   pPtr = (u8 *)sqlite3MallocZero(
     ROUND8(sizeof(*pPager)) +            /* Pager structure */
index 0537ab69f1b32d18eee994b4f34695667d4e1b84..7b2049ae0a231d71582be7e245b57f63f85773f9 100644 (file)
@@ -3617,6 +3617,59 @@ const char *sqlite3_filename_database(const char*);
 const char *sqlite3_filename_journal(const char*);
 const char *sqlite3_filename_wal(const char*);
 
+/*
+** CAPI3REF: Create and Destroy VFS Filenames
+**
+** These interfces are provided for use by [VFS shim] implementations and
+** are not useful outside of that context.
+**
+** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
+** database filename D with corresponding journal file J and WAL file W and
+** with N URI parameters key/values pairs in the array P.  The result from
+** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
+** is safe to pass to routines like:
+** <ul>
+** <li> [sqlite3_uri_parameter()],
+** <li> [sqlite3_uri_boolean()],
+** <li> [sqlite3_uri_int64()],
+** <li> [sqlite3_uri_key()], 
+** <li> [sqlite3_filename_database()],
+** <li> [sqlite3_filename_journal()], or
+** <li> [sqlite3_filename_wal()].
+** </ul>
+** If a memory allocation error occurs, sqlite3_create_filename() might
+** return a NULL pointer.  The memory obtained from sqlite3_create_filename(X)
+** must be released by a corresponding call to sqlite3_free_filename(Y).
+**
+** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array
+** of 2*N pointers to strings.  Each pair of pointers in this array corresponds
+** to a key and value for a query parameter.  The P parameter may be a NULL
+** pointer if N is zero.  None of the 2*N pointers in the P array may be
+** NULL pointers and key pointers should not be empty strings.
+** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
+** be NULL pointers, though they can be empty strings.
+**
+** The sqlite3_free_filename(Y) routine releases a memory allocation
+** previously obtained from sqlite3_create_filename().  Invoking
+** sqlite3_free_filename(Y) is a NULL pointer is a harmless no-op.
+**
+** If the Y parameter to sqlite3_free_filename(Y) is anything other
+** than a NULL pointer or a pointer previously acquired from
+** sqlite3_create_filename(), then bad things such as heap
+** corruption or segfaults may occur. The value Y should be 
+** used again after sqlite3_free_filename(Y) has been called.  This means
+** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
+** then the corresponding [sqlite3_module.xClose() method should also be
+** invoked prior to calling sqlite3_free_filename(Y).
+*/
+char *sqlite3_create_filename(
+  const char *zDatabase,
+  const char *zJournal,
+  const char *zWal,
+  int nParam,
+  const char **azParam
+);
+void sqlite3_free_filename(char*);
 
 /*
 ** CAPI3REF: Error Codes And Messages
index bdd0a85ed770b7a9cf118dcd0e01caab839e7f57..a7c76a678481b5b2715a9edde7f29b427b645b41 100644 (file)
@@ -330,6 +330,10 @@ struct sqlite3_api_routines {
   const char *(*filename_database)(const char*);
   const char *(*filename_journal)(const char*);
   const char *(*filename_wal)(const char*);
+  /* Version 3.32.0 and later */
+  char *(*create_filename)(const char*,const char*,const char*,
+                           int,const char**);
+  void (*free_filename)(char*);
 };
 
 /*
@@ -630,6 +634,9 @@ typedef int (*sqlite3_loadext_entry)(
 #define sqlite3_filename_database      sqlite3_api->filename_database
 #define sqlite3_filename_journal       sqlite3_api->filename_journal
 #define sqlite3_filename_wal           sqlite3_api->filename_wal
+/* Version 3.32.0 and later */
+#define sqlite3_create_filename        sqlite3_api->create_filename
+#define sqlite3_free_filename          sqlite3_api->free_filename
 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
 
 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
index 56e78c35f7838e029c7a7651407afa00a090c61c..3c9aa034cc37a14ff23646dd96ff1e02b22161d6 100644 (file)
@@ -267,11 +267,14 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
   if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){
     char *z;
     int n = pGroup->nName;
-    pGroup->aReal[iChunk].z = z = sqlite3_malloc64( n+5 );
+    z = sqlite3_malloc64( n+5 );
     if( z==0 ){
       return SQLITE_NOMEM;
     }
     multiplexFilename(pGroup->zName, pGroup->nName, pGroup->flags, iChunk, z);
+    pGroup->aReal[iChunk].z = sqlite3_create_filename(z,"","",0,0);
+    sqlite3_free(z);
+    if( pGroup->aReal[iChunk].z==0 ) return SQLITE_NOMEM;
   }
   return SQLITE_OK;
 }
@@ -438,7 +441,7 @@ static void multiplexSubClose(
     }
     sqlite3_free(pGroup->aReal[iChunk].p);
   }
-  sqlite3_free(pGroup->aReal[iChunk].z);
+  sqlite3_free_filename(pGroup->aReal[iChunk].z);
   memset(&pGroup->aReal[iChunk], 0, sizeof(pGroup->aReal[iChunk]));
 }