Add PRAGMA 'temp_store_directory'. Added os_*.c function
sqlite3OsIsDirWritable(), split pragma.c changeTempStorage() function into invalidateTempStorage(). (CVS 2171) FossilOrigin-Name: 772e22cbd69463be41c2e73b4fd4eb33946193c4
This commit is contained in:
@@ -176,6 +176,7 @@ int sqlite3OsOpenReadOnly(const char*, OsFile*);
|
||||
int sqlite3OsOpenDirectory(const char*, OsFile*);
|
||||
int sqlite3OsSyncDirectory(const char*);
|
||||
int sqlite3OsTempFileName(char*);
|
||||
int sqlite3OsIsDirWritable(char*);
|
||||
int sqlite3OsClose(OsFile*);
|
||||
int sqlite3OsRead(OsFile*, void*, int amt);
|
||||
int sqlite3OsWrite(OsFile*, const void*, int amt);
|
||||
|
||||
@@ -272,6 +272,22 @@ int sqlite3OsTempFileName(char *zBuf){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the following global variable points to a string which is the
|
||||
** name of a directory, then that directory will be used to store
|
||||
** temporary files.
|
||||
*/
|
||||
char *sqlite3_temp_directory = 0;
|
||||
|
||||
/*
|
||||
** Check that a given pathname is a directory and is writable
|
||||
** Just return false, as module is deprecated.
|
||||
*/
|
||||
int sqlite3OsIsDirWritable(char *zBuf){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Close a file.
|
||||
*/
|
||||
|
||||
+15
-1
@@ -574,7 +574,7 @@ int sqlite3OsOpenDirectory(
|
||||
** name of a directory, then that directory will be used to store
|
||||
** temporary files.
|
||||
*/
|
||||
const char *sqlite3_temp_directory = 0;
|
||||
char *sqlite3_temp_directory = 0;
|
||||
|
||||
/*
|
||||
** Create a temporary file name in zBuf. zBuf must be big enough to
|
||||
@@ -616,6 +616,20 @@ int sqlite3OsTempFileName(char *zBuf){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check that a given pathname is a directory and is writable
|
||||
**
|
||||
*/
|
||||
int sqlite3OsIsDirWritable(char *zBuf){
|
||||
struct stat buf;
|
||||
if( zBuf==0 ) return 0;
|
||||
if( strlen(zBuf)==0 ) return 0;
|
||||
if( stat(zBuf, &buf) ) return 0;
|
||||
if( !S_ISDIR(buf.st_mode) ) return 0;
|
||||
if( access(zBuf, 07) ) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read data from a file into a buffer. Return SQLITE_OK if all
|
||||
** bytes were read successfully and SQLITE_IOERR if anything goes
|
||||
|
||||
+16
-1
@@ -202,7 +202,7 @@ int sqlite3OsOpenDirectory(
|
||||
** name of a directory, then that directory will be used to store
|
||||
** temporary files.
|
||||
*/
|
||||
const char *sqlite3_temp_directory = 0;
|
||||
char *sqlite3_temp_directory = 0;
|
||||
|
||||
/*
|
||||
** Create a temporary file name in zBuf. zBuf must be big enough to
|
||||
@@ -409,6 +409,21 @@ static int unlockReadLock(OsFile *id){
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check that a given pathname is a directory and is writable
|
||||
**
|
||||
*/
|
||||
int sqlite3OsIsDirWritable(char *zBuf){
|
||||
int fileAttr;
|
||||
if(! zBuf ) return 0;
|
||||
if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0;
|
||||
fileAttr = GetFileAttributesA(zBuf);
|
||||
if( fileAttr == 0xffffffff ) return 0;
|
||||
if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Lock the file with the lock specified by parameter locktype - one
|
||||
** of the following:
|
||||
|
||||
+81
-7
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the PRAGMA command.
|
||||
**
|
||||
** $Id: pragma.c,v 1.79 2004/11/22 19:12:21 drh Exp $
|
||||
** $Id: pragma.c,v 1.80 2004/12/20 19:01:33 tpoindex Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -79,14 +79,11 @@ static int getTempStore(const char *z){
|
||||
}
|
||||
|
||||
/*
|
||||
** If the TEMP database is open, close it and mark the database schema
|
||||
** as needing reloading. This must be done when using the TEMP_STORE
|
||||
** or DEFAULT_TEMP_STORE pragmas.
|
||||
** Invalidate temp storage, either when the temp storage is changed
|
||||
** from default, or when 'file' and the temp_store_directory has changed
|
||||
*/
|
||||
static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
int ts = getTempStore(zStorageType);
|
||||
static int invalidateTempStorage(Parse *pParse){
|
||||
sqlite3 *db = pParse->db;
|
||||
if( db->temp_store==ts ) return SQLITE_OK;
|
||||
if( db->aDb[1].pBt!=0 ){
|
||||
if( db->flags & SQLITE_InTrans ){
|
||||
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
|
||||
@@ -97,6 +94,21 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
db->aDb[1].pBt = 0;
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the TEMP database is open, close it and mark the database schema
|
||||
** as needing reloading. This must be done when using the TEMP_STORE
|
||||
** or DEFAULT_TEMP_STORE pragmas.
|
||||
*/
|
||||
static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
int ts = getTempStore(zStorageType);
|
||||
sqlite3 *db = pParse->db;
|
||||
if( db->temp_store==ts ) return SQLITE_OK;
|
||||
if( invalidateTempStorage( pParse ) != SQLITE_OK ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
db->temp_store = ts;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -342,6 +354,68 @@ void sqlite3Pragma(
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA temp_store_directory
|
||||
** PRAGMA temp_store_directory = ""|"directory_name"
|
||||
**
|
||||
** Return or set the local value of the temp_store_directory flag. Changing
|
||||
** the value sets a specific directory to be used for temporary files.
|
||||
** Setting to a null string reverts to the default temporary directory search.
|
||||
** If temporary directory is changed, then invalidateTempStorage.
|
||||
**
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){
|
||||
if( !zRight ){
|
||||
if( sqlite3_temp_directory ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
}else{
|
||||
if( strlen(zRight)==0 ){
|
||||
/* empty path, set to default. allows os_{unix,win}.c to choose directory */
|
||||
if( sqlite3_temp_directory ){
|
||||
/* previous temp_store_directory defined, free and invalidate */
|
||||
sqlite3FreeX(sqlite3_temp_directory);
|
||||
if( db->temp_store==1 ) {
|
||||
/* temp storage is "file", so invalidate temp */
|
||||
invalidateTempStorage( pParse );
|
||||
}
|
||||
}
|
||||
sqlite3_temp_directory = 0;
|
||||
}else{
|
||||
/* check if previous directory defined, free and alloc if needed */
|
||||
if( sqlite3_temp_directory ){
|
||||
if( strlen(sqlite3_temp_directory) < strlen(zRight) + 1){
|
||||
sqlite3FreeX(sqlite3_temp_directory);
|
||||
sqlite3_temp_directory = sqlite3Malloc( strlen(zRight) + 1 );
|
||||
if( sqlite3_temp_directory==0 ){
|
||||
goto pragma_out;
|
||||
}
|
||||
sqlite3_temp_directory[0] = '\0';
|
||||
}
|
||||
}else{
|
||||
sqlite3_temp_directory = sqlite3Malloc( strlen(zRight) + 1 );
|
||||
if( sqlite3_temp_directory==0 ){
|
||||
goto pragma_out;
|
||||
}
|
||||
sqlite3_temp_directory[0] = '\0';
|
||||
}
|
||||
/* check that directory exists and is writable */
|
||||
if( sqlite3OsIsDirWritable( zRight ) ){
|
||||
strcpy(sqlite3_temp_directory, zRight);
|
||||
if( db->temp_store==1 ) {
|
||||
/* temp storage is "file", so invalidate temp */
|
||||
invalidateTempStorage( pParse );
|
||||
}
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "not a directory, or not writable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA [database.]synchronous
|
||||
** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
|
||||
|
||||
+5
-6
@@ -12,7 +12,7 @@
|
||||
** This header file defines the interface that the SQLite library
|
||||
** presents to client programs.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.125 2004/12/07 02:14:51 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.126 2004/12/20 19:01:33 tpoindex Exp $
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
@@ -1155,17 +1155,16 @@ int sqlite3_rekey(
|
||||
);
|
||||
|
||||
/*
|
||||
** If the following global variable is made to point to a constant
|
||||
** If the following global variable is made to point to a
|
||||
** string which is the name of a directory, then all temporary files
|
||||
** created by SQLite will be placed in that directory. If this variable
|
||||
** is NULL pointer, then SQLite does a search for an appropriate temporary
|
||||
** file directory.
|
||||
**
|
||||
** This variable should only be changed when there are no open databases.
|
||||
** Once sqlite3_open() has been called, this variable should not be changed
|
||||
** until all database connections are closed.
|
||||
** Once sqlite3_open() has been called, changing this variable will invalidate the
|
||||
** current temporary database, if any.
|
||||
*/
|
||||
extern const char *sqlite3_temp_directory;
|
||||
extern char *sqlite3_temp_directory;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
|
||||
Reference in New Issue
Block a user