mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Change some variable names and comments in the new in-memory database file
implementation. Partial (non-working) implementation of the VACUUM command. (CVS 904) FossilOrigin-Name: e76787f877c456abdc8bc88bfefc50eaeed68744
This commit is contained in:
17
Makefile.in
17
Makefile.in
@@ -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
|
||||
###############################################################################
|
||||
|
26
manifest
26
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
|
||||
|
@@ -1 +1 @@
|
||||
96336bffde6c441af197a521ee9e56fdfd7efff8
|
||||
e76787f877c456abdc8bc88bfefc50eaeed68744
|
@@ -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);
|
||||
|
53
src/main.c
53
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.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);
|
||||
}
|
||||
}
|
||||
|
44
src/pragma.c
44
src/pragma.c
@@ -11,9 +11,10 @@
|
||||
*************************************************************************
|
||||
** 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,12 +70,12 @@ 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){
|
||||
static int getTempStore(char *z){
|
||||
if (sqliteStrICmp(z, "file") == 0) {
|
||||
return 1;
|
||||
} else if (sqliteStrICmp(z, "memory") == 0) {
|
||||
}else if(sqliteStrICmp(z, "memory") == 0) {
|
||||
return 2;
|
||||
} else {
|
||||
}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);
|
||||
}
|
||||
|
@@ -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"
|
||||
@@ -65,6 +65,30 @@
|
||||
*/
|
||||
#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 */
|
||||
|
177
src/vacuum.c
177
src/vacuum.c
@@ -14,10 +14,104 @@
|
||||
** 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,
|
||||
@@ -31,6 +125,85 @@
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user