diff options
author | drh <drh@noemail.net> | 2002-06-25 19:31:18 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2002-06-25 19:31:18 +0000 |
commit | 411995dc0d1611c8aa2a00c48d0c9cf756a34d98 (patch) | |
tree | acc44ba6a738483663ba7552cfab191af4a10ab7 /src | |
parent | e3c163e4e0dcde351a1cebd88b890ade51cfa9b7 (diff) | |
download | sqlite-411995dc0d1611c8aa2a00c48d0c9cf756a34d98.tar.gz sqlite-411995dc0d1611c8aa2a00c48d0c9cf756a34d98.zip |
Add the sqlite_open_aux_file() API. (CVS 646)
FossilOrigin-Name: 332164d6455658ca633a1dc49811d9fb0fd4b01c
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 46 | ||||
-rw-r--r-- | src/shell.c | 12 | ||||
-rw-r--r-- | src/sqlite.h.in | 10 | ||||
-rw-r--r-- | src/tclsqlite.c | 48 |
4 files changed, 103 insertions, 13 deletions
diff --git a/src/main.c b/src/main.c index e6877b38f..ee79bfdb9 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.84 2002/06/25 01:09:11 drh Exp $ +** $Id: main.c,v 1.85 2002/06/25 19:31:18 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -710,7 +710,9 @@ int sqlite_create_aggregate( } /* -** Change the datatype for all functions with a given name. +** Change the datatype for all functions with a given name. See the +** header comment for the prototype of this function in sqlite.h for +** additional information. */ int sqlite_function_type(sqlite *db, const char *zName, int dataType){ FuncDef *p = (FuncDef*)sqliteHashFind(&db->aFunc, zName, strlen(zName)); @@ -720,3 +722,43 @@ int sqlite_function_type(sqlite *db, const char *zName, int dataType){ } return SQLITE_OK; } + +/* +** Attempt to open the file named in the argument as the auxiliary database +** file. The auxiliary database file is used to store TEMP tables. But +** by using this API, it is possible to trick SQLite into opening two +** separate databases and acting on them as if they were one. +** +** This routine closes the existing auxiliary database file, which will +** cause any previously created TEMP tables to be created. +** +** The zName parameter can be a NULL pointer or an empty string to cause +** a temporary file to be opened and automatically deleted when closed. +*/ +int sqlite_open_aux_file(sqlite *db, const char *zName, char **pzErrMsg){ + int rc; + if( zName && zName[0]==0 ) zName = 0; + if( sqliteSafetyOn(db) ) goto openaux_misuse; + sqliteResetInternalSchema(db); + if( db->pBeTemp!=0 ){ + sqliteBtreeClose(db->pBeTemp); + } + rc = sqliteBtreeOpen(zName, 0, MAX_PAGES, &db->pBeTemp); + if( rc ){ + if( zName==0 ) zName = "a temporary file"; + sqliteSetString(pzErrMsg, "unable to open ", zName, + ": ", sqlite_error_string(rc), 0); + sqliteStrRealloc(pzErrMsg); + sqliteSafetyOff(db); + return rc; + } + rc = sqliteInit(db, pzErrMsg); + if( sqliteSafetyOff(db) ) goto openaux_misuse; + sqliteStrRealloc(pzErrMsg); + return rc; + +openaux_misuse: + sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0); + sqliteStrRealloc(pzErrMsg); + return SQLITE_MISUSE; +} diff --git a/src/shell.c b/src/shell.c index d8ee2108e..a3c94bf67 100644 --- a/src/shell.c +++ b/src/shell.c @@ -12,7 +12,7 @@ ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** -** $Id: shell.c,v 1.58 2002/06/25 01:09:12 drh Exp $ +** $Id: shell.c,v 1.59 2002/06/25 19:31:18 drh Exp $ */ #include <stdlib.h> #include <string.h> @@ -486,6 +486,7 @@ static char zHelp[] = " \"insert\", \"list\", or \"html\"\n" ".mode insert TABLE Generate SQL insert statements for TABLE\n" ".nullvalue STRING Print STRING instead of nothing for NULL data\n" + ".openaux FILENAME Use FILENAME to hold TEMP tables\n" ".output FILENAME Send output to FILENAME\n" ".output stdout Send output to the screen\n" ".prompt MAIN CONTINUE Replace the standard prompts\n" @@ -702,6 +703,15 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ sprintf(p->nullvalue, "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); }else + if( c=='o' && strncmp(azArg[0], "openaux", n)==0 ){ + char *zErrMsg = 0; + sqlite_open_aux_file(db, nArg>=2 ? azArg[1] : 0, &zErrMsg); + if( zErrMsg ){ + fprintf(stderr,"Error: %s\n", zErrMsg); + free(zErrMsg); + } + }else + if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){ if( p->out!=stdout ){ fclose(p->out); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 5d7d52c1f..f14e06ff4 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.32 2002/06/20 11:36:50 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.33 2002/06/25 19:31:18 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ @@ -496,6 +496,14 @@ void *sqlite_aggregate_context(sqlite_func*, int nBytes); */ int sqlite_aggregate_count(sqlite_func*); +/* +** Attempt to open the file named in the argument as the auxiliary database +** file. The auxiliary database file is used to store TEMP tables. But +** by using this API, it is possible to trick SQLite into opening two +** separate databases and acting on them as if they were one. +*/ +int sqlite_open_aux_file(sqlite *db, const char *zName, char **pzErrMsg); + #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 7df3f7741..c613e8a60 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -11,7 +11,7 @@ ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.32 2002/05/10 13:14:07 drh Exp $ +** $Id: tclsqlite.c,v 1.33 2002/06/25 19:31:18 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ @@ -267,24 +267,26 @@ static int DbBusyHandler(void *cd, const char *zTable, int nTries){ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ SqliteDb *pDb = (SqliteDb*)cd; int choice; - static char *DB_optStrs[] = { - "busy", "changes", "close", "complete", - "eval", "last_insert_rowid", "timeout", 0 + static char *DB_strs[] = { + "busy", "changes", "close", + "complete", "eval", "last_insert_rowid", + "open_aux_file", "timeout", 0 }; - enum DB_opts { - DB_BUSY, DB_CHANGES, DB_CLOSE, DB_COMPLETE, - DB_EVAL, DB_LAST_INSERT_ROWID, DB_TIMEOUT + enum DB_enum { + DB_BUSY, DB_CHANGES, DB_CLOSE, + DB_COMPLETE, DB_EVAL, DB_LAST_INSERT_ROWID, + DB_OPEN_AUX_FILE, DB_TIMEOUT, }; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); return TCL_ERROR; } - if( Tcl_GetIndexFromObj(interp, objv[1], DB_optStrs, "option", 0, &choice) ){ + if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){ return TCL_ERROR; } - switch( (enum DB_opts)choice ){ + switch( (enum DB_enum)choice ){ /* $db busy ?CALLBACK? ** @@ -464,6 +466,34 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } /* + ** $db open_aux_file FILENAME + ** + ** Begin using FILENAME as the database file used to store temporary + ** tables. + */ + case DB_OPEN_AUX_FILE: { + const char *zFilename; + char *zErrMsg = 0; + int rc; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 2, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetStringFromObj(objv[2], 0); + rc = sqlite_open_aux_file(pDb->db, zFilename, &zErrMsg); + if( rc!=0 ){ + if( zErrMsg ){ + Tcl_AppendResult(interp, zErrMsg, 0); + free(zErrMsg); + }else{ + Tcl_AppendResult(interp, sqlite_error_string(rc), 0); + } + return TCL_ERROR; + } + break; + } + + /* ** $db timeout MILLESECONDS ** ** Delay for the number of milliseconds specified when a file is locked. |