1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Update comments and documentation associated with new URI parsing code. Add test file e_uri.test, containing tests mapped to documentation regarding URI filenames.

FossilOrigin-Name: 92751788eae082e3104838cb6dd8b9793cb325d1
This commit is contained in:
dan
2011-05-06 18:34:54 +00:00
parent 4d7a4461e2
commit 286ab7c2b1
7 changed files with 560 additions and 41 deletions

View File

@@ -1,5 +1,5 @@
C Have\sthe\sxFullpath\smethod\sin\sos_win.c\sdiscard\sthe\sinitial\s"/"\sif\sa\sfilename\sbegins\swith\s"/X:",\swhere\sX\sis\sany\salphabetic\scharacter.\sAlso\sfix\ssome\stest\sissues\sin\suri.test. C Update\scomments\sand\sdocumentation\sassociated\swith\snew\sURI\sparsing\scode.\sAdd\stest\sfile\se_uri.test,\scontaining\stests\smapped\sto\sdocumentation\sregarding\sURI\sfilenames.
D 2011-05-05T18:53:48.721 D 2011-05-06T18:34:54.463
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -144,7 +144,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85 F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85
F src/main.c 872493d84fed9b9c910e1b7b2427a3e28dbe995a F src/main.c 145f04d5d8a6a391093b8e6a3b37511ac79e05c3
F src/malloc.c 74c740e8ba22b806cfb980c8c0ddea1cbd54a20e F src/malloc.c 74c740e8ba22b806cfb980c8c0ddea1cbd54a20e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
@@ -179,14 +179,14 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff
F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79 F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79
F src/sqlite.h.in f865bde9a0af4cd77b85265df71a9d760e5def18 F src/sqlite.h.in 6acf3863a9ac8cd613029ff4d477519406632d78
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
F src/sqliteInt.h 5a7bf51f767fb67b484f09d73cccff683731af22 F src/sqliteInt.h 5a7bf51f767fb67b484f09d73cccff683731af22
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 501c9a200fd998a268be475be5858febc90b725b F src/tclsqlite.c 501c9a200fd998a268be475be5858febc90b725b
F src/test1.c e0e4af306b678da05334c2ccaf0377ae8f06e911 F src/test1.c f506164085bc4cbbb4b5c14b9c6de153f1aeafc5
F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432
F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
@@ -379,6 +379,7 @@ F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test bf385ae3aa0f014c4933ae66fd3e1302138493eb F test/e_select.test bf385ae3aa0f014c4933ae66fd3e1302138493eb
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92 F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
F test/e_update.test 963d6876064e65f318d1c93aaed36a02b9b389bf F test/e_update.test 963d6876064e65f318d1c93aaed36a02b9b389bf
F test/e_uri.test 26c3ba638e38b9a92272174564df41e7c48e25a1
F test/e_vacuum.test 6c09c2af7f2f140518f371c5342100118f779dcf F test/e_vacuum.test 6c09c2af7f2f140518f371c5342100118f779dcf
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
@@ -840,7 +841,7 @@ F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2
F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e
F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced
F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172
F test/uri.test f21a5cd025ccedf0c6d4c5e365bb47e163098c04 F test/uri.test e8579b07985b8f4f658eb4e077962a9b2b7b6491
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
F test/vacuum.test 29b60e8cc9e573b39676df6c4a75fe9e02d04a09 F test/vacuum.test 29b60e8cc9e573b39676df6c4a75fe9e02d04a09
F test/vacuum2.test 91a84c9b08adfc4472097d2e8deb0150214e0e76 F test/vacuum2.test 91a84c9b08adfc4472097d2e8deb0150214e0e76
@@ -934,7 +935,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P ea562d6d67c2f2ef8baca02a77634c21b945196f P fe57a8f621944fd2af5a4e9349c8fd77c4aba237
R ab4f619c8bbf9faf6cdcf553d75032d8 R 3f5b227194b2ccadbce712d322c27966
U dan U dan
Z d81fc059a3e07abc471a058222e61ec9 Z 5f09c493780289f14c0820ca02b5d7dc

View File

@@ -1 +1 @@
fe57a8f621944fd2af5a4e9349c8fd77c4aba237 92751788eae082e3104838cb6dd8b9793cb325d1

View File

@@ -1791,9 +1791,28 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
} }
/* /*
** This function is used to parse URIs passed by the user to API functions ** This function is used to parse both URIs and non-URI filenames passed by the
** sqlite3_open() or sqlite3_open_v2(), and for database URIs specified as ** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database
** part of ATTACH statements. ** URIs specified as part of ATTACH statements.
**
** The first argument to this function is the name of the VFS to use (or
** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx"
** query parameter. The second argument contains the URI (or non-URI filename)
** itself. When this function is called the *pFlags variable should contain
** the default flags to open the database handle with. The value stored in
** *pFlags may be updated before returning if the URI filename contains
** "cache=xxx" or "mode=xxx" query parameters.
**
** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to
** the VFS that should be used to open the database file. *pzFile is set to
** point to a buffer containing the name of the file to open. It is the
** responsibility of the caller to eventually call sqlite3_free() to release
** this buffer.
**
** If an error occurs, then an SQLite error code is returned and *pzErrMsg
** may be set to point to a buffer containing an English language error
** message. It is the responsibility of the caller to eventually release
** this buffer by calling sqlite3_free().
*/ */
int sqlite3ParseUri( int sqlite3ParseUri(
const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */
@@ -1819,8 +1838,12 @@ int sqlite3ParseUri(
int iIn; /* Input character index */ int iIn; /* Input character index */
int iOut = 0; /* Output character index */ int iOut = 0; /* Output character index */
int nByte = nUri+2; /* Bytes of space to allocate */ int nByte = nUri+2; /* Bytes of space to allocate */
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
/* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen
** method that there may be extra parameters following the file-name. */
flags |= SQLITE_OPEN_URI;
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
zFile = sqlite3_malloc(nByte); zFile = sqlite3_malloc(nByte);
if( !zFile ) return SQLITE_NOMEM; if( !zFile ) return SQLITE_NOMEM;
@@ -1907,7 +1930,7 @@ int sqlite3ParseUri(
char *zVal = &zOpt[nOpt+1]; char *zVal = &zOpt[nOpt+1];
int nVal = sqlite3Strlen30(zVal); int nVal = sqlite3Strlen30(zVal);
if( nOpt==3 && sqlite3_strnicmp("vfs", zOpt, 3)==0 ){ if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){
zVfs = zVal; zVfs = zVal;
}else{ }else{
struct OpenMode { struct OpenMode {
@@ -1918,7 +1941,7 @@ int sqlite3ParseUri(
int mask; int mask;
int limit; int limit;
if( nOpt==5 && sqlite3_strnicmp("cache", zOpt, 5)==0 ){ if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){
static struct OpenMode aCacheMode[] = { static struct OpenMode aCacheMode[] = {
{ "shared", SQLITE_OPEN_SHAREDCACHE }, { "shared", SQLITE_OPEN_SHAREDCACHE },
{ "private", SQLITE_OPEN_PRIVATECACHE }, { "private", SQLITE_OPEN_PRIVATECACHE },
@@ -1930,7 +1953,7 @@ int sqlite3ParseUri(
limit = mask; limit = mask;
zModeType = "cache"; zModeType = "cache";
} }
if( nOpt==4 && sqlite3_strnicmp("mode", zOpt, 4)==0 ){ if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){
static struct OpenMode aOpenMode[] = { static struct OpenMode aOpenMode[] = {
{ "ro", SQLITE_OPEN_READONLY }, { "ro", SQLITE_OPEN_READONLY },
{ "rw", SQLITE_OPEN_READWRITE }, { "rw", SQLITE_OPEN_READWRITE },
@@ -1949,7 +1972,7 @@ int sqlite3ParseUri(
int mode = 0; int mode = 0;
for(i=0; aMode[i].z; i++){ for(i=0; aMode[i].z; i++){
const char *z = aMode[i].z; const char *z = aMode[i].z;
if( nVal==strlen(z) && 0==sqlite3_strnicmp(zVal, z, nVal) ){ if( nVal==strlen(z) && 0==memcmp(zVal, z, nVal) ){
mode = aMode[i].mode; mode = aMode[i].mode;
break; break;
} }

View File

@@ -2430,10 +2430,8 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** ^SQLite uses the 'path' component of the URI as the path to the database file ** ^SQLite uses the 'path' component of the URI as the path to the database file
** to open. ^If the path begins with a '/' character, then it is interpreted as ** to open. ^If the path begins with a '/' character, then it is interpreted as
** an absolute path. ^If it does not begin with a '/', it is interpreted as a ** an absolute path. ^If it does not begin with a '/', it is interpreted as a
** relative path. ^On windows, if the first component of an absolute path is ** relative path. ^On windows, the first component of an absolute path
** of the form "X:", where "X" is any alphabetic character, it is interpreted ** is a drive specification (e.g. "C:").
** as a drive specification. ^Otherwise, the absolute path is interpreted as
** the full pathname of a file on the current drive.
** **
** The query component of a URI may contain parameters that are interpreted ** The query component of a URI may contain parameters that are interpreted
** either by SQLite itself, or by a [sqlite3_vfs | custom VFS implementation]. ** either by SQLite itself, or by a [sqlite3_vfs | custom VFS implementation].
@@ -2444,20 +2442,22 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** a VFS object that provides the operating system interface that should ** a VFS object that provides the operating system interface that should
** be used to access the database file on disk. ^If this option is set to ** be used to access the database file on disk. ^If this option is set to
** an empty string the default VFS object is used. ^Specifying an unknown ** an empty string the default VFS object is used. ^Specifying an unknown
** VFS is an error. ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is
** present, then the VFS specified by the option takes precedence over
** the value passed as the fourth parameter to sqlite3_open_v2().
** **
** <li> <b>mode</b>: ^(This option may be set to either "ro", "rw" or "rwc". ** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw" or
** Attempting to set it to any other value is an error)^. ^If "ro" is ** "rwc". Attempting to set it to any other value is an error)^.
** specified, then the database is opened for read-only access, just as if ** ^If "ro" is specified, then the database is opened for read-only
** the [SQLITE_OPEN_READONLY] flag had been set in the third argument to ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
** sqlite3_prepare_v2(). ^If the mode option is set to "rw", then the ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to
** database is opened for read-write (but not create) access, as if ** "rw", then the database is opened for read-write (but not create)
** SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had been set. ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
** ^Value "rwc" is equivalent to setting both SQLITE_OPEN_READWRITE and ** been set. ^Value "rwc" is equivalent to setting both
** SQLITE_OPEN_CREATE. ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is
** ^If sqlite3_open_v2() is used, it is an error to specify a value for ** used, it is an error to specify a value for the mode parameter that is
** the mode parameter that is less restrictive than that specified by the ** less restrictive than that specified by the flags passed as the third
** flags passed as the third parameter. ** parameter.
** **
** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
** "private". ^Setting it to "shared" is equivalent to setting the ** "private". ^Setting it to "shared" is equivalent to setting the
@@ -2487,10 +2487,8 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** <tr><td style="white-space:nowrap"> ** <tr><td style="white-space:nowrap">
** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db ** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db
** <td> Windows only: Open the file "data.db" on fred's desktop on drive ** <td> Windows only: Open the file "data.db" on fred's desktop on drive
** C:. If the "C:/" component were omitted from this URI, then the ** C:. Note that the %20 escaping in this example is not strictly
** file "\Documents and Settings\fred\Desktop\data.db" would be opened ** necessary - space characters can be used literally
** on the current drive. Note that the %20 escaping in this example
** is not strictly necessary - space characters can be used literally
** in URI filenames. ** in URI filenames.
** <tr><td> file:data.db?mode=ro&cache=private <td> ** <tr><td> file:data.db?mode=ro&cache=private <td>
** Open file "data.db" in the current directory for read-only access. ** Open file "data.db" in the current directory for read-only access.

View File

@@ -3845,6 +3845,76 @@ static int test_open(
return TCL_OK; return TCL_OK;
} }
/*
** Usage: sqlite3_open_v2 FILENAME FLAGS VFS
*/
static int test_open_v2(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
const char *zFilename;
const char *zVfs;
int flags = 0;
sqlite3 *db;
int rc;
char zBuf[100];
int nFlag;
Tcl_Obj **apFlag;
int i;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "FILENAME FLAGS VFS");
return TCL_ERROR;
}
zFilename = Tcl_GetString(objv[1]);
zVfs = Tcl_GetString(objv[3]);
if( zVfs[0]==0x00 ) zVfs = 0;
rc = Tcl_ListObjGetElements(interp, objv[2], &nFlag, &apFlag);
if( rc!=TCL_OK ) return rc;
for(i=0; i<nFlag; i++){
int iFlag;
struct OpenFlag {
const char *zFlag;
int flag;
} aFlag[] = {
{ "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY },
{ "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE },
{ "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE },
{ "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE },
{ "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE },
{ "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY },
{ "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB },
{ "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB },
{ "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB },
{ "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL },
{ "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL },
{ "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL },
{ "SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL },
{ "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX },
{ "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX },
{ "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE },
{ "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE },
{ "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL },
{ "SQLITE_OPEN_URI", SQLITE_OPEN_URI },
{ 0, 0 }
};
rc = Tcl_GetIndexFromObjStruct(interp, apFlag[i], aFlag, sizeof(aFlag[0]),
"flag", 0, &iFlag
);
if( rc!=TCL_OK ) return rc;
flags |= aFlag[iFlag].flag;
}
rc = sqlite3_open_v2(zFilename, &db, flags, zVfs);
if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
Tcl_AppendResult(interp, zBuf, 0);
return TCL_OK;
}
/* /*
** Usage: sqlite3_open16 filename options ** Usage: sqlite3_open16 filename options
*/ */
@@ -5593,6 +5663,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_errmsg16", test_errmsg16 ,0 }, { "sqlite3_errmsg16", test_errmsg16 ,0 },
{ "sqlite3_open", test_open ,0 }, { "sqlite3_open", test_open ,0 },
{ "sqlite3_open16", test_open16 ,0 }, { "sqlite3_open16", test_open16 ,0 },
{ "sqlite3_open_v2", test_open_v2 ,0 },
{ "sqlite3_complete16", test_complete16 ,0 }, { "sqlite3_complete16", test_complete16 ,0 },
{ "sqlite3_prepare", test_prepare ,0 }, { "sqlite3_prepare", test_prepare ,0 },

427
test/e_uri.test Normal file
View File

@@ -0,0 +1,427 @@
# 2011 May 06
#
# 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.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_uri
db close
proc parse_uri {uri} {
testvfs tvfs2
testvfs tvfs
tvfs filter xOpen
tvfs script parse_uri_open_cb
set ::uri_open [list]
set DB [sqlite3_open_v2 $uri {
SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_WAL
} tvfs]
sqlite3_close $DB
tvfs delete
tvfs2 delete
set ::uri_open
}
proc parse_uri_open_cb {method file arglist} {
set ::uri_open [list $file $arglist]
}
proc open_uri_error {uri} {
set flags {SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_WAL}
set DB [sqlite3_open_v2 $uri $flags ""]
set e [sqlite3_errmsg $DB]
sqlite3_close $DB
set e
}
# EVIDENCE-OF: R-35840-33204 If URI filename interpretation is enabled,
# and the filename argument begins with "file:", then the filename is
# interpreted as a URI.
#
# EVIDENCE-OF: R-00067-59538 URI filename interpretation is enabled if
# the SQLITE_OPEN_URI flag is is set in the fourth argument to
# sqlite3_open_v2(), or if it has been enabled globally using the
# SQLITE_CONFIG_URI option with the sqlite3_config() method.
#
if {$tcl_platform(platform) == "unix"} {
set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE]
# Tests with SQLITE_CONFIG_URI configured to false. URI intepretation is
# only enabled if the SQLITE_OPEN_URI flag is specified.
sqlite3_shutdown
sqlite3_config_uri 0
do_test 1.1 {
forcedelete file:test.db test.db
set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""]
list [file exists file:test.db] [file exists test.db]
} {0 1}
sqlite3_close $DB
do_test 1.2 {
forcedelete file:test.db test.db
set DB [sqlite3_open_v2 file:test.db [concat $flags] ""]
list [file exists file:test.db] [file exists test.db]
} {1 0}
sqlite3_close $DB
# Tests with SQLITE_CONFIG_URI configured to true. URI intepretation is
# enabled with or without SQLITE_OPEN_URI.
sqlite3_shutdown
sqlite3_config_uri 1
do_test 1.3 {
forcedelete file:test.db test.db
set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""]
list [file exists file:test.db] [file exists test.db]
} {0 1}
sqlite3_close $DB
do_test 1.4 {
forcedelete file:test.db test.db
set DB [sqlite3_open_v2 file:test.db [concat $flags] ""]
list [file exists file:test.db] [file exists test.db]
} {0 1}
sqlite3_close $DB
}
# EVIDENCE-OF: R-17482-00398 If the authority is not an empty string or
# "localhost", an error is returned to the caller.
#
if {$tcl_platform(platform) == "unix"} {
set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI]
foreach {tn uri error} "
1 {file://localhost[pwd]/test.db} {not an error}
2 {file://[pwd]/test.db} {not an error}
3 {file://x[pwd]/test.db} {invalid uri authority: x}
4 {file://invalid[pwd]/test.db} {invalid uri authority: invalid}
" {
do_test 2.$tn {
set DB [sqlite3_open_v2 $uri $flags ""]
set e [sqlite3_errmsg $DB]
sqlite3_close $DB
set e
} $error
}
}
# EVIDENCE-OF: R-43804-65312 The 'fragment' component of a URI, if
# present, is always ignored.
#
# It is difficult to test that something is ignore correctly. So these tests
# just show that adding a fragment does not interfere with the pathname or
# parameters passed through to the VFS xOpen() methods.
#
if {$tcl_platform(platform) == "unix"} {
foreach {tn uri parse} "
1 {file:test.db#abc} {[pwd]/test.db {}}
2 {file:test.db?a=b#abc} {[pwd]/test.db {a b}}
3 {file:test.db?a=b#?c=d} {[pwd]/test.db {a b}}
" {
do_test 3.$tn { parse_uri $uri } $parse
}
}
# EVIDENCE-OF: R-00273-20588 SQLite uses the 'path' component of the URI
# as the path to the database file to open.
#
# EVIDENCE-OF: R-28659-11035 If the path begins with a '/' character,
# then it is interpreted as an absolute path.
#
# EVIDENCE-OF: R-39349-47203 If it does not begin with a '/', it is
# interpreted as a relative path.
#
if {$tcl_platform(platform) == "unix"} {
foreach {tn uri parse} "
1 {file:test.db} {[pwd]/test.db {}}
2 {file:/test.db} {/test.db {}}
3 {file:///test.db} {/test.db {}}
4 {file://localhost/test.db} {/test.db {}}
5 {file:/a/b/c/test.db} {/a/b/c/test.db {}}
" {
do_test 4.$tn { parse_uri $uri } $parse
}
}
# EVIDENCE-OF: R-01612-30877 The "vfs" parameter may be used to specify
# the name of a VFS object that provides the operating system interface
# that should be used to access the database file on disk.
#
# The above is tested by cases 1.* below.
#
# EVIDENCE-OF: R-52293-58497 If this option is set to an empty string
# the default VFS object is used.
#
# The above is tested by cases 2.* below.
#
# EVIDENCE-OF: R-31855-18665 If sqlite3_open_v2() is used and the vfs
# option is present, then the VFS specified by the option takes
# precedence over the value passed as the fourth parameter to
# sqlite3_open_v2().
#
# The above is tested by cases 3.* below.
#
proc vfs_open_cb {name args} {
set ::vfs $name
}
foreach {name default} {vfs1 0 vfs2 0 vfs3 1} {
testvfs $name -default $default
$name filter xOpen
$name script [list vfs_open_cb $name]
}
foreach {tn uri defvfs vfs} {
1.1 "file:test.db?vfs=vfs1" "" vfs1
1.2 "file:test.db?vfs=vfs2" "" vfs2
2.1 "file:test.db" vfs1 vfs1
2.2 "file:test.db?vfs=" vfs1 vfs3
3.1 "file:test.db?vfs=vfs1" vfs2 vfs1
3.2 "file:test.db?vfs=vfs2" vfs1 vfs2
3.3 "file:test.db?xvfs=vfs1" vfs2 vfs2
3.4 "file:test.db?xvfs=vfs2" vfs1 vfs1
} {
do_test 5.$tn {
set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI]
sqlite3_close [
sqlite3_open_v2 $uri $flags $defvfs
]
set ::vfs
} $vfs
}
vfs1 delete
vfs2 delete
vfs3 delete
# EVIDENCE-OF: R-48365-36308 Specifying an unknown VFS is an error.
#
set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI]
do_test 6.1 {
set DB [sqlite3_open_v2 file:test.db?vfs=nosuchvfs $flags ""]
set errmsg [sqlite3_errmsg $DB]
sqlite3_close $DB
set errmsg
} {no such vfs: nosuchvfs}
# EVIDENCE-OF: R-60479-64270 The mode parameter may be set to either
# "ro", "rw" or "rwc". Attempting to set it to any other value is an
# error
#
sqlite3 db test.db
db close
foreach {tn uri error} "
1 {file:test.db?mode=ro} {not an error}
2 {file:test.db?mode=rw} {not an error}
3 {file:test.db?mode=rwc} {not an error}
4 {file:test.db?mode=Ro} {no such access mode: Ro}
5 {file:test.db?mode=Rw} {no such access mode: Rw}
6 {file:test.db?mode=Rwc} {no such access mode: Rwc}
" {
do_test 7.$tn { open_uri_error $uri } $error
}
# EVIDENCE-OF: R-09651-31805 If "ro" is specified, then the database is
# opened for read-only access, just as if the SQLITE_OPEN_READONLY flag
# had been set in the third argument to sqlite3_prepare_v2().
#
# EVIDENCE-OF: R-40137-26050 If the mode option is set to "rw", then the
# database is opened for read-write (but not create) access, as if
# SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had been set.
#
# EVIDENCE-OF: R-26845-32976 Value "rwc" is equivalent to setting both
# SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE.
#
sqlite3_shutdown
sqlite3_config_uri 1
foreach {tn uri read write create} {
1 {file:test.db?mode=ro} 1 0 0
2 {file:test.db?mode=rw} 1 1 0
3 {file:test.db?mode=rwc} 1 1 1
} {
set RES(c,0) {1 {unable to open database file}}
set RES(c,1) {0 {}}
set RES(w,0) {1 {attempt to write a readonly database}}
set RES(w,1) {0 {}}
set RES(r,0) {1 {this never happens}}
set RES(r,1) {0 {a b}}
# Test CREATE access:
forcedelete test.db
do_test 8.$tn.c { list [catch { sqlite3 db $uri } msg] $msg } $RES(c,$create)
catch { db close }
sqlite3 db test.db
db eval { CREATE TABLE t1(a, b) ; INSERT INTO t1 VALUES('a', 'b') ;}
db close
# Test READ access:
do_test 8.$tn.r {
sqlite3 db $uri
catchsql { SELECT * FROM t1 }
} $RES(r,$read)
# Test WRITE access:
do_test 8.$tn.w {
sqlite3 db $uri
catchsql { INSERT INTO t1 VALUES(1, 2) }
} $RES(w,$write)
catch {db close}
}
# EVIDENCE-OF: R-56032-32287 If sqlite3_open_v2() is used, it is an
# error to specify a value for the mode parameter that is less
# restrictive than that specified by the flags passed as the third
# parameter.
#
forcedelete test.db
sqlite3 db test.db
db close
foreach {tn uri flags error} {
1 {file:test.db?mode=ro} ro {not an error}
2 {file:test.db?mode=ro} rw {not an error}
3 {file:test.db?mode=ro} rwc {not an error}
4 {file:test.db?mode=rw} ro {access permission denied}
5 {file:test.db?mode=rw} rw {not an error}
6 {file:test.db?mode=rw} rwc {not an error}
7 {file:test.db?mode=rwc} ro {access permission denied}
8 {file:test.db?mode=rwc} rw {access permission denied}
9 {file:test.db?mode=rwc} rwc {not an error}
} {
set f(ro) [list SQLITE_OPEN_READONLY SQLITE_OPEN_URI]
set f(rw) [list SQLITE_OPEN_READWRITE SQLITE_OPEN_URI]
set f(rwc) [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI]
set DB [sqlite3_open_v2 $uri $f($flags) ""]
set e [sqlite3_errmsg $DB]
sqlite3_close $DB
do_test 9.$tn { set e } $error
}
# EVIDENCE-OF: R-23182-54295 The cache parameter may be set to either
# "shared" or "private".
sqlite3 db test.db
db close
foreach {tn uri error} "
1 {file:test.db?cache=private} {not an error}
2 {file:test.db?cache=shared} {not an error}
3 {file:test.db?cache=yes} {no such cache mode: yes}
4 {file:test.db?cache=} {no such cache mode: }
" {
do_test 10.$tn { open_uri_error $uri } $error
}
# EVIDENCE-OF: R-23027-03515 Setting it to "shared" is equivalent to
# setting the SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed
# to sqlite3_open_v2().
#
# EVIDENCE-OF: R-49793-28525 Setting the cache parameter to "private" is
# equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
#
# EVIDENCE-OF: R-19510-48080 If sqlite3_open_v2() is used and the
# "cache" parameter is present in a URI filename, its value overrides
# any behaviour requested by setting SQLITE_OPEN_PRIVATECACHE or
# SQLITE_OPEN_SHAREDCACHE flag.
#
set orig [sqlite3_enable_shared_cache]
foreach {tn uri flags shared_default isshared} {
1.1 "file:test.db" "" 0 0
1.2 "file:test.db" "" 1 1
1.3 "file:test.db" private 0 0
1.4 "file:test.db" private 1 0
1.5 "file:test.db" shared 0 1
1.6 "file:test.db" shared 1 1
2.1 "file:test.db?cache=private" "" 0 0
2.2 "file:test.db?cache=private" "" 1 0
2.3 "file:test.db?cache=private" private 0 0
2.4 "file:test.db?cache=private" private 1 0
2.5 "file:test.db?cache=private" shared 0 0
2.6 "file:test.db?cache=private" shared 1 0
3.1 "file:test.db?cache=shared" "" 0 1
3.2 "file:test.db?cache=shared" "" 1 1
3.3 "file:test.db?cache=shared" private 0 1
3.4 "file:test.db?cache=shared" private 1 1
3.5 "file:test.db?cache=shared" shared 0 1
3.6 "file:test.db?cache=shared" shared 1 1
} {
forcedelete test.db
sqlite3_enable_shared_cache 1
sqlite3 db test.db
sqlite3_enable_shared_cache 0
db eval {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('ok');
}
unset -nocomplain f
set f() {SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI}
set f(shared) [concat $f() SQLITE_OPEN_SHAREDCACHE]
set f(private) [concat $f() SQLITE_OPEN_PRIVATECACHE]
sqlite3_enable_shared_cache $shared_default
set DB [sqlite3_open_v2 $uri $f($flags) ""]
set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy]
db eval {
BEGIN;
INSERT INTO t1 VALUES('ko');
}
sqlite3_step $STMT
sqlite3_finalize $STMT
set RES(0) {not an error}
set RES(1) {database table is locked: t1}
do_test 11.$tn { sqlite3_errmsg $DB } $RES($isshared)
sqlite3_close $DB
db close
}
sqlite3_enable_shared_cache $orig
# EVIDENCE-OF: R-63472-46769 Specifying an unknown parameter in the
# query component of a URI is not an error.
#
do_test 12.1 {
parse_uri file://localhost/test.db?an=unknown&parameter=is&ok=
} {/test.db {an unknown parameter is ok {}}}
do_test 12.2 {
parse_uri file://localhost/test.db?an&unknown&parameter&is&ok
} {/test.db {an {} unknown {} parameter {} is {} ok {}}}
# EVIDENCE-OF: R-27458-04043 URI hexadecimal escape sequences (%HH) are
# supported within the path and query components of a URI.
#
# EVIDENCE-OF: R-52765-50368 Before the path or query components of a
# URI filename are interpreted, they are encoded using UTF-8 and all
# hexadecimal escape sequences replaced by a single byte containing the
# corresponding octet.
#
# The second of the two statements above is tested by creating a
# multi-byte utf-8 character using a sequence of %HH escapes.
#
foreach {tn uri parse} "
1 {file:/test.%64%62} {/test.db {}}
2 {file:/test.db?%68%65%6c%6c%6f=%77%6f%72%6c%64} {/test.db {hello world}}
3 {file:/%C3%BF.db} {/\xFF.db {}}
" {
do_test 13.$tn { parse_uri $uri } $parse
}
finish_test

View File

@@ -20,6 +20,7 @@ source $testdir/tester.tcl
# 3.*: That specifying an unknown VFS causes an error. # 3.*: That specifying an unknown VFS causes an error.
# 4.*: Tests for specifying other options (other than "vfs"). # 4.*: Tests for specifying other options (other than "vfs").
# 5.*: Test using a different VFS with an attached database. # 5.*: Test using a different VFS with an attached database.
# 6.*: Test that authorities other than "" and localhost cause errors.
# #
set testprefix uri set testprefix uri
@@ -128,8 +129,6 @@ do_test 3.1 {
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Test some of the other options (other than "vfs"). # Test some of the other options (other than "vfs").
# #
# TODO: Fix this after the list of options is decided.
#
foreach {tn mode create_ok write_ok readonly_ok} { foreach {tn mode create_ok write_ok readonly_ok} {
1 ro 0 0 1 1 ro 0 0 1
2 rw 0 1 0 2 rw 0 1 0