diff options
author | drh <drh@noemail.net> | 2012-12-06 19:01:42 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2012-12-06 19:01:42 +0000 |
commit | 696b33e622f4f139be012f12671f860c17d0bb67 (patch) | |
tree | 73649ece8e17b06ce5ebc8a1f8e89ef87c602d45 /src | |
parent | 48dd9deffe0a56081af7055013050b07186b8278 (diff) | |
download | sqlite-696b33e622f4f139be012f12671f860c17d0bb67.tar.gz sqlite-696b33e622f4f139be012f12671f860c17d0bb67.zip |
Add the SQLITE_FCNTL_TEMPFILENAME file control that asks the underlying VFS
to return a new temporary filename. Per request from NSS team at Mozilla.
FossilOrigin-Name: 1a63b1d5fa5d79f96eddbda6d94bc10248863710
Diffstat (limited to 'src')
-rw-r--r-- | src/os_unix.c | 11 | ||||
-rw-r--r-- | src/os_win.c | 11 | ||||
-rw-r--r-- | src/sqlite.h.in | 12 | ||||
-rw-r--r-- | src/test1.c | 33 | ||||
-rw-r--r-- | src/test_sqllog.c | 2 | ||||
-rw-r--r-- | src/test_vfstrace.c | 4 |
6 files changed, 70 insertions, 3 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index a3a012126..315f15018 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3581,6 +3581,9 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ } } +/* Forward declaration */ +static int unixGetTempname(int nBuf, char *zBuf); + /* ** Information and control of an open file handle. */ @@ -3618,6 +3621,14 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); return SQLITE_OK; } + case SQLITE_FCNTL_TEMPFILENAME: { + char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname ); + if( zTFile ){ + unixGetTempname(pFile->pVfs->mxPathname, zTFile); + *(char**)pArg = zTFile; + } + return SQLITE_OK; + } #ifdef SQLITE_DEBUG /* The pager calls this method to signal that it has done ** a rollback and that the database is therefore unchanged and diff --git a/src/os_win.c b/src/os_win.c index 6f4925770..107370c41 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2691,6 +2691,9 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ } } +/* Forward declaration */ +static int getTempname(int nBuf, char *zBuf); + /* ** Control and query of the open file handle. */ @@ -2751,6 +2754,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ } return SQLITE_OK; } + case SQLITE_FCNTL_TEMPFILENAME: { + char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname ); + if( zTFile ){ + getTempname(pFile->pVfs->mxPathname, zTFile); + *(char**)pArg = zTFile; + } + return SQLITE_OK; + } } return SQLITE_NOTFOUND; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ba97cd7d4..0bf0be5fc 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -852,7 +852,6 @@ struct sqlite3_io_methods { ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] ** file control occurs at the beginning of pragma statement analysis and so ** it is able to override built-in [PRAGMA] statements. -** </ul> ** ** <li>[[SQLITE_FCNTL_BUSYHANDLER]] ** ^This file-control may be invoked by SQLite on the database file handle @@ -864,6 +863,16 @@ struct sqlite3_io_methods { ** the array as the only argument. If it returns non-zero, then the operation ** should be retried. If it returns zero, the custom VFS should abandon the ** current operation. +** +** <li>[[SQLITE_FCNTL_TEMPFILENAME]] +** ^Application can invoke this file-control to have SQLite generate a +** temporary filename using the same algorithm that is followed to generate +** temporary filenames for TEMP tables and other internal uses. The +** argument should be a char** which will be filled with the filename +** written into memory obtained from [sqlite3_malloc()]. The caller should +** invoke [sqlite3_free()] on the result to avoid a memory leak. +** +** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 @@ -880,6 +889,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 #define SQLITE_FCNTL_PRAGMA 14 #define SQLITE_FCNTL_BUSYHANDLER 15 +#define SQLITE_FCNTL_TEMPFILENAME 16 /* ** CAPI3REF: Mutex Handle diff --git a/src/test1.c b/src/test1.c index e7a224221..bb8d186c1 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5321,6 +5321,38 @@ static int file_control_vfsname( return TCL_OK; } +/* +** tclcmd: file_control_tempfilename DB ?AUXDB? +** +** Return a string that is a temporary filename +*/ +static int file_control_tempfilename( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + const char *zDbName = "main"; + char *zTName = 0; + + if( objc!=2 && objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + if( objc==3 ){ + zDbName = Tcl_GetString(objv[2]); + } + sqlite3_file_control(db, zDbName, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTName); + Tcl_AppendResult(interp, zTName, (char*)0); + sqlite3_free(zTName); + return TCL_OK; +} + /* ** tclcmd: sqlite3_vfs_list @@ -6150,6 +6182,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_persist_wal", file_control_persist_wal, 0 }, { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0}, { "file_control_vfsname", file_control_vfsname, 0 }, + { "file_control_tempfilename", file_control_tempfilename, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, diff --git a/src/test_sqllog.c b/src/test_sqllog.c index 49569a39f..7cb570bcf 100644 --- a/src/test_sqllog.c +++ b/src/test_sqllog.c @@ -390,7 +390,7 @@ static void testSqllogStmt(struct SLConn *p, const char *zSql){ ** The SQLITE_CONFIG_SQLLOG callback registered by sqlite3_init_sqllog(). */ static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){ - struct SLConn *p; + struct SLConn *p = 0; sqlite3_mutex *master = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); assert( eType==0 || eType==1 || eType==2 ); diff --git a/src/test_vfstrace.c b/src/test_vfstrace.c index d2f7455e3..0aacc01fe 100644 --- a/src/test_vfstrace.c +++ b/src/test_vfstrace.c @@ -475,6 +475,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break; case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break; case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break; + case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break; case 0xca093fa0: zOp = "DB_UNCHANGED"; break; case SQLITE_FCNTL_PRAGMA: { const char *const* a = (const char*const*)pArg; @@ -496,7 +497,8 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z", pInfo->zVfsName, *(char**)pArg); } - if( op==SQLITE_FCNTL_PRAGMA && rc==SQLITE_OK && *(char**)pArg ){ + if( (op==SQLITE_FCNTL_PRAGMA || op==SQLITE_FCNTL_TEMPFILENAME) + && rc==SQLITE_OK && *(char**)pArg ){ vfstrace_printf(pInfo, "%s.xFileControl(%s,%s) returns %s", pInfo->zVfsName, p->zFName, zOp, *(char**)pArg); } |