OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ** 2016 September 10 |
| 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: |
| 6 ** |
| 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. |
| 10 ** |
| 11 ************************************************************************* |
| 12 ** This file contains test code to delete an SQLite database and all |
| 13 ** of its associated files. Associated files include: |
| 14 ** |
| 15 ** * The journal file. |
| 16 ** * The wal file. |
| 17 ** * The SQLITE_ENABLE_8_3_NAMES version of the db, journal or wal files. |
| 18 ** * Files created by the test_multiplex.c module to extend any of the |
| 19 ** above. |
| 20 */ |
| 21 |
| 22 #if SQLITE_OS_WIN |
| 23 # include <io.h> |
| 24 # define F_OK 0 |
| 25 #else |
| 26 # include <unistd.h> |
| 27 #endif |
| 28 #include <string.h> |
| 29 #include <errno.h> |
| 30 #include "sqlite3.h" |
| 31 |
| 32 /* The following #defines are copied from test_multiplex.c */ |
| 33 #ifndef MX_CHUNK_NUMBER |
| 34 # define MX_CHUNK_NUMBER 299 |
| 35 #endif |
| 36 #ifndef SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET |
| 37 # define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400 |
| 38 #endif |
| 39 #ifndef SQLITE_MULTIPLEX_WAL_8_3_OFFSET |
| 40 # define SQLITE_MULTIPLEX_WAL_8_3_OFFSET 700 |
| 41 #endif |
| 42 |
| 43 /* |
| 44 ** This routine is a copy of (most of) the code from SQLite function |
| 45 ** sqlite3FileSuffix3(). It modifies the filename in buffer z in the |
| 46 ** same way as SQLite does when in 8.3 filenames mode. |
| 47 */ |
| 48 static void sqlite3Delete83Name(char *z){ |
| 49 int i, sz; |
| 50 sz = (int)strlen(z); |
| 51 for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} |
| 52 if( z[i]=='.' && (sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); |
| 53 } |
| 54 |
| 55 /* |
| 56 ** zFile is a filename. Assuming no error occurs, if this file exists, |
| 57 ** set *pbExists to true and unlink it. Or, if the file does not exist, |
| 58 ** set *pbExists to false before returning. |
| 59 ** |
| 60 ** If an error occurs, the value of errno is returned. Or, if no error |
| 61 ** occurs, zero is returned. |
| 62 */ |
| 63 static int sqlite3DeleteUnlinkIfExists(const char *zFile, int *pbExists){ |
| 64 int rc; |
| 65 rc = access(zFile, F_OK); |
| 66 if( rc ){ |
| 67 if( errno==ENOENT ){ |
| 68 if( pbExists ) *pbExists = 0; |
| 69 return 0; |
| 70 } |
| 71 return errno; |
| 72 } |
| 73 if( pbExists ) *pbExists = 1; |
| 74 rc = unlink(zFile); |
| 75 if( rc ) return errno; |
| 76 return 0; |
| 77 } |
| 78 |
| 79 /* |
| 80 ** Delete the database file identified by the string argument passed to this |
| 81 ** function. The string must contain a filename, not an SQLite URI. |
| 82 */ |
| 83 SQLITE_API int sqlite3_delete_database( |
| 84 const char *zFile /* File to delete */ |
| 85 ){ |
| 86 char *zBuf; /* Buffer to sprintf() filenames to */ |
| 87 int nBuf; /* Size of buffer in bytes */ |
| 88 int rc = 0; /* System error code */ |
| 89 int i; /* Iterate through azFmt[] and aMFile[] */ |
| 90 |
| 91 const char *azFmt[] = { "%s", "%s-journal", "%s-wal", "%s-shm" }; |
| 92 |
| 93 struct MFile { |
| 94 const char *zFmt; |
| 95 int iOffset; |
| 96 int b83; |
| 97 } aMFile[] = { |
| 98 { "%s%03d", 0, 0 }, |
| 99 { "%s-journal%03d", 0, 0 }, |
| 100 { "%s-wal%03d", 0, 0 }, |
| 101 { "%s%03d", 0, 1 }, |
| 102 { "%s-journal%03d", SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET, 1 }, |
| 103 { "%s-wal%03d", SQLITE_MULTIPLEX_WAL_8_3_OFFSET, 1 }, |
| 104 }; |
| 105 |
| 106 /* Allocate a buffer large enough for any of the files that need to be |
| 107 ** deleted. */ |
| 108 nBuf = (int)strlen(zFile) + 100; |
| 109 zBuf = (char*)sqlite3_malloc(nBuf); |
| 110 if( zBuf==0 ) return SQLITE_NOMEM; |
| 111 |
| 112 /* Delete both the regular and 8.3 filenames versions of the database, |
| 113 ** journal, wal and shm files. */ |
| 114 for(i=0; rc==0 && i<sizeof(azFmt)/sizeof(azFmt[0]); i++){ |
| 115 sqlite3_snprintf(nBuf, zBuf, azFmt[i], zFile); |
| 116 rc = sqlite3DeleteUnlinkIfExists(zBuf, 0); |
| 117 if( rc==0 && i!=0 ){ |
| 118 sqlite3Delete83Name(zBuf); |
| 119 rc = sqlite3DeleteUnlinkIfExists(zBuf, 0); |
| 120 } |
| 121 } |
| 122 |
| 123 /* Delete any multiplexor files */ |
| 124 for(i=0; rc==0 && i<sizeof(aMFile)/sizeof(aMFile[0]); i++){ |
| 125 struct MFile *p = &aMFile[i]; |
| 126 int iChunk; |
| 127 for(iChunk=1; iChunk<=MX_CHUNK_NUMBER; iChunk++){ |
| 128 int bExists; |
| 129 sqlite3_snprintf(nBuf, zBuf, p->zFmt, zFile, iChunk+p->iOffset); |
| 130 if( p->b83 ) sqlite3Delete83Name(zBuf); |
| 131 rc = sqlite3DeleteUnlinkIfExists(zBuf, &bExists); |
| 132 if( bExists==0 || rc!=0 ) break; |
| 133 } |
| 134 } |
| 135 |
| 136 sqlite3_free(zBuf); |
| 137 return (rc ? SQLITE_ERROR : SQLITE_OK); |
| 138 } |
OLD | NEW |