1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Get VACUUM working again - with test cases. Some other minor cleanups. (CVS 931)

FossilOrigin-Name: 5afb88008fed253e6d1fc0ed5172370b61d3727b
This commit is contained in:
drh
2003-04-25 02:43:08 +00:00
parent 5cf590c128
commit 45a304ee8c
7 changed files with 150 additions and 27 deletions

View File

@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.31 2003/04/16 01:28:16 drh Exp $
** @(#) $Id: btree.h,v 1.32 2003/04/25 02:43:08 drh Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
@ -95,6 +95,7 @@ struct BtCursorOps {
#define SQLITE_N_BTREE_META 10
int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree);
int sqliteRBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree);
#define btOps(pBt) (*((BtOps **)(pBt)))
#define btCOps(pCur) (*((BtCursorOps **)(pCur)))

View File

@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree_rb.c,v 1.7 2003/04/24 01:45:04 drh Exp $
** $Id: btree_rb.c,v 1.8 2003/04/25 02:43:08 drh Exp $
**
** This file implements an in-core database using Red-Black balanced
** binary trees.
@ -1327,7 +1327,7 @@ static struct Pager *memBtreePager(Btree* tree)
** Return the full pathname of the underlying database file.
*/
static const char *memBtreeGetFilename(Btree *pBt){
return ":memory:";
return 0; /* A NULL return indicates there is no underlying file */
}
/*

View File

@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.4 2003/04/22 20:30:39 drh Exp $
** $Id: pragma.c,v 1.5 2003/04/25 02:43:08 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -71,9 +71,11 @@ static int getSafetyLevel(char *z){
** and 0 to use the compile-time default.
*/
static int getTempStore(char *z){
if (sqliteStrICmp(z, "file") == 0) {
if( z[0]>='0' || z[0]<='2' ){
return z[0] - '0';
}else if( sqliteStrICmp(z, "file")==0 ){
return 1;
}else if(sqliteStrICmp(z, "memory") == 0) {
}else if( sqliteStrICmp(z, "memory")==0 ){
return 2;
}else{
return 0;

View File

@ -14,7 +14,7 @@
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.3 2003/04/18 02:31:04 drh Exp $
** $Id: vacuum.c,v 1.4 2003/04/25 02:43:08 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -41,6 +41,7 @@ struct vacuumStruct {
sqlite *dbNew; /* New database */
Parse *pParse; /* The parser context */
const char *zTable; /* Name of a table being copied */
const char *zPragma; /* Pragma to execute with results */
dynStr s1, s2; /* Two dynamic strings */
};
@ -160,6 +161,24 @@ static int vacuumCallback1(void *pArg, int argc, char **argv, char **NotUsed){
return rc;
}
/*
** This callback is used to transfer PRAGMA settings from one database
** to the other. The value in argv[0] should be passed to a pragma
** identified by ((vacuumStruct*)pArg)->zPragma.
*/
static int vacuumCallback3(void *pArg, int argc, char **argv, char **NotUsed){
vacuumStruct *p = (vacuumStruct*)pArg;
int rc = 0;
char zBuf[200];
assert( argc==1 );
assert( argv[0]!=0 );
assert( strlen(p->zPragma)<100 );
assert( strlen(argv[0])<30 );
sprintf(zBuf,"PRAGMA %s=%s;", p->zPragma, argv[0]);
rc = execsql(p->pParse, p->dbNew, zBuf);
return rc;
}
/*
** Generate a random name of 20 character in length.
*/
@ -199,6 +218,14 @@ void sqliteVacuum(Parse *pParse, Token *pTableName){
int safety = 0;
vacuumStruct sVac;
/* These are all of the pragmas that need to be transferred over
** to the new database */
static const char *zPragma[] = {
"default_synchronous",
"default_cache_size",
/* "default_temp_store", */
};
/* Initial error checks
*/
if( pParse->explain ){
@ -256,14 +283,17 @@ void sqliteVacuum(Parse *pParse, Token *pTableName){
sVac.dbOld = db;
sVac.dbNew = dbNew;
sVac.pParse = pParse;
for(i=0; i<sizeof(zPragma)/sizeof(zPragma[0]); i++){
char zBuf[200];
assert( strlen(zPragma[i])<100 );
sprintf(zBuf, "PRAGMA %s;", zPragma[i]);
sVac.zPragma = zPragma[i];
rc = sqlite_exec(db, zBuf, vacuumCallback3, &sVac, &zErrMsg);
if( rc ) goto vacuum_error;
}
rc = sqlite_exec(db, "SELECT type, name, sql FROM sqlite_master "
"WHERE sql NOT NULL", vacuumCallback1, &sVac, &zErrMsg);
if( rc ){
if( pParse->zErrMsg==0 ){
sqliteErrorMsg(pParse, "unable to vacuum database - %s", zErrMsg);
}
goto end_of_vacuum;
}
if( rc ) goto vacuum_error;
if( sqliteOsFileRename(zFilename, zTemp2) ){
sqliteErrorMsg(pParse, "unable to rename database file");
@ -285,6 +315,12 @@ void sqliteVacuum(Parse *pParse, Token *pTableName){
if( sqliteOsDelete(zTemp2) ){
sqliteErrorMsg(pParse, "unable to delete old database: %s", zTemp2);
}
sqliteBtreeClose(db->aDb[0].pBt);
zTemp2[nFilename] = 0;
if( sqliteBtreeOpen(zTemp2, 0, MAX_PAGES, &db->aDb[0].pBt) ){
sqliteErrorMsg(pParse, "unable to reopen database after vacuuming");
}
sqliteResetInternalSchema(db, 0);
end_of_vacuum:
sqlite_exec(db, "COMMIT", 0, 0, 0);
@ -298,5 +334,12 @@ end_of_vacuum:
sqliteFree(sVac.s1.z);
sqliteFree(sVac.s2.z);
if( zErrMsg ) sqlite_freemem(zErrMsg);
return;
vacuum_error:
if( pParse->zErrMsg==0 ){
sqliteErrorMsg(pParse, "unable to vacuum database - %s", zErrMsg);
}
goto end_of_vacuum;
#endif
}