aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/os_unix.c11
-rw-r--r--src/os_win.c11
-rw-r--r--src/sqlite.h.in12
-rw-r--r--src/test1.c33
-rw-r--r--src/test_sqllog.c2
-rw-r--r--src/test_vfstrace.c4
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);
}