]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add new file test_delete.c, containing test code for deleting an sqlite database.
authordan <dan@noemail.net>
Fri, 9 Sep 2016 20:00:40 +0000 (20:00 +0000)
committerdan <dan@noemail.net>
Fri, 9 Sep 2016 20:00:40 +0000 (20:00 +0000)
FossilOrigin-Name: fb0b95e9405a3180d13c6318409af361e9df7632

Makefile.in
Makefile.msc
main.mk
manifest
manifest.uuid
src/test1.c
src/test_delete.c [new file with mode: 0644]
test/delete_db.test [new file with mode: 0644]

index 9b2fe86cf47fd39219f75168b42a61350542fe4f..bb1f14b6ab6f5e98d82c8f4b2eb80fc18a866aa6 100644 (file)
@@ -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 \
index 6c7211651d71e0e42d4b91bb2ede9ad337184d8d..931e1836b37fc7111bc3d370b1c7019bbb87c2f8 100644 (file)
@@ -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 451837ffff98cb86592fb23d4082547c7829c5f2..a5a50d205d4933216cdae39e934144e5c9955f19 100644 (file)
--- 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 \
index 0c8f1e22ebbf38434f033efc9b53e3a2e054092c..8bece82eaf3b7746b04766a2a091e841e31cc3f7 100644 (file)
--- 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
index 163d453923b615d227b02ce3559dac82a110e44d..ad519456390a3372e1cc36f83806d59f14d184e2 100644 (file)
@@ -1 +1 @@
-6ac932c92a61cd68cc5b1816216e4748a5c7b3cd
\ No newline at end of file
+fb0b95e9405a3180d13c6318409af361e9df7632
\ No newline at end of file
index 367bcc1f7bc7aa6bb28e79f9cc574a948e4673f2..a7d20be45db8d2f546fafa16cf20b7a2b86c3efb 100644 (file)
@@ -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 (file)
index 0000000..6d5c353
--- /dev/null
@@ -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 <unistd.h>
+#include <string.h>
+#include <errno.h>
+#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 && i<sizeof(azFmt)/sizeof(azFmt[0]); i++){
+    sqlite3_snprintf(nBuf, zBuf, azFmt[i], zFile);
+    rc = sqlite3DeleteUnlinkIfExists(zBuf, 0);
+    if( rc==0 && i!=0 ){
+      sqlite3Delete83Name(zBuf);
+      rc = sqlite3DeleteUnlinkIfExists(zBuf, 0);
+    }
+  }
+
+  /* Delete any multiplexor files */
+  for(i=0; rc==0 && i<sizeof(aMFile)/sizeof(aMFile[0]); i++){
+    struct MFile *p = &aMFile[i];
+    int iChunk;
+    for(iChunk=1; iChunk<=MX_CHUNK_NUMBER; iChunk++){
+      int bExists;
+      sqlite3_snprintf(nBuf, zBuf, p->zFmt, 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 (file)
index 0000000..520d4f9
--- /dev/null
@@ -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