]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change some variable names and comments in the new in-memory database file
authordrh <drh@noemail.net>
Tue, 15 Apr 2003 01:19:47 +0000 (01:19 +0000)
committerdrh <drh@noemail.net>
Tue, 15 Apr 2003 01:19:47 +0000 (01:19 +0000)
implementation.  Partial (non-working) implementation of the VACUUM command. (CVS 904)

FossilOrigin-Name: e76787f877c456abdc8bc88bfefc50eaeed68744

Makefile.in
manifest
manifest.uuid
src/build.c
src/main.c
src/pragma.c
src/sqliteInt.h
src/vacuum.c
src/vdbe.c

index ea77dbeb21fe9c80f5274cdf337a32f7883b18b9..a89204140b0041947e97264e477507bc39eae19c 100644 (file)
@@ -58,15 +58,16 @@ LIBREADLINE = @TARGET_READLINE_LIBS@
 ENCODING = @ENCODING@
 
 # Flags controlling use of the in memory btree implementation
-# INCOREDB says whether to build btree_rb.c
-# TEMPDBINCORE controls the default placement of temporary databases.
-# ALLOWATTACHMEM controls whether ATTACH DATABASE ':memory:' is supported
+#
+# SQLITE_OMIT_INMEMORYDB is defined in order to omit the in-memory
+# red/black tree driver in the file btree_rb.c
+#
+# TEMP_STORE is 0 to force temporary tables to be in a file, 1 to
+# default to file, 2 to default ot memory, and 3 to force temporary
+# tables to always be in memory.
+#
 INCOREDB = @INCOREDB@
-TEMPDBINCORE = @TEMPDBINCORE@
-ALLOWATTACHMEM = @ALLOWATTACHMEM@
-
-INCOREFLAGS = -DINCOREDB=${INCOREDB} -DTEMPDBINCORE=${TEMPDBINCORE} 
-INCOREFLAGS += -DALLOWATTACHMEM=${ALLOWATTACHMEM}
+INCOREFLAGS = -DSQLITE_OMIT_INMEMORYDB=1 -DTEMP_STORE=${INCOREDB}
 
 # You should not have to change anything below this line
 ###############################################################################
index 4f77037db43a5c1f1cacba5955f5930cf3697b99..6d758ea353705746535e3fe164b7fcb0ff328fad 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,6 +1,6 @@
-C Support\sin-memory\sdatabases\sfor\stemp\stables\s(CVS\s903)
-D 2003-04-13T18:26:49
-F Makefile.in 503590f4bdb4733d4c1f114939d68ff8a74523c6
+C Change\ssome\svariable\snames\sand\scomments\sin\sthe\snew\sin-memory\sdatabase\sfile\nimplementation.\s\sPartial\s(non-working)\simplementation\sof\sthe\sVACUUM\scommand.\s(CVS\s904)
+D 2003-04-15T01:19:48
+F Makefile.in df3a4db41a7450468b5fe934d9dd8f723b631249
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
 F VERSION e5b03976c56deafa24511d6ef17d64a28679e9bd
@@ -23,7 +23,7 @@ F src/attach.c 8c98e2c0ca434b94deca1b8694c72bd0303a9a87
 F src/auth.c f37bfc9451b8c1fa52f34adff474560018892729
 F src/btree.c 9949031b6087e9d1b43b359b84c68a491086984f
 F src/btree.h 5cb871546bd6fa58396a6f033e2b29b388241e1b
-F src/build.c 77b910f739174b0655f052ce8c1a7a0f01d3bfca
+F src/build.c daed1dacdb70e5d4def9df2e34a1cabeeb8467c9
 F src/copy.c ddd204d5dddac09d71a07f4ceded4c9926d5512b
 F src/delete.c 58d698779a6b7f819718ecd45b310a9de8537088
 F src/encode.c faf03741efe921755ec371cf4a6984536de00042
@@ -32,21 +32,21 @@ F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605
 F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f
 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
 F src/insert.c e2f5e7feecb507d904a7da48874595f440b715aa
-F src/main.c 8500dcd5dab93b201842b6688e0329c2b25c0d79
+F src/main.c daf5b7c256340fb9aa77df7254865218a47d5a63
 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
 F src/os.c c33ebb320921b8df6d09ea19fe846348df86a0c9
 F src/os.h aa52f0c9da321ff6134d19f2ca959e18e33615d0
 F src/pager.c df4c81350cbd80c1ab48341ae0768ba78d99ad49
 F src/pager.h e3702f7d384921f6cd5ce0b3ed589185433e9f6c
 F src/parse.y 3be47fa18323aa2e3364fc42bf7a6ba5b3cc0a81
-F src/pragma.c 476b13896571bc8d1049d6dbe9c9a84e6d4e33c8
+F src/pragma.c aef327bd597e15f0d31f45b042bd2797cca65039
 F src/printf.c fc5fdef6e92ad205005263661fe9716f55a49f3e
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
 F src/select.c 14e2e2a512f4edfc75fb310ebcb502ff3ee87402
 F src/shell.c 97f397c0c108176ccbc52ea5b8ec688f995eba7a
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in f49c2cdec7d24cb03e496a1ca519e16306495ee1
-F src/sqliteInt.h 3dcd08da7d9a9f85dcd67a064f1e9baa17238d3a
+F src/sqliteInt.h 048303eafaf5811a0977528756386873931cd914
 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
 F src/tclsqlite.c 7a072c3c8ba9796edc25e5ffa62b68558134e192
 F src/test1.c 7ad4e6308dde0bf5a0f0775ce20cb2ec37a328f8
@@ -57,8 +57,8 @@ F src/tokenize.c 675b4718d17c69fe7609dc8e85e426ef002be811
 F src/trigger.c bd5a5b234b47f28f9f21a46243dcaf1c5b2383a3
 F src/update.c b368369f1fbe6d7f56a53e5ffad3b75dae9e3e1a
 F src/util.c 8953c612a036e30f24c1c1f5a1498176173daa37
-F src/vacuum.c 6b9ebf0ef5761b06ce86672574c71b1e9098ef9c
-F src/vdbe.c 45d2987a5f8337d9aa0da92830fd654fb5fcd478
+F src/vacuum.c ac65e9578506a0cdf70ece2668e5b22f4895477c
+F src/vdbe.c cf9ef07b1fce5a340d8926a493f9313208f1773f
 F src/vdbe.h 985c24f312d10f9ef8f9a8b8ea62fcdf68e82f21
 F src/where.c e5733f7d5e9cc4ed3590dc3401f779e7b7bb8127
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
@@ -161,7 +161,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be
 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 73359037ea639abb066c74db9c19e84bf1104006
-R 4a0923ca1b7d3d92da7657c4b796ad95
-U paul
-Z 85c89f43ad9bfc64133f7dac4ee2ff75
+P 96336bffde6c441af197a521ee9e56fdfd7efff8
+R 502f917ded2eef9644690cdab0eeb915
+U drh
+Z 288074bf98169396dec5124561acfdbb
index 44bbc6d75e56d6e4dd8db760770bc33b3d045b85..4daf83b66ccaf538f20b621f11134a8fb4a57504 100644 (file)
@@ -1 +1 @@
-96336bffde6c441af197a521ee9e56fdfd7efff8
\ No newline at end of file
+e76787f877c456abdc8bc88bfefc50eaeed68744
\ No newline at end of file
index 9f41cbbd90403a55d029d2137abd93a6246ae8a3..6db409278d0ff09d994c3e98a9d10544d0d532fb 100644 (file)
@@ -23,7 +23,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.144 2003/04/13 18:26:51 paul Exp $
+** $Id: build.c,v 1.145 2003/04/15 01:19:48 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -436,7 +436,7 @@ void sqliteStartTable(
   ** holding temporary tables is open.
   */
   if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){
-    int rc = sqliteBtreeFactory(db, ":temp:", 0, MAX_PAGES, &db->aDb[1].pBt);
+    int rc = sqliteBtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
     if( rc!=SQLITE_OK ){
       sqliteSetString(&pParse->zErrMsg, "unable to open a temporary database "
         "file for storing temporary tables", 0);
index 211eb7012f016134076e1308873f7f38235dee8a..9eb5fb3654680dec072ba0a4819a712227782dbb 100644 (file)
@@ -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.122 2003/04/13 18:26:51 paul Exp $
+** $Id: main.c,v 1.123 2003/04/15 01:19:48 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -1057,10 +1057,31 @@ void *sqlite_commit_hook(
 }
 
 /*
-** This routine is called when sqlite wants to open a btree.  zFilename is
-** either the name of a btree file or the magic name ":memory:" which opens an
-** in-memory btree or ":temp:" which opens a temporary btree. This may either
-** be in memory or backed by a temporary file depending on run-time settings.
+** This routine is called to create a connection to a database BTree
+** driver.  If zFilename is the name of a file, then that file is
+** opened and used.  If zFilename is the magic name ":memory:" then
+** the database is stored in memory (and is thus forgotten as soon as
+** the connection is closed.)  If zFilename is NULL then the database
+** is for temporary use only and is deleted as soon as the connection
+** is closed.
+**
+** 
+**
+** A temporary database can be either a disk file (that is automatically
+** deleted when the file is closed) or a set of red-black trees held in memory,
+** depending on the values of the TEMP_STORE compile-time macro and the
+** db->temp_store variable, according to the following chart:
+**
+**       TEMP_STORE     db->temp_store     Location of temporary database
+**       ----------     --------------     ------------------------------
+**           0               any             file
+**           1                1              file
+**           1                2              memory
+**           1                0              file
+**           2                1              file
+**           2                2              memory
+**           2                0              memory
+**           3               any             memory
 */
 int sqliteBtreeFactory(
   const sqlite *db,        /* Main database when opening aux otherwise 0 */
@@ -1069,22 +1090,16 @@ int sqliteBtreeFactory(
   int nCache,               /* How many pages in the page cache */
   Btree **ppBtree){         /* Pointer to new Btree object written here */
 
-  assert( zFilename != 0 );
   assert( ppBtree != 0);
 
-  if (strcmp(zFilename, ":memory:") == 0) {
-    if (ALLOWATTACHMEM) {
-      return sqliteRBtreeOpen(0, 0, 0, ppBtree);
-    } else {
-      return SQLITE_CANTOPEN;
-    }
-  } else if (strcmp(zFilename, ":temp:") == 0) {
-    if (TEMPDBINCORE == 0) {
+#ifndef SQLITE_OMIT_INMEMORYDB
+  if( zFilename==0 ){
+    if (TEMP_STORE == 0) {
       /* Always use file based temporary DB */
       return sqliteBtreeOpen(0, omitJournal, nCache, ppBtree);
-    } else if (TEMPDBINCORE == 1 || TEMPDBINCORE == 2) {
+    } else if (TEMP_STORE == 1 || TEMP_STORE == 2) {
       /* Switch depending on compile-time and/or runtime settings. */
-      int location = db->tmpdb_loc == 0 ? TEMPDBINCORE : db->tmpdb_loc;
+      int location = db->temp_store==0 ? TEMP_STORE : db->temp_store;
 
       if (location == 1) {
         return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
@@ -1095,7 +1110,11 @@ int sqliteBtreeFactory(
       /* Always use in-core DB */
       return sqliteRBtreeOpen(0, 0, 0, ppBtree);
     }
-  } else {
+  }else if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
+    return sqliteRBtreeOpen(0, 0, 0, ppBtree);
+  }else
+#endif
+  {
     return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
   }
 }
index f3f7b62dad9f1675ec876182b33bbe919f2a1f07..1466cc1b648f45171588dfc7d96a2c09a8f0eccf 100644 (file)
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.2 2003/04/13 18:26:51 paul Exp $
+** $Id: pragma.c,v 1.3 2003/04/15 01:19:49 drh Exp $
 */
 #include "sqliteInt.h"
+#include <ctype.h>
 
 /*
 ** Interpret the given string as a boolean value.
@@ -69,14 +70,14 @@ static int getSafetyLevel(char *z){
 ** backed temporary databases, 2 for the Red-Black tree in memory database
 ** and 0 to use the compile-time default.
 */
-static int getTmpdbLocation(char *z){
-    if (sqliteStrICmp(z, "file") == 0) {
-       return 1;
-    } else if (sqliteStrICmp(z, "memory") == 0) {
-       return 2;
-    } else {
-       return 0;
-    }
+static int getTempStore(char *z){
+  if (sqliteStrICmp(z, "file") == 0) {
+    return 1;
+  }else if(sqliteStrICmp(z, "memory") == 0) {
+    return 2;
+  }else{
+    return 0;
+  }
 }
 
 /*
@@ -439,56 +440,59 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     }
   }else
   /*
-  **   PRAGMA tmpdb_location
-  **   PRAGMA tmpdb_location= DEFAULT|MEMORY|FILE
+  **   PRAGMA temp_store
+  **   PRAGMA temp_store = "default"|"memory"|"file"
   **
-  ** Return or set the local value of the tmpdb_location flag.  Changing
+  ** Return or set the local value of the temp_store flag.  Changing
   ** the local value does not make changes to the disk file and the default
   ** value will be restored the next time the database is opened.
   **
   ** Note that it is possible for the library compile-time options to
   ** override this setting
   */
-  if( sqliteStrICmp(zLeft, "tmpdb_location")==0 ){
+  if( sqliteStrICmp(zLeft, "temp_store")==0 ){
     static VdbeOp getTmpDbLoc[] = {
-      { OP_ColumnName,  0, 0,        "tmpdb_location"},
+      { OP_ColumnName,  0, 0,        "temp_store"},
       { OP_Callback,    1, 0,        0},
     };
     if( pRight->z==pLeft->z ){
-      sqliteVdbeAddOp(v, OP_Integer, db->tmpdb_loc, 0);
+      sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
       sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
     }else{
       if (&db->aDb[1].pBt != 0) {
-       sqliteErrorMsg(pParse, "The temporary database already exists, its location cannot now be changed");
+       sqliteErrorMsg(pParse, "The temporary database already exists - "
+          "its location cannot now be changed");
       } else {
-       db->tmpdb_loc = getTmpdbLocation(zRight);
+       db->temp_store = getTempStore(zRight);
       }
     }
   }else
+
   /*
-  **   PRAGMA default_tmpdb_location
-  **   PRAGMA default_tmpdb_location= DEFAULT|MEMORY|FILE
+  **   PRAGMA default_temp_store
+  **   PRAGMA default_temp_store = "default"|"memory"|"file"
   **
-  ** Return or set the value of the persistent tmpdb_location flag (as
+  ** Return or set the value of the persistent temp_store flag (as
   ** well as the value currently in force).
   **
   ** Note that it is possible for the library compile-time options to
   ** override this setting
   */
-  if( sqliteStrICmp(zLeft, "default_tmpdb_location")==0 ){
+  if( sqliteStrICmp(zLeft, "default_temp_store")==0 ){
     static VdbeOp getTmpDbLoc[] = {
-      { OP_ColumnName,  0, 0,        "tmpdb_location"},
+      { OP_ColumnName,  0, 0,        "temp_store"},
       { OP_ReadCookie,  0, 5,        0},
       { OP_Callback,    1, 0,        0}};
     if( pRight->z==pLeft->z ){
       sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
     }else{
       if (&db->aDb[1].pBt != 0) {
-       sqliteErrorMsg(pParse, "The temporary database already exists, its location cannot now be changed");
+       sqliteErrorMsg(pParse, "The temporary database already exists - "
+            "its location cannot now be changed");
       } else {
        sqliteBeginWriteOperation(pParse, 0, 0);
-       db->tmpdb_loc = getTmpdbLocation(zRight);
-       sqliteVdbeAddOp(v, OP_Integer, db->tmpdb_loc, 0);
+       db->temp_store = getTempStore(zRight);
+       sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
        sqliteVdbeAddOp(v, OP_SetCookie, 0, 5);
        sqliteEndWriteOperation(pParse);
       }
index 838da3a3bf311f65ecc14c885b88ca4ea273f5cf..fe3743a0152ad5a47b828e324659a446bb02179c 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.171 2003/04/13 18:26:52 paul Exp $
+** @(#) $Id: sqliteInt.h,v 1.172 2003/04/15 01:19:49 drh Exp $
 */
 #include "config.h"
 #include "sqlite.h"
 */
 #define MAX_ATTACHED 10
 
+/*
+** The next macro is used to determine where TEMP tables and indices
+** are stored.  Possible values:
+**
+**   0    Always use a temporary files
+**   1    Use a file unless overridden by "PRAGMA temp_store"
+**   2    Use memory unless overridden by "PRAGMA temp_store"
+**   3    Always use memory
+*/
+#ifndef TEMP_STORE
+# define TEMP_STORE 1
+#endif
+
+/*
+** When building SQLite for embedded systems where memory is scarce,
+** you can define one or more of the following macros to omit extra
+** features of the library and thus keep the size of the library to
+** a minimum.
+*/
+/* #define SQLITE_OMIT_AUTHORIZATION  1 */
+#define SQLITE_OMIT_INMEMORYDB     1
+/* #define SQLITE_OMIT_TRACE          1 */
+/* #define SQLITE_OMIT_VACUUM         1 */
+
 /*
 ** Integers of known sizes.  These typedefs might change for architectures
 ** where the sizes very.  Preprocessor macros are available so that the
@@ -230,6 +254,11 @@ struct Db {
 **     file_format==3    Version 2.6.0. Fix empty-string index bug.
 **     file_format==4    Version 2.7.0. Add support for separate numeric and
 **                       text datatypes.
+**
+** The sqlite.temp_store determines where temporary database files
+** are stored.  If 1, then a file is created to hold those tables.  If
+** 2, then they are held in memory.  0 means use the default value in
+** the TEMP_STORE macro.
 */
 struct sqlite {
   int nDb;                      /* Number of backends currently in use */
@@ -241,7 +270,7 @@ struct sqlite {
   u8 want_to_close;             /* Close after all VDBEs are deallocated */
   int next_cookie;              /* Next value of aDb[0].schema_cookie */
   int cache_size;               /* Number of pages to use in the cache */
-  int tmpdb_loc;                /* Temp DB loc */
+  int temp_store;               /* 1=file, 2=memory, 0=compile-time default */
   int nTable;                   /* Number of tables in the database */
   void *pBusyArg;               /* 1st Argument to the busy callback */
   int (*xBusyCallback)(void *,const char*,int);  /* The busy callback */
index cb8b404e8365b1dfb23a6cbd1c708a8f06714886..dc8cd1edf3bda7ea438f027a76569c7123839d6b 100644 (file)
 ** Most of the code in this file may be omitted by defining the
 ** SQLITE_OMIT_VACUUM macro.
 **
-** $Id: vacuum.c,v 1.1 2003/04/06 21:08:24 drh Exp $
+** $Id: vacuum.c,v 1.2 2003/04/15 01:19:49 drh Exp $
 */
 #include "sqliteInt.h"
 
+#define SQLITE_OMIT_VACUUM 1
+
+/*
+** A structure for holding a dynamic string - a string that can grow
+** without bound.
+*/
+typedef struct dynStr dynStr;
+struct dynStr {
+  char *z;        /* Text of the string in space obtained from sqliteMalloc() */
+  int nAlloc;     /* Amount of space allocated to z[] */
+  int nUsed;      /* Next unused slot in z[] */
+};
+
+#ifndef SQLITE_OMIT_VACUUM
+/*
+** Append text to a dynamic string
+*/
+static void appendText(dynStr *p, const char *zText, int nText){
+  if( nText<0 ) nText = strlen(zText);
+  if( p->z==0 || p->nUsed + nText + 1 >= p->nAlloc ){
+    char *zNew;
+    p->nAlloc = p->nUsed + nText + 1000;
+    zNew = sqliteRealloc(p->z, p->nAlloc);
+    if( zNew==0 ){
+      sqliteFree(p->z);
+      memset(p, 0, sizeof(*p));
+      return;
+    }
+    p->z = zNew;
+  }
+  memcpy(&p->z[p->nUsed], zText, nText+1);
+  p->nUsed += nText;
+}
+
+/*
+** Append text to a dynamic string, having first put the text in quotes.
+*/
+static void appendQuoted(dynStr *p, const char *zText){
+  int i, j;
+  appendText(p, "'", 1);
+  for(i=j=0; zText[i]; i++){
+    if( zText[i]='\'' ){
+      appendText(p, &zText[j], i-j+1);
+      j = i + 1;
+      appendText(p, "'", 1);
+    }
+  }
+  if( j<i ){
+    appendText(p, &zText[j], i-j);
+  }
+  appendText(p, "'", 1);
+}
+
+/*
+** This is an SQLite callback that is invoked once for each row in
+** the SQLITE_MASTER table of the database being vacuumed.  The three
+** parameters are the type of entry, the name of the entry, and the SQL
+** text for the entry.
+**
+** Append SQL text to the dynStr that will make a copy of the structure
+** identified by this row.
+*/
+static int vacuumCallback(void *pArg, int argc, char **argv, char **NotUsed){
+  dynStr *p = (dynStr*)pArg;
+  assert( argc==3 );
+  assert( argv[0]!=0 );
+  assert( argv[1]!=0 );
+  assert( argv[2]!=0 );
+  appendText(p, argv[2], -1);
+  appendText(p, ";\n", 2);
+  if( strcmp(argv[0],"table")==0 ){
+    appendText(p, "INSERT INTO ", -1);
+    appendQuoted(p, argv[1]);
+    appendText(p, " SELECT * FROM ", -1);
+    appendQuoted(p, argv[1]);
+    appendText(p, ";\n");
+  }
+  return 0;
+}
+
+/*
+** Generate a random name of 20 character in length.
+*/
+static void randomName(char *zBuf){
+  static const char zChars[] =
+    "abcdefghijklmnopqrstuvwxyz"
+    "0123456789";
+  int i;
+  for(i=0; i<20; i++){
+    int n = sqliteRandomByte() % (sizeof(zChars)-1);
+    zBuf[i] = zChars[n];
+  }
+}
+#endif
 
 /*
 ** The non-standard VACUUM command is used to clean up the database,
 */
 void sqliteVacuum(Parse *pParse, Token *pTableName){
 #ifndef SQLITE_OMIT_VACUUM
-  /* Do nothing */
+  const char *zFilename;  /* full pathname of the database file */
+  int nFilename;          /* number of characters  in zFilename[] */
+  char *zTemp = 0;        /* a temporary file in same directory as zFilename */
+  char *zTemp2;           /* Another temp file in the same directory */
+  sqlite *dbNew = 0;      /* The new vacuumed database */
+  sqlite *dbOld = 0;      /* Alternative connection to original database */
+  sqlite *db;             /* The original database */
+  int rc;
+  char *zErrMsg = 0;
+  char *zSql = 0;
+  dynStr sStr;
+
+  /* Initial error checks
+  */
+  if( pParse->explain ){
+    return;
+  }
+  db = pParse->db;
+  if( db->flags & SQLITE_InTrans ){
+    sqliteErrorMsg(pParse, "cannot VACUUM from within a transaction");
+    return;
+  }
+  memset(&sStr, 0, sizeof(sStr));
+
+  /* Get the full pathname of the database file and create two
+  ** temporary filenames in the same directory as the original file.
+  */
+  zFilename = sqliteBtreeGetFilename(db->aDb[0].pBt);
+  if( zFilename==0 ){
+    /* This only happens with the in-memory database.  VACUUM is a no-op
+    ** there, so just return */
+    return;
+  }
+  nFilename = strlen(zFilename);
+  zTemp = sqliteMalloc( 2*(nFilename+40) );
+  if( zTemp==0 ) return;
+  zTemp2 = &zTemp[nFilename+40];
+  strcpy(zTemp, zFilename);
+  strcpy(zTemp2, zFilename);
+  for(i=0; i<10; i++){
+    zTemp[nFilename] = '-';
+    randomName(&zTemp[nFilename+1]);
+    randomName(&zTemp2[nFilename+1]);
+    if( !sqliteOsFileExists(zTemp) && !sqliteOsFileExists(zTemp2) ) break;
+  }
+  if( i>=10 ){
+    sqliteErrorMsg(pParse, "unable to create a temporary database files "
+       "in the same directory as the original database");
+    goto end_of_vacuum;
+  }
+
+  
+  dbNew = sqlite_open(zTemp, 0, &zErrMsg);
+  if( dbNew==0 ){
+    sqliteErrorMsg(pParse, "unable to open a temporary database at %s - %s",
+       zTemp, zErrMsg);
+    goto end_of_vacuum;
+  }
+  appendText(&sStr, "ATTACH DATABASE ", -1);
+  appendQuoted(&sStr, zFilename);
+  appendText(&sStr, " AS orig;\nBEGIN;\n", -1);
+  if( execsql(pParse, dbNew, sStr.z) ) goto end_of_vacuum;
+  sStr.nUsed = 0;
+  rc = sqlite_exec(dbNew, "SELECT type, name, sql FROM sqlite_master "
+           "WHERE sql NOT NULL", vacuumCallback, &sStr, &zErrMsg);
+  if( rc ){
+    sqliteErrorMsg(pParse, "unable to vacuum database - %s", zErrMsg);
+    goto end_of_vacuum;
+  }
+  appendText(&sStr, "COMMIT;\n", -1);
+  if( execsql(pParse, dbNew, sStr.z) ) goto end_of_vacuum;
+
+
+  
+end_of_vacuum:
+  sqliteFree(zTemp);
+  sqliteFree(zSql);
+  sqliteFree(sStr.z);
+  if( zErrMsg ) sqlite_freemem(zErrMsg);
+  if( dbNew ) sqlite_close(dbNew);
 #endif
 }
index 7579255ea7b4d30fc8d6ff6c265586fa9bb7a139..c160dacd5fe2fc3d8799732337458e1c7e1d0e50 100644 (file)
@@ -36,7 +36,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.212 2003/04/13 18:26:52 paul Exp $
+** $Id: vdbe.c,v 1.213 2003/04/15 01:19:49 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -3503,7 +3503,7 @@ case OP_OpenTemp: {
   cleanupCursor(pCx);
   memset(pCx, 0, sizeof(*pCx));
   pCx->nullRow = 1;
-  rc = sqliteBtreeFactory(db, ":temp:", 1, TEMP_PAGES, &pCx->pBt);
+  rc = sqliteBtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
 
   if( rc==SQLITE_OK ){
     rc = sqliteBtreeBeginTrans(pCx->pBt);