AryaWu/sqlite
0
1/*2** 2016 September 103**4** The author disclaims copyright to this source code. In place of5** 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 all13** 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#ifndef SQLITE_OS_WIN23# include <unistd.h>24# include <errno.h>25#endif26#include <string.h>27#include <assert.h>28#include "sqlite3.h"29 30/* The following #defines are copied from test_multiplex.c */31#ifndef MX_CHUNK_NUMBER 32# define MX_CHUNK_NUMBER 29933#endif34#ifndef SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET35# define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 40036#endif37#ifndef SQLITE_MULTIPLEX_WAL_8_3_OFFSET38# define SQLITE_MULTIPLEX_WAL_8_3_OFFSET 70039#endif40 41/*42** This routine is a copy of (most of) the code from SQLite function43** sqlite3FileSuffix3(). It modifies the filename in buffer z in the44** same way as SQLite does when in 8.3 filenames mode.45*/46static void sqlite3Delete83Name(char *z){47 int i, sz;48 sz = (int)strlen(z);49 for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}50 if( z[i]=='.' && (sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);51}52 53/*54** zFile is a filename. Assuming no error occurs, if this file exists, 55** set *pbExists to true and unlink it. Or, if the file does not exist,56** set *pbExists to false before returning.57**58** If an error occurs, non-zero is returned. Or, if no error occurs, zero.59*/60static int sqlite3DeleteUnlinkIfExists(61 sqlite3_vfs *pVfs,62 const char *zFile, 63 int *pbExists64){65 int rc = SQLITE_ERROR;66#ifdef _WIN3267 if( pVfs ){68 if( pbExists ) *pbExists = 1;69 rc = pVfs->xDelete(pVfs, zFile, 0);70 if( rc==SQLITE_IOERR_DELETE_NOENT ){71 if( pbExists ) *pbExists = 0;72 rc = SQLITE_OK;73 }74 }75#else76 assert( pVfs==0 );77 rc = access(zFile, F_OK);78 if( rc ){79 if( errno==ENOENT ){ 80 if( pbExists ) *pbExists = 0;81 rc = SQLITE_OK; 82 }83 }else{84 if( pbExists ) *pbExists = 1;85 rc = unlink(zFile);86 }87#endif88 return rc;89}90 91/*92** Delete the database file identified by the string argument passed to this93** function. The string must contain a filename, not an SQLite URI.94*/95SQLITE_API int sqlite3_delete_database(96 const char *zFile /* File to delete */97){98 char *zBuf; /* Buffer to sprintf() filenames to */99 int nBuf; /* Size of buffer in bytes */100 int rc = 0; /* System error code */101 int i; /* Iterate through azFmt[] and aMFile[] */102 103 const char *azFmt[] = { "%s", "%s-journal", "%s-wal", "%s-shm" };104 105 struct MFile {106 const char *zFmt;107 int iOffset;108 int b83;109 } aMFile[] = {110 { "%s%03d", 0, 0 },111 { "%s-journal%03d", 0, 0 },112 { "%s-wal%03d", 0, 0 },113 { "%s%03d", 0, 1 },114 { "%s-journal%03d", SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET, 1 },115 { "%s-wal%03d", SQLITE_MULTIPLEX_WAL_8_3_OFFSET, 1 },116 };117 118#ifdef _WIN32119 sqlite3_vfs *pVfs = sqlite3_vfs_find("win32");120#else121 sqlite3_vfs *pVfs = 0;122#endif123 124 /* Allocate a buffer large enough for any of the files that need to be125 ** deleted. */126 nBuf = (int)strlen(zFile) + 100;127 zBuf = (char*)sqlite3_malloc(nBuf);128 if( zBuf==0 ) return SQLITE_NOMEM;129 130 /* Delete both the regular and 8.3 filenames versions of the database,131 ** journal, wal and shm files. */132 for(i=0; rc==0 && i<sizeof(azFmt)/sizeof(azFmt[0]); i++){133 sqlite3_snprintf(nBuf, zBuf, azFmt[i], zFile);134 rc = sqlite3DeleteUnlinkIfExists(pVfs, zBuf, 0);135 if( rc==0 && i!=0 ){136 sqlite3Delete83Name(zBuf);137 rc = sqlite3DeleteUnlinkIfExists(pVfs, zBuf, 0);138 }139 }140 141 /* Delete any multiplexor files */142 for(i=0; rc==0 && i<sizeof(aMFile)/sizeof(aMFile[0]); i++){143 struct MFile *p = &aMFile[i];144 int iChunk;145 for(iChunk=1; iChunk<=MX_CHUNK_NUMBER; iChunk++){146 int bExists;147 sqlite3_snprintf(nBuf, zBuf, p->zFmt, zFile, iChunk+p->iOffset);148 if( p->b83 ) sqlite3Delete83Name(zBuf);149 rc = sqlite3DeleteUnlinkIfExists(pVfs, zBuf, &bExists);150 if( bExists==0 || rc!=0 ) break;151 }152 }153 154 sqlite3_free(zBuf);155 return (rc ? SQLITE_ERROR : SQLITE_OK);156}157 