diff options
| author | Wez Furlong <wez@php.net> | 2005-02-27 05:20:19 +0000 |
|---|---|---|
| committer | Wez Furlong <wez@php.net> | 2005-02-27 05:20:19 +0000 |
| commit | ae5649598dcbb3b3b105344452c782bf0f289739 (patch) | |
| tree | e03893cec670b02478808f8913d6b4148455ec2c /ext/pdo_sqlite/sqlite/src/vacuum.c | |
| parent | 58f61a16eea562cfed04c19cc319a608b2e9f345 (diff) | |
| download | php-git-ae5649598dcbb3b3b105344452c782bf0f289739.tar.gz | |
upgrade bundled sqlite to sqlite 3.1.3
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/vacuum.c')
| -rw-r--r-- | ext/pdo_sqlite/sqlite/src/vacuum.c | 86 |
1 files changed, 62 insertions, 24 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/vacuum.c b/ext/pdo_sqlite/sqlite/src/vacuum.c index 371a855770..ed418b0ff6 100644 --- a/ext/pdo_sqlite/sqlite/src/vacuum.c +++ b/ext/pdo_sqlite/sqlite/src/vacuum.c @@ -19,7 +19,7 @@ #include "sqliteInt.h" #include "os.h" -#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM +#ifndef SQLITE_OMIT_VACUUM /* ** Generate a random name of 20 character in length. */ @@ -93,11 +93,10 @@ void sqlite3Vacuum(Parse *pParse, Token *pTableName){ */ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ int rc = SQLITE_OK; /* Return code from service routines */ -#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM +#ifndef SQLITE_OMIT_VACUUM 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 */ - int i; /* Loop counter */ Btree *pMain; /* The database being vacuumed */ Btree *pTemp; char *zSql = 0; @@ -129,11 +128,19 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ goto end_of_vacuum; } strcpy(zTemp, zFilename); - i = 0; + + /* The randomName() procedure in the following loop uses an excellent + ** source of randomness to generate a name from a space of 1.3e+31 + ** possibilities. So unless the directory already contains on the order + ** of 1.3e+31 files, the probability that the following loop will + ** run more than once or twice is vanishingly small. We are certain + ** enough that this loop will always terminate (and terminate quickly) + ** that we don't even bother to set a maximum loop count. + */ do { zTemp[nFilename] = '-'; randomName((unsigned char*)&zTemp[nFilename+1]); - } while( i<10 && sqlite3OsFileExists(zTemp) ); + } while( sqlite3OsFileExists(zTemp) ); /* Attach the temporary database as 'vacuum_db'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash @@ -159,6 +166,10 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) ); execSql(db, "PRAGMA vacuum_db.synchronous=OFF"); +#ifndef SQLITE_OMIT_AUTOVACUUM + sqlite3BtreeSetAutoVacuum(pTemp, sqlite3BtreeGetAutoVacuum(pMain)); +#endif + /* Begin a transaction */ rc = execSql(db, "BEGIN;"); if( rc!=SQLITE_OK ) goto end_of_vacuum; @@ -168,14 +179,17 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ */ rc = execExecSql(db, "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) " - " FROM sqlite_master WHERE type='table' " - "UNION ALL " - "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14,100000000) " - " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' " - "UNION ALL " + " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execExecSql(db, + "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14,100000000)" + " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' "); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execExecSql(db, "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21,100000000) " - " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'" - "UNION ALL " + " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execExecSql(db, "SELECT 'CREATE VIEW vacuum_db.' || substr(sql,13,100000000) " " FROM sqlite_master WHERE type='view'" ); @@ -189,9 +203,24 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ "SELECT 'INSERT INTO vacuum_db.' || quote(name) " "|| ' SELECT * FROM ' || quote(name) || ';'" "FROM sqlite_master " - "WHERE type = 'table';" + "WHERE type = 'table' AND name!='sqlite_sequence';" + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Copy over the sequence table + */ + rc = execExecSql(db, + "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' " + "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' " ); if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execExecSql(db, + "SELECT 'INSERT INTO vacuum_db.' || quote(name) " + "|| ' SELECT * FROM ' || quote(name) || ';' " + "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';" + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + /* Copy the triggers from the main database to the temporary database. ** This was deferred before in case the triggers interfered with copying @@ -215,22 +244,31 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ */ if( sqlite3BtreeIsInTrans(pTemp) ){ u32 meta; + int i; + + /* This array determines which meta meta values are preserved in the + ** vacuum. Even entries are the meta value number and odd entries + ** are an increment to apply to the meta value after the vacuum. + ** The increment is used to increase the schema cookie so that other + ** connections to the same database will know to reread the schema. + */ + static const unsigned char aCopy[] = { + 1, 1, /* Add one to the old schema cookie */ + 3, 0, /* Preserve the default page cache size */ + 5, 0, /* Preserve the default text encoding */ + 6, 0, /* Preserve the user version */ + }; assert( 0==sqlite3BtreeIsInTrans(pMain) ); rc = sqlite3BtreeBeginTrans(pMain, 1); if( rc!=SQLITE_OK ) goto end_of_vacuum; - /* Copy Btree meta values 3 and 4. These correspond to SQL layer meta - ** values 2 and 3, the default values of a couple of pragmas. - */ - rc = sqlite3BtreeGetMeta(pMain, 3, &meta); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = sqlite3BtreeUpdateMeta(pTemp, 3, meta); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = sqlite3BtreeGetMeta(pMain, 4, &meta); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = sqlite3BtreeUpdateMeta(pTemp, 4, meta); - if( rc!=SQLITE_OK ) goto end_of_vacuum; + /* Copy Btree meta values */ + for(i=0; i<sizeof(aCopy)/sizeof(aCopy[0]); i+=2){ + rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]); + } rc = sqlite3BtreeCopyFile(pMain, pTemp); if( rc!=SQLITE_OK ) goto end_of_vacuum; |
