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:
tpoindex
2004-12-20 19:01:32 +00:00
parent 9012bcbc0a
commit 9a09a3caed
11 changed files with 270 additions and 34 deletions
+1
View File
@@ -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);
+16
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */