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:
@ -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)))
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
57
src/vacuum.c
57
src/vacuum.c
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user