aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2002-06-25 19:31:18 +0000
committerdrh <drh@noemail.net>2002-06-25 19:31:18 +0000
commit411995dc0d1611c8aa2a00c48d0c9cf756a34d98 (patch)
treeacc44ba6a738483663ba7552cfab191af4a10ab7 /src
parente3c163e4e0dcde351a1cebd88b890ade51cfa9b7 (diff)
downloadsqlite-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.c46
-rw-r--r--src/shell.c12
-rw-r--r--src/sqlite.h.in10
-rw-r--r--src/tclsqlite.c48
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.