]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change the supported URI options to "mode" and "cache".
authordan <dan@noemail.net>
Tue, 3 May 2011 10:22:32 +0000 (10:22 +0000)
committerdan <dan@noemail.net>
Tue, 3 May 2011 10:22:32 +0000 (10:22 +0000)
FossilOrigin-Name: 0a694a0b27e3ce251ce313cb5d19a7637c2fa309

manifest
manifest.uuid
src/main.c
test/uri.test

index 5dc26122512af6c92a1424931e4281374aca38ec..af1b6678735192a1a1ee3d36428062494a449c64 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\sthe\slatest\strunk\schanges\sinto\suri\sbranch.
-D 2011-05-02T17:41:01.076
+C Change\sthe\ssupported\sURI\soptions\sto\s"mode"\sand\s"cache".
+D 2011-05-03T10:22:32.361
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -143,7 +143,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
 F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
 F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
 F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85
-F src/main.c 933d0bcf586ba7acbe2ce3f37d35c474a8306109
+F src/main.c 8e13c02ec1992f94dcc06b4b2bc0001a79b3e68f
 F src/malloc.c 74c740e8ba22b806cfb980c8c0ddea1cbd54a20e
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
@@ -837,7 +837,7 @@ F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2
 F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e
 F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced
 F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172
-F test/uri.test 062ba42524a5042985e7994dc2289259424b60bf
+F test/uri.test 2e2dea3054bc6b3e5e1bf43fbab09a847ed9eb5f
 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
 F test/vacuum.test 29b60e8cc9e573b39676df6c4a75fe9e02d04a09
 F test/vacuum2.test 91a84c9b08adfc4472097d2e8deb0150214e0e76
@@ -931,7 +931,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 2af51f856c6203f836d8bb62b6b79b19554886e7 f55156c5194e85c47728b8a97fde3e5f0a5c9b56
-R 5b3361d8c251d725e8fb18c102b1e7f2
+P 7fdd0786c7e0d66baf3aba4485128e16a4e5ea46
+R 9466d8a507f14eedc64f1b5ce9c925cf
 U dan
-Z ce77508d586b51f29df902539114b8b5
+Z bebe00795592ddf7acadaf3bca1d1f57
index 8258359950761cc8571ce83d0d161276454267e3..1c54c8762d63caac7443a9787048c4a3f36ad5dc 100644 (file)
@@ -1 +1 @@
-7fdd0786c7e0d66baf3aba4485128e16a4e5ea46
\ No newline at end of file
+0a694a0b27e3ce251ce313cb5d19a7637c2fa309
\ No newline at end of file
index 313222f54b27a373297092f9b2d5db3dc78d59f9..eaf0f74159a7a1f3a2c599ab46d04653b7c3bd10 100644 (file)
@@ -1803,18 +1803,7 @@ int sqlite3ParseUri(
   char **pzFile,                  /* OUT: Filename component of URI */
   char **pzErrMsg                 /* OUT: Error message (if rc!=SQLITE_OK) */
 ){
-  struct UriOption {
-    const char *zOption;
-    int mask;
-  } aOpt [] = {
-    { "vfs", 0 },
-    { "readonly",     SQLITE_OPEN_READONLY },
-    { "readwrite",    SQLITE_OPEN_READWRITE },
-    { "create",       SQLITE_OPEN_CREATE },
-    { "sharedcache",  SQLITE_OPEN_SHAREDCACHE },
-    { "privatecache", SQLITE_OPEN_PRIVATECACHE }
-  };
-
+  int rc = SQLITE_OK;
   int flags = *pFlags;
   const char *zVfs = zDefaultVfs;
   char *zFile;
@@ -1864,7 +1853,12 @@ int sqlite3ParseUri(
         codepoint += sqlite3HexToInt(zUri[iIn++]);
 
         assert( codepoint>=0 && codepoint<256 );
-        if( codepoint==0 ){
+        if( codepoint>=128 ){
+          *pzErrMsg = sqlite3_mprintf("invalid uri escape: %.3s", &zUri[-3]);
+          rc = SQLITE_ERROR;
+          goto parse_uri_out;
+        }
+        else if( codepoint==0 ){
           /* This branch is taken when "%00" appears within the URI. In this
           ** case we ignore all text in the remainder of the path, name or
           ** value currently being parsed. So ignore the current character
@@ -1904,27 +1898,70 @@ int sqlite3ParseUri(
     /* Check if there were any options specified that should be interpreted 
     ** here. Options that are interpreted here include "vfs" and those that
     ** correspond to flags that may be passed to the sqlite3_open_v2()
-    ** method.  */
+    ** method. */
     zOpt = &zFile[sqlite3Strlen30(zFile)+1];
     while( zOpt[0] ){
       int nOpt = sqlite3Strlen30(zOpt);
       char *zVal = &zOpt[nOpt+1];
       int nVal = sqlite3Strlen30(zVal);
-      int i;
-
-      for(i=0; i<ArraySize(aOpt); i++){
-        const char *z = aOpt[i].zOption;
-        if( nOpt==sqlite3Strlen30(z) && 0==memcmp(zOpt, z, nOpt) ){
-          int mask = aOpt[i].mask;
-          if( mask==0 ){
-            zVfs = zVal;
-          }else{
-            if( zVal[0]=='\0' || sqlite3GetBoolean(zVal) ){
-              flags |= mask;
-            }else{
-              flags &= ~mask;
+
+      if( nOpt==3 && sqlite3_strnicmp("vfs", zOpt, 3)==0 ){
+        zVfs = zVal;
+      }else{
+        struct OpenMode {
+          const char *z;
+          int mode;
+        } *aMode = 0;
+        char *zModeType;
+        int mask;
+        int limit;
+
+        if( nOpt==5 && sqlite3_strnicmp("cache", zOpt, 5)==0 ){
+          static struct OpenMode aCacheMode[] = {
+            { "shared",  SQLITE_OPEN_SHAREDCACHE },
+            { "private", SQLITE_OPEN_PRIVATECACHE },
+            { 0, 0 }
+          };
+
+          mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE;
+          aMode = aCacheMode;
+          limit = mask;
+          zModeType = "cache";
+        }
+        if( nOpt==4 && sqlite3_strnicmp("mode", zOpt, 4)==0 ){
+          static struct OpenMode aOpenMode[] = {
+            { "ro",  SQLITE_OPEN_READONLY },
+            { "rw",  SQLITE_OPEN_READWRITE }, 
+            { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
+            { 0, 0 }
+          };
+
+          mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
+          aMode = aOpenMode;
+          limit = mask & flags;
+          zModeType = "access";
+        }
+
+        if( aMode ){
+          int i;
+          int mode = 0;
+          for(i=0; aMode[i].z; i++){
+            const char *z = aMode[i].z;
+            if( nVal==strlen(z) && 0==sqlite3_strnicmp(zVal, z, nVal) ){
+              mode = aMode[i].mode;
+              break;
             }
           }
+          if( mode==0 ){
+            *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal);
+            rc = SQLITE_ERROR;
+            goto parse_uri_out;
+          }
+          if( mode>limit ){
+            rc = SQLITE_PERM;
+            goto parse_uri_out;
+          }
+          flags = (flags & ~mask) | mode;
         }
       }
 
@@ -1942,12 +1979,16 @@ int sqlite3ParseUri(
   *ppVfs = sqlite3_vfs_find(zVfs);
   if( *ppVfs==0 ){
     *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs);
+    rc = SQLITE_ERROR;
+  }
+ parse_uri_out:
+  if( rc!=SQLITE_OK ){
     sqlite3_free(zFile);
-    return SQLITE_ERROR;
+    zFile = 0;
   }
   *pFlags = flags;
   *pzFile = zFile;
-  return SQLITE_OK;
+  return rc;
 }
 
 
@@ -1974,6 +2015,27 @@ static int openDatabase(
   if( rc ) return rc;
 #endif
 
+  /* Only allow sensible combinations of bits in the flags argument.  
+  ** Throw an error if any non-sense combination is used.  If we
+  ** do not block illegal combinations here, it could trigger
+  ** assert() statements in deeper layers.  Sensible combinations
+  ** are:
+  **
+  **  1:  SQLITE_OPEN_READONLY
+  **  2:  SQLITE_OPEN_READWRITE
+  **  6:  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
+  */
+  assert( SQLITE_OPEN_READONLY  == 0x01 );
+  assert( SQLITE_OPEN_READWRITE == 0x02 );
+  assert( SQLITE_OPEN_CREATE    == 0x04 );
+  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
+  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
+  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
+  if( ((1<<(flags&7)) & 0x46)==0 ){
+    rc = SQLITE_MISUSE;
+    goto opendb_out;
+  }
+
   if( sqlite3GlobalConfig.bCoreMutex==0 ){
     isThreadsafe = 0;
   }else if( flags & SQLITE_OPEN_NOMUTEX ){
@@ -2078,32 +2140,11 @@ static int openDatabase(
   /* Parse the filename/URI argument. */
   rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
   if( rc!=SQLITE_OK ){
-    sqlite3Error(db, rc, "%s", zErrMsg);
+    sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
     sqlite3_free(zErrMsg);
     goto opendb_out;
   }
 
-  /* Only allow sensible combinations of bits in the flags argument.  
-  ** Throw an error if any non-sense combination is used.  If we
-  ** do not block illegal combinations here, it could trigger
-  ** assert() statements in deeper layers.  Sensible combinations
-  ** are:
-  **
-  **  1:  SQLITE_OPEN_READONLY
-  **  2:  SQLITE_OPEN_READWRITE
-  **  6:  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
-  */
-  assert( SQLITE_OPEN_READONLY  == 0x01 );
-  assert( SQLITE_OPEN_READWRITE == 0x02 );
-  assert( SQLITE_OPEN_CREATE    == 0x04 );
-  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
-  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
-  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
-  if( ((1<<(flags&7)) & 0x46)==0 ){
-    rc = SQLITE_MISUSE;
-    goto opendb_out;
-  }
-
   /* Open the backend database driver */
   db->openFlags = flags;
   rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0,
index 6248381f815059f0d4609e2785d479cae09a5fb5..38b0740ec12aa8f65250ca8b16cc40b7d054f426 100644 (file)
@@ -117,26 +117,77 @@ do_test 3.1 {
 #
 # TODO: Fix this after the list of options is decided.
 #
-do_test 4.0 {
+foreach {tn mode create_ok write_ok readonly_ok} {
+  1    ro    0   0   1
+  2    rw    0   1   0
+  3    rwc   1   1   0
+} {
+  catch { db close }
+  forcedelete test.db
+
+  set A(1) {0 {}}
+  set A(0) {1 {unable to open database file}}
+  do_test 4.1.$tn.1 {
+    list [catch {sqlite3 db "file:test.db?mode=$mode"} msg] $msg
+  } $A($create_ok)
+
+  catch { db close }
+  forcedelete test.db
   sqlite3 db test.db
-  db eval {CREATE TABLE t1(a, b)}
+  db eval { CREATE TABLE t1(a, b) }
   db close
-} {}
-foreach {tn uri ro} {
-  1    "file:test.db"                                 0
-  2    "file:test.db?readonly=0"                      0
-  3    "file:test.db?readonly=1&readwrite=0&create=0" 1
-} {
-  set RES(0) {0 {}}
-  set RES(1) {1 {attempt to write a readonly database}}
 
-  do_test 4.$tn {
-    sqlite3 db $uri
+  set A(1) {0 {}}
+  set A(0) {1 {attempt to write a readonly database}}
+  do_test 4.1.$tn.2 {
+    sqlite3 db "file:test.db?mode=$mode"
     catchsql { INSERT INTO t1 VALUES(1, 2) }
-  } $RES($ro)
-  db close
+  } $A($write_ok)
+
+  set A(1) {0 {}}
+  set A(0) {1 {access permission denied}}
+  do_test 4.1.$tn.3 {
+    list [catch {sqlite3 db "file:test.db?mode=$mode" -readonly 1} msg] $msg
+  } $A($readonly_ok)
 }
 
+set orig [sqlite3_enable_shared_cache]
+foreach {tn options sc_default is_shared} {
+  1    ""                1   1
+  2    "cache=private"   1   0
+  3    "cache=shared"    1   1
+  4    ""                0   0
+  5    "cache=private"   0   0
+  6    "cache=shared"    0   1
+} {
+  catch { db close }
+  forcedelete test.db
+
+  sqlite3_enable_shared_cache 1
+  sqlite3 db2 test.db
+  db2 eval {CREATE TABLE t1(a, b)}
+
+  sqlite3_enable_shared_cache $sc_default
+  sqlite3 db "file:test.db?$options"
+  db eval {SELECT * FROM t1}
+
+  set A(1) {1 {database table is locked: t1}}
+  set A(0) {0 {}}
+  do_test 4.2.$tn {
+    db2 eval {BEGIN; INSERT INTO t1 VALUES(1, 2);}
+    catchsql { SELECT * FROM t1 }
+  } $A($is_shared)
+
+  db2 close
+}
+
+do_test 4.3.1 {
+  list [catch {sqlite3 db "file:test.db?mode=rc"} msg] $msg
+} {1 {no such access mode: rc}}
+do_test 4.3.2 {
+  list [catch {sqlite3 db "file:test.db?cache=public"} msg] $msg
+} {1 {no such cache mode: public}}
+
 #-------------------------------------------------------------------------
 # Test that things work if an ATTACHed database uses a different VFS than
 # the main database. The important point is that for all operations 
@@ -177,7 +228,7 @@ do_test 5.1.1 {
     CREATE TABLE t1(a, b);
     CREATE TABLE aux.t2(a, b);
     PRAGMA main.journal_mode = WAL;
-    PRAGMA aux.journal_mode = PERSIST;
+    PRAGMA aux.journal_mode = WAL;
     INSERT INTO t1 VALUES('x', 'y');
     INSERT INTO t2 VALUES('x', 'y');
   }