From: dan Date: Fri, 9 Sep 2016 20:00:40 +0000 (+0000) Subject: Add new file test_delete.c, containing test code for deleting an sqlite database. X-Git-Tag: version-3.15.0~102^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=000f95b1ba8760b3d8859395ed360b9933634ae3;p=thirdparty%2Fsqlite.git Add new file test_delete.c, containing test code for deleting an sqlite database. FossilOrigin-Name: fb0b95e9405a3180d13c6318409af361e9df7632 --- diff --git a/Makefile.in b/Makefile.in index 9b2fe86cf4..bb1f14b6ab 100644 --- a/Makefile.in +++ b/Makefile.in @@ -382,6 +382,7 @@ TESTSRC = \ $(TOP)/src/test_blob.c \ $(TOP)/src/test_btree.c \ $(TOP)/src/test_config.c \ + $(TOP)/src/test_delete.c \ $(TOP)/src/test_demovfs.c \ $(TOP)/src/test_devsym.c \ $(TOP)/src/test_fs.c \ diff --git a/Makefile.msc b/Makefile.msc index 6c7211651d..931e1836b3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1269,6 +1269,7 @@ TESTSRC = \ $(TOP)\src\test_blob.c \ $(TOP)\src\test_btree.c \ $(TOP)\src\test_config.c \ + $(TOP)\src\test_delete.c \ $(TOP)\src\test_demovfs.c \ $(TOP)\src\test_devsym.c \ $(TOP)\src\test_fs.c \ diff --git a/main.mk b/main.mk index 451837ffff..a5a50d205d 100644 --- a/main.mk +++ b/main.mk @@ -293,6 +293,7 @@ TESTSRC = \ $(TOP)/src/test_blob.c \ $(TOP)/src/test_btree.c \ $(TOP)/src/test_config.c \ + $(TOP)/src/test_delete.c \ $(TOP)/src/test_demovfs.c \ $(TOP)/src/test_devsym.c \ $(TOP)/src/test_fs.c \ diff --git a/manifest b/manifest index 0c8f1e22eb..8bece82eaf 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\sa\sout-of-order\svariable\sdeclaration\sfor\ssome\scompile-time\sconfigurations. -D 2016-09-09T15:12:41.801 -F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 +C Add\snew\sfile\stest_delete.c,\scontaining\stest\scode\sfor\sdeleting\san\ssqlite\sdatabase. +D 2016-09-09T20:00:40.358 +F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c +F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 25e2e333adeff5965520bc8db999c658898c972d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -310,7 +310,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 1883ecab643b136e8ab3fdc33785e6ea8b5ceb46 +F main.mk 06dc0b1a9c9e2d05c9275937dd5b894bfe7d17d8 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -396,7 +396,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 -F src/test1.c 8574e41c1bf103727909b37351b3690cc07bc8a7 +F src/test1.c 61a08ed5861f3396ea4ff83931387696b692e1f8 F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -412,6 +412,7 @@ F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c a0f7ad49a0c9d4b72f693fe2a71c58d7e507174d F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 +F src/test_delete.c 3e7c7223fd78da017569aea5521696a2d203d2ba F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b @@ -631,6 +632,7 @@ F test/delete.test acc38fca8ee4851467705b1c2cfea64cd26667e5 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/delete4.test 21d2113217eeaacac2d99defe14fe6611615ae86 +F test/delete_db.test 906fb709bd71443c2484dcf24b05a21d125d149f F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 @@ -1523,7 +1525,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2bdd838e2c434f1d26b1836ef39fa938ef93131d -R cdaf391119a3a76bb49bf405a13f8694 -U drh -Z f913482662ff429e344c363b85d81ce9 +P 6ac932c92a61cd68cc5b1816216e4748a5c7b3cd +R 49c1be8b151a3311317589c820143e41 +T *branch * test_delete +T *sym-test_delete * +T -sym-trunk * +U dan +Z b08ae969e8f18eb5dd37e3842872bc5d diff --git a/manifest.uuid b/manifest.uuid index 163d453923..ad51945639 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ac932c92a61cd68cc5b1816216e4748a5c7b3cd \ No newline at end of file +fb0b95e9405a3180d13c6318409af361e9df7632 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 367bcc1f7b..a7d20be45d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2388,6 +2388,29 @@ static int SQLITE_TCLAPI test_snapshot_cmp( } #endif /* SQLITE_ENABLE_SNAPSHOT */ +/* +** Usage: sqlite3_delete_database FILENAME +*/ +int sqlite3_delete_database(const char*); /* in test_delete.c */ +static int SQLITE_TCLAPI test_delete_database( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + const char *zFile; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILE"); + return TCL_ERROR; + } + zFile = (const char*)Tcl_GetString(objv[1]); + rc = sqlite3_delete_database(zFile); + + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_OK; +} + /* ** Usage: sqlite3_next_stmt DB STMT ** @@ -7483,6 +7506,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_snapshot_free", test_snapshot_free, 0 }, { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 }, #endif + { "sqlite3_delete_database", test_delete_database, 0 }, }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); diff --git a/src/test_delete.c b/src/test_delete.c new file mode 100644 index 0000000000..6d5c353dea --- /dev/null +++ b/src/test_delete.c @@ -0,0 +1,136 @@ +/* +** 2016 September 10 +** +** 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 file contains test code to delete an SQLite database and all +** of its associated files. Associated files include: +** +** * The journal file. +** * The wal file. +** * The SQLITE_ENABLE_8_3_NAMES version of the db, journal or wal files. +** * Files created by the test_multiplex.c module to extend any of the +** above. +*/ + + +#include +#include +#include +#include "sqlite3.h" + +/* The following #defines are copied from test_multiplex.c */ +#ifndef MX_CHUNK_NUMBER +# define MX_CHUNK_NUMBER 299 +#endif +#ifndef SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET +# define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400 +#endif +#ifndef SQLITE_MULTIPLEX_WAL_8_3_OFFSET +# define SQLITE_MULTIPLEX_WAL_8_3_OFFSET 700 +#endif + +/* +** This routine is a copy of (most of) the code from SQLite function +** sqlite3FileSuffix3(). It modifies the filename in buffer z in the +** same way as SQLite does when in 8.3 filenames mode. +*/ +static void sqlite3Delete83Name(char *z){ + int i, sz; + sz = strlen(z); + for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} + if( z[i]=='.' && (sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); +} + +/* +** zFile is a filename. Assuming no error occurs, if this file exists, +** set *pbExists to true and unlink it. Or, if the file does not exist, +** set *pbExists to false before returning. +** +** If an error occurs, the value of errno is returned. Or, if no error +** occurs, zero is returned. +*/ +static int sqlite3DeleteUnlinkIfExists(const char *zFile, int *pbExists){ + int rc; + rc = access(zFile, F_OK); + if( rc ){ + if( errno==ENOENT ){ + if( pbExists ) *pbExists = 0; + return 0; + } + return errno; + } + if( pbExists ) *pbExists = 1; + rc = unlink(zFile); + if( rc ) return errno; + return 0; +} + +/* +** Delete the database file identified by the string argument passed to this +** function. The string must contain a filename, not an SQLite URI. +*/ +int sqlite3_delete_database( + const char *zFile /* File to delete */ +){ + char *zBuf; /* Buffer to sprintf() filenames to */ + int nBuf; /* Size of buffer in bytes */ + int rc; /* System error code */ + int i; /* Iterate through azFmt[] and aMFile[] */ + + const char *azFmt[] = { "%s", "%s-journal", "%s-wal", "%s-shm" }; + + struct MFile { + const char *zFmt; + int iOffset; + int b83; + } aMFile[] = { + { "%s%03d", 0, 0 }, + { "%s-journal%03d", 0, 0 }, + { "%s-wal%03d", 0, 0 }, + { "%s%03d", 0, 1 }, + { "%s-journal%03d", SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET, 1 }, + { "%s-wal%03d", SQLITE_MULTIPLEX_WAL_8_3_OFFSET, 1 }, + }; + + /* Allocate a buffer large enough for any of the files that need to be + ** deleted. */ + nBuf = strlen(zFile) + 100; + zBuf = (char*)sqlite3_malloc(nBuf); + if( zBuf==0 ) return SQLITE_NOMEM; + + /* Delete both the regular and 8.3 filenames versions of the database, + ** journal, wal and shm files. */ + for(i=0; rc==0 && izFmt, zFile, iChunk+p->iOffset); + if( p->b83 ) sqlite3Delete83Name(zBuf); + rc = sqlite3DeleteUnlinkIfExists(zBuf, &bExists); + if( bExists==0 || rc!=0 ) break; + } + } + + sqlite3_free(zBuf); + return (rc ? SQLITE_ERROR : SQLITE_OK); +} + + diff --git a/test/delete_db.test b/test/delete_db.test new file mode 100644 index 0000000000..520d4f94b3 --- /dev/null +++ b/test/delete_db.test @@ -0,0 +1,214 @@ +# 2016 September 10 +# +# 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 file implements regression tests for SQLite library. The +# focus of this file is testing the DELETE FROM statement. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix delete_db + +proc delete_all {} { + foreach f [glob -nocomplain test2*] { file delete $f } + foreach f [glob -nocomplain test3*] { file delete $f } +} + +proc copydb {} { + foreach f [glob -nocomplain test3*] { file delete $f } + foreach f [glob -nocomplain test2*] { + set p [string range $f 5 end] + file copy "test2$p" "test3$p" + } +} + +proc files {} { + lsort [glob -nocomplain test3*] +} + +db close +delete_all +sqlite3 db test2.database + +#------------------------------------------------------------------------- +# +# 1.1: Journal files. +# 1.2: Wal files. +# 1.3: Multiplexor with journal file. +# 1.4: Multiplexor with wal file. +# +# 2.* are a copy of 1.* with the multiplexor enabled. +# +# 3.* tests errors. +# + +do_test 1.1.0 { + execsql { + CREATE TABLE t1(x, y); + BEGIN; + INSERT INTO t1 VALUES(1, 2); + } + copydb + files +} {test3.database test3.database-journal} + +do_test 1.1.1 { + sqlite3_delete_database test3.database + files +} {} + +do_test 1.2.0 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(3, 4); + } + copydb + files +} {test3.database test3.database-shm test3.database-wal} +do_test 1.2.1 { + sqlite3_delete_database test3.database + files +} {} + +db close +delete_all +sqlite3_multiplex_initialize "" 0 +sqlite3 db test2.database -vfs multiplex +sqlite3_multiplex_control db "main" chunk_size 32768 + +do_test 1.3.0 { + execsql { + CREATE TABLE x1(a, b); + WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1000 ) + INSERT INTO x1 SELECT randomblob(100), randomblob(100) FROM s; + BEGIN; + UPDATE x1 SET a=randomblob(101) + } + copydb + files +} [list {*}{ + test3.database test3.database-journal test3.database001 + test3.database002 test3.database003 +}] +do_test 1.3.1 { + sqlite3_delete_database test3.database + files +} {} + + +do_test 1.4.0 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + UPDATE x1 SET a=randomblob(102) + } + copydb + files +} [list {*}{ + test3.database test3.database-shm test3.database-wal test3.database001 + test3.database002 test3.database003 +}] +do_test 1.4.1 { + sqlite3_delete_database test3.database + files +} {} + + +ifcapable 8_3_names { + db close + delete_all + sqlite3 db file:test2.db?8_3_names=1 -uri 1 + + do_test 2.1.0 { + execsql { + CREATE TABLE t1(x, y); + BEGIN; + INSERT INTO t1 VALUES(1, 2); + } + copydb + files + } {test3.db test3.nal} + + do_test 2.1.1 { + sqlite3_delete_database test3.db + files + } {} + + do_test 2.2.0 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(3, 4); + } + copydb + files + } {test3.db test3.shm test3.wal} + do_test 2.2.1 { + sqlite3_delete_database test3.db + files + } {} + + + db close + delete_all + sqlite3_multiplex_initialize "" 0 + sqlite3 db file:test2.db?8_3_names=1 -uri 1 -vfs multiplex + sqlite3_multiplex_control db "main" chunk_size 32768 + + do_test 2.3.0 { + execsql { + CREATE TABLE x1(a, b); + WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1000 ) + INSERT INTO x1 SELECT randomblob(100), randomblob(100) FROM s; + BEGIN; + UPDATE x1 SET a=randomblob(101) + } + copydb + files + } [list {*}{ + test3.001 test3.002 test3.003 test3.db test3.nal + }] + do_test 2.3.1 { + sqlite3_delete_database test3.db + files + } {} + + + do_test 2.4.0 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + UPDATE x1 SET a=randomblob(102) + } + copydb + files + } [list {*}{ + test3.001 test3.002 test3.003 test3.db test3.db-shm test3.wal + }] + do_test 2.4.1 { + sqlite3_delete_database test3.db + files + } {} +} + +db close +delete_all +sqlite3_multiplex_shutdown + +do_test 3.0 { + file mkdir dir2.db + sqlite3_delete_database dir2.db +} {SQLITE_ERROR} +do_test 3.1 { + sqlite3_delete_database dir2.db/test.db +} {SQLITE_OK} + +finish_test