diff --git a/manifest b/manifest index f76832d8fc..f246fc0116 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stesting\sof\sATTACH\sand\sDETACH.\s(CVS\s899) -D 2003-04-05T16:56:29 +C Simplify\sthe\sBTree\sinterface\sby\sshortening\snames.\s\sAdded\stwo\snew\smethods\nfor\saccessing\sthe\scurrent\sfilename\sand\sfor\schanging\sthe\sname\sof\sthe\ndatabase\sfile.\s(CVS\s900) +D 2003-04-06T20:44:45 F Makefile.in 3c4ba24253e61c954d67adbbb4245e7117c5357e F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -20,8 +20,8 @@ F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2 F src/auth.c f37bfc9451b8c1fa52f34adff474560018892729 -F src/btree.c 7eae5413a7f957bb0733bcab6fab31c6943c51d2 -F src/btree.h 024d2dd21310c202d648c6244dec885e48efa9ad +F src/btree.c 3b0e0f09886bc83fa183df367d6a1b7077da9c46 +F src/btree.h 5cb871546bd6fa58396a6f033e2b29b388241e1b F src/build.c 8f158c26c89464e33de4b83a0964042462ea9977 F src/delete.c 58d698779a6b7f819718ecd45b310a9de8537088 F src/encode.c faf03741efe921755ec371cf4a6984536de00042 @@ -32,10 +32,10 @@ F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 F src/insert.c e2f5e7feecb507d904a7da48874595f440b715aa F src/main.c c5109638c0cd86fa450faa2bd5a60468325aef69 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 -F src/os.c dfed46091f69cd2d1e601f8a214d41344f2b00b6 +F src/os.c c33ebb320921b8df6d09ea19fe846348df86a0c9 F src/os.h aa52f0c9da321ff6134d19f2ca959e18e33615d0 -F src/pager.c dd1dfa4d929a58b44175f3117360ff1553671173 -F src/pager.h 97d9a8cc5103750efd8037d71ebfb41849ef2f2f +F src/pager.c 53abd9df41889ca31b223eceda6e5e724145eae2 +F src/pager.h e3702f7d384921f6cd5ce0b3ed589185433e9f6c F src/parse.y 3be47fa18323aa2e3364fc42bf7a6ba5b3cc0a81 F src/printf.c fc5fdef6e92ad205005263661fe9716f55a49f3e F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe @@ -157,7 +157,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 7a0f8024a1323a15d0c83afe9302400736f01fe8 -R 46fc1ff8621b9b0935cd818bb39b2c75 +P 51f515f28cb1cc3e8f0c3531724dc8876b25f18e +R c5d5548ccf24f7b5ba0652ab8b119df1 U drh -Z a79dcf89f73a5ac08f2e57c1e7e0b648 +Z 46e4a19e80ac8f859bd26b2a93f77bd0 diff --git a/manifest.uuid b/manifest.uuid index 0a123a101b..fdef62adb4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -51f515f28cb1cc3e8f0c3531724dc8876b25f18e \ No newline at end of file +185d8dc8d0c26cef36aeba6992823e5124af4056 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index cd9f13dc5f..a47b98a7c9 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.86 2003/04/01 21:16:42 paul Exp $ +** $Id: btree.c,v 1.87 2003/04/06 20:44:45 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -3495,6 +3495,27 @@ char *sqliteBtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ return sCheck.zErrMsg; } +/* +** Return the full pathname of the underlying database file. +*/ +static const char *sqliteBtreeGetFilename(Btree *pBt){ + assert( pBt->pPager!=0 ); + return sqlitepager_filename(pBt->pPager); +} + +/* +** Change the name of the underlying database file. +*/ +static int sqliteBtreeChangeFilename(Btree *pBt, const char *zNew){ + return sqlitepager_rename(pBt->pPager, zNew); +} + +/* +** The following tables contain pointers to all of the interface +** routines for this implementation of the B*Tree backend. To +** substitute a different implemention of the backend, one has merely +** to provide pointers to alternative functions in similar tables. +*/ static BtOps sqliteBtreeOps = { sqliteBtreeClose, sqliteBtreeSetCacheSize, @@ -3513,13 +3534,13 @@ static BtOps sqliteBtreeOps = { sqliteBtreeGetMeta, sqliteBtreeUpdateMeta, sqliteBtreeIntegrityCheck, - + sqliteBtreeGetFilename, + sqliteBtreeChangeFilename, #ifdef SQLITE_TEST sqliteBtreePageDump, sqliteBtreePager #endif }; - static BtCursorOps sqliteBtreeCursorOps = { sqliteBtreeMoveto, sqliteBtreeDelete, diff --git a/src/btree.h b/src/btree.h index 52c23d7759..98ea3345ad 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,69 +13,85 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.29 2003/04/01 21:16:43 paul Exp $ +** @(#) $Id: btree.h,v 1.30 2003/04/06 20:44:45 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ +/* +** Forward declarations of structure +*/ typedef struct Btree Btree; typedef struct BtCursor BtCursor; - -struct BtOps { - int (*sqliteBtreeClose)(Btree*); - int (*sqliteBtreeSetCacheSize)(Btree*, int); - int (*sqliteBtreeSetSafetyLevel)(Btree*, int); - - int (*sqliteBtreeBeginTrans)(Btree*); - int (*sqliteBtreeCommit)(Btree*); - int (*sqliteBtreeRollback)(Btree*); - int (*sqliteBtreeBeginCkpt)(Btree*); - int (*sqliteBtreeCommitCkpt)(Btree*); - int (*sqliteBtreeRollbackCkpt)(Btree*); - - int (*sqliteBtreeCreateTable)(Btree*, int*); - int (*sqliteBtreeCreateIndex)(Btree*, int*); - int (*sqliteBtreeDropTable)(Btree*, int); - int (*sqliteBtreeClearTable)(Btree*, int); - - int (*sqliteBtreeCursor)(Btree*, int iTable, int wrFlag, BtCursor **ppCur); - - int (*sqliteBtreeGetMeta)(Btree*, int*); - int (*sqliteBtreeUpdateMeta)(Btree*, int*); - - char *(*sqliteBtreeIntegrityCheck)(Btree*, int*, int); - -#ifdef SQLITE_TEST - int (*sqliteBtreePageDump)(Btree*, int, int); - struct Pager * (*sqliteBtreePager)(Btree*); -#endif -}; - typedef struct BtOps BtOps; - -struct BtCursorOps { - int (*sqliteBtreeMoveto)(BtCursor*, const void *pKey, int nKey, int *pRes); - int (*sqliteBtreeDelete)(BtCursor*); - int (*sqliteBtreeInsert)(BtCursor*, const void *pKey, int nKey, - const void *pData, int nData); - int (*sqliteBtreeFirst)(BtCursor*, int *pRes); - int (*sqliteBtreeLast)(BtCursor*, int *pRes); - int (*sqliteBtreeNext)(BtCursor*, int *pRes); - int (*sqliteBtreePrevious)(BtCursor*, int *pRes); - int (*sqliteBtreeKeySize)(BtCursor*, int *pSize); - int (*sqliteBtreeKey)(BtCursor*, int offset, int amt, char *zBuf); - int (*sqliteBtreeKeyCompare)(BtCursor*, const void *pKey, int nKey, - int nIgnore, int *pRes); - int (*sqliteBtreeDataSize)(BtCursor*, int *pSize); - int (*sqliteBtreeData)(BtCursor*, int offset, int amt, char *zBuf); - int (*sqliteBtreeCloseCursor)(BtCursor*); -#ifdef SQLITE_TEST - int (*sqliteBtreeCursorDump)(BtCursor*, int*); -#endif -}; - typedef struct BtCursorOps BtCursorOps; + +/* +** An instance of the following structure contains pointers to all +** methods against an open BTree. Alternative BTree implementations +** (examples: file based versus in-memory) can be created by substituting +** different methods. Users of the BTree cannot tell the difference. +** +** In C++ we could do this by defining a virtual base class and then +** creating subclasses for each different implementation. But this is +** C not C++ so we have to be a little more explicit. +*/ +struct BtOps { + int (*Close)(Btree*); + int (*SetCacheSize)(Btree*, int); + int (*SetSafetyLevel)(Btree*, int); + int (*BeginTrans)(Btree*); + int (*Commit)(Btree*); + int (*Rollback)(Btree*); + int (*BeginCkpt)(Btree*); + int (*CommitCkpt)(Btree*); + int (*RollbackCkpt)(Btree*); + int (*CreateTable)(Btree*, int*); + int (*CreateIndex)(Btree*, int*); + int (*DropTable)(Btree*, int); + int (*ClearTable)(Btree*, int); + int (*Cursor)(Btree*, int iTable, int wrFlag, BtCursor **ppCur); + int (*GetMeta)(Btree*, int*); + int (*UpdateMeta)(Btree*, int*); + char *(*IntegrityCheck)(Btree*, int*, int); + const char *(*GetFilename)(Btree*); + int (*ChangeFilename)(Btree*, const char *zNew); +#ifdef SQLITE_TEST + int (*PageDump)(Btree*, int, int); + struct Pager *(*Pager)(Btree*); +#endif +}; + +/* +** An instance of this structure defines all of the methods that can +** be executed against a cursor. +*/ +struct BtCursorOps { + int (*Moveto)(BtCursor*, const void *pKey, int nKey, int *pRes); + int (*Delete)(BtCursor*); + int (*Insert)(BtCursor*, const void *pKey, int nKey, + const void *pData, int nData); + int (*First)(BtCursor*, int *pRes); + int (*Last)(BtCursor*, int *pRes); + int (*Next)(BtCursor*, int *pRes); + int (*Previous)(BtCursor*, int *pRes); + int (*KeySize)(BtCursor*, int *pSize); + int (*Key)(BtCursor*, int offset, int amt, char *zBuf); + int (*KeyCompare)(BtCursor*, const void *pKey, int nKey, + int nIgnore, int *pRes); + int (*DataSize)(BtCursor*, int *pSize); + int (*Data)(BtCursor*, int offset, int amt, char *zBuf); + int (*CloseCursor)(BtCursor*); +#ifdef SQLITE_TEST + int (*CursorDump)(BtCursor*, int*); +#endif +}; + +/* +** The number of 4-byte "meta" values contained on the first page of each +** database file. +*/ #define SQLITE_N_BTREE_META 10 int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree); @@ -84,76 +100,58 @@ int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree); #define btOps(pBt) (*((BtOps **)(pBt))) #define btCOps(pCur) (*((BtCursorOps **)(pCur))) -#define sqliteBtreeClose(pBt)\ - (btOps(pBt)->sqliteBtreeClose(pBt)) -#define sqliteBtreeSetCacheSize(pBt, sz)\ - (btOps(pBt)->sqliteBtreeSetCacheSize(pBt, sz)) -#define sqliteBtreeSetSafetyLevel(pBt, sl)\ - (btOps(pBt)->sqliteBtreeSetSafetyLevel(pBt, sl)) -#define sqliteBtreeBeginTrans(pBt)\ - (btOps(pBt)->sqliteBtreeBeginTrans(pBt)) -#define sqliteBtreeCommit(pBt)\ - (btOps(pBt)->sqliteBtreeCommit(pBt)) -#define sqliteBtreeRollback(pBt)\ - (btOps(pBt)->sqliteBtreeRollback(pBt)) -#define sqliteBtreeBeginCkpt(pBt)\ - (btOps(pBt)->sqliteBtreeBeginCkpt(pBt)) -#define sqliteBtreeCommitCkpt(pBt)\ - (btOps(pBt)->sqliteBtreeCommitCkpt(pBt)) -#define sqliteBtreeRollbackCkpt(pBt)\ - (btOps(pBt)->sqliteBtreeRollbackCkpt(pBt)) -#define sqliteBtreeCreateTable(pBt, piTable)\ - (btOps(pBt)->sqliteBtreeCreateTable(pBt, piTable)) +#define sqliteBtreeClose(pBt) (btOps(pBt)->Close(pBt)) +#define sqliteBtreeSetCacheSize(pBt, sz) (btOps(pBt)->SetCacheSize(pBt, sz)) +#define sqliteBtreeSetSafetyLevel(pBt, sl) (btOps(pBt)->SetSafetyLevel(pBt, sl)) +#define sqliteBtreeBeginTrans(pBt) (btOps(pBt)->BeginTrans(pBt)) +#define sqliteBtreeCommit(pBt) (btOps(pBt)->Commit(pBt)) +#define sqliteBtreeRollback(pBt) (btOps(pBt)->Rollback(pBt)) +#define sqliteBtreeBeginCkpt(pBt) (btOps(pBt)->BeginCkpt(pBt)) +#define sqliteBtreeCommitCkpt(pBt) (btOps(pBt)->CommitCkpt(pBt)) +#define sqliteBtreeRollbackCkpt(pBt) (btOps(pBt)->RollbackCkpt(pBt)) +#define sqliteBtreeCreateTable(pBt,piTable)\ + (btOps(pBt)->CreateTable(pBt,piTable)) #define sqliteBtreeCreateIndex(pBt, piIndex)\ - (btOps(pBt)->sqliteBtreeCreateIndex(pBt, piIndex)) -#define sqliteBtreeDropTable(pBt, iTable)\ - (btOps(pBt)->sqliteBtreeDropTable(pBt, iTable)) + (btOps(pBt)->CreateIndex(pBt, piIndex)) +#define sqliteBtreeDropTable(pBt, iTable) (btOps(pBt)->DropTable(pBt, iTable)) #define sqliteBtreeClearTable(pBt, iTable)\ - (btOps(pBt)->sqliteBtreeClearTable(pBt, iTable)) + (btOps(pBt)->ClearTable(pBt, iTable)) #define sqliteBtreeCursor(pBt, iTable, wrFlag, ppCur)\ - (btOps(pBt)->sqliteBtreeCursor(pBt, iTable, wrFlag, ppCur)) + (btOps(pBt)->Cursor(pBt, iTable, wrFlag, ppCur)) #define sqliteBtreeMoveto(pCur, pKey, nKey, pRes)\ - (btCOps(pCur)->sqliteBtreeMoveto(pCur, pKey, nKey, pRes)) -#define sqliteBtreeDelete(pCur)\ - (btCOps(pCur)->sqliteBtreeDelete(pCur)) + (btCOps(pCur)->Moveto(pCur, pKey, nKey, pRes)) +#define sqliteBtreeDelete(pCur) (btCOps(pCur)->Delete(pCur)) #define sqliteBtreeInsert(pCur, pKey, nKey, pData, nData) \ - (btCOps(pCur)->sqliteBtreeInsert(pCur, pKey, nKey, pData, nData)) -#define sqliteBtreeFirst(pCur, pRes)\ - (btCOps(pCur)->sqliteBtreeFirst(pCur, pRes)) -#define sqliteBtreeLast(pCur, pRes)\ - (btCOps(pCur)->sqliteBtreeLast(pCur, pRes)) -#define sqliteBtreeNext(pCur, pRes)\ - (btCOps(pCur)->sqliteBtreeNext(pCur, pRes)) -#define sqliteBtreePrevious(pCur, pRes)\ - (btCOps(pCur)->sqliteBtreePrevious(pCur, pRes)) -#define sqliteBtreeKeySize(pCur, pSize)\ - (btCOps(pCur)->sqliteBtreeKeySize(pCur, pSize) ) + (btCOps(pCur)->Insert(pCur, pKey, nKey, pData, nData)) +#define sqliteBtreeFirst(pCur, pRes) (btCOps(pCur)->First(pCur, pRes)) +#define sqliteBtreeLast(pCur, pRes) (btCOps(pCur)->Last(pCur, pRes)) +#define sqliteBtreeNext(pCur, pRes) (btCOps(pCur)->Next(pCur, pRes)) +#define sqliteBtreePrevious(pCur, pRes) (btCOps(pCur)->Previous(pCur, pRes)) +#define sqliteBtreeKeySize(pCur, pSize) (btCOps(pCur)->KeySize(pCur, pSize) ) #define sqliteBtreeKey(pCur, offset, amt, zBuf)\ - (btCOps(pCur)->sqliteBtreeKey(pCur, offset, amt, zBuf)) + (btCOps(pCur)->Key(pCur, offset, amt, zBuf)) #define sqliteBtreeKeyCompare(pCur, pKey, nKey, nIgnore, pRes)\ - (btCOps(pCur)->sqliteBtreeKeyCompare(pCur, pKey, nKey, nIgnore, pRes)) -#define sqliteBtreeDataSize(pCur, pSize)\ - (btCOps(pCur)->sqliteBtreeDataSize(pCur, pSize)) + (btCOps(pCur)->KeyCompare(pCur, pKey, nKey, nIgnore, pRes)) +#define sqliteBtreeDataSize(pCur, pSize) (btCOps(pCur)->DataSize(pCur, pSize)) #define sqliteBtreeData(pCur, offset, amt, zBuf)\ - (btCOps(pCur)->sqliteBtreeData(pCur, offset, amt, zBuf)) -#define sqliteBtreeCloseCursor(pCur)\ - (btCOps(pCur)->sqliteBtreeCloseCursor(pCur)) -#define sqliteBtreeGetMeta(pBt, aMeta)\ - (btOps(pBt)->sqliteBtreeGetMeta(pBt, aMeta)) -#define sqliteBtreeUpdateMeta(pBt, aMeta)\ - (btOps(pBt)->sqliteBtreeUpdateMeta(pBt, aMeta)) + (btCOps(pCur)->Data(pCur, offset, amt, zBuf)) +#define sqliteBtreeCloseCursor(pCur) (btCOps(pCur)->CloseCursor(pCur)) +#define sqliteBtreeGetMeta(pBt, aMeta) (btOps(pBt)->GetMeta(pBt, aMeta)) +#define sqliteBtreeUpdateMeta(pBt, aMeta) (btOps(pBt)->UpdateMeta(pBt, aMeta)) #define sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot)\ - (btOps(pBt)->sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot)) + (btOps(pBt)->IntegrityCheck(pBt, aRoot, nRoot)) +#define sqliteBtreeGetFilename(pBt) (btOps(pBt)->GetFilename(pBt)) +#define sqliteBtreeChangeFilename(pBt, zNew)\ + (btOps(pBt)->ChangeFilename(pBt, zNew)) #endif #ifdef SQLITE_TEST #if !defined(SQLITE_NO_BTREE_DEFS) #define sqliteBtreePageDump(pBt, pgno, recursive)\ - (btOps(pBt)->sqliteBtreePageDump(pBt, pgno, recursive)) + (btOps(pBt)->PageDump(pBt, pgno, recursive)) #define sqliteBtreeCursorDump(pCur, aResult)\ - (btCOps(pCur)->sqliteBtreeCursorDump(pCur, aResult)) -#define sqliteBtreePager(pBt)\ - (btOps(pBt)->sqliteBtreePager(pBt)) + (btCOps(pCur)->CursorDump(pCur, aResult)) +#define sqliteBtreePager(pBt) (btOps(pBt)->Pager(pBt)) #endif int btree_native_byte_order; diff --git a/src/os.c b/src/os.c index 77bdf3ae00..a0ec2d6b73 100644 --- a/src/os.c +++ b/src/os.c @@ -271,7 +271,7 @@ int sqliteOsFileExists(const char *zFilename){ /* ** Change the name of an existing file. */ -int sqliteOsRename(const char *zOldName, const char *zNewName){ +int sqliteOsFileRename(const char *zOldName, const char *zNewName){ #if OS_UNIX if( link(zOldName, zNewName) ){ return SQLITE_ERROR; diff --git a/src/pager.c b/src/pager.c index 58eb8cee41..37948df6c8 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.79 2003/03/19 03:14:02 drh Exp $ +** @(#) $Id: pager.c,v 1.80 2003/04/06 20:44:45 drh Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" @@ -966,6 +966,10 @@ int sqlitepager_close(Pager *pPager){ ** } */ CLR_PAGER(pPager); + if( pPager->zFilename!=(char*)&pPager[1] ){ + sqliteFree(pPager->zFilename); + sqliteFree(pPager->zJournal); + } sqliteFree(pPager); return SQLITE_OK; } @@ -2026,6 +2030,50 @@ int sqlitepager_ckpt_rollback(Pager *pPager){ return rc; } +/* +** Return the full pathname of the database file. +*/ +const char *sqlitepager_filename(Pager *pPager){ + return pPager->zFilename; +} + +/* +** Rename the database file +*/ +int sqlitepager_rename(Pager *pPager, const char *zNewName){ + char *zNew; + char *zJournal; + int nName; + int rc; + + nName = strlen(zNewName); + zNew = sqliteMalloc( nName*2 + 30 ); + if( zNew==0 ){ + return SQLITE_NOMEM; + } + memcpy(zNew, zNewName, nName+1); + zJournal = &zNew[nName+1]; + memcpy(zJournal, zNew, nName); + strcpy(&zJournal[nName], "-journal"); + if( pPager->journalOpen ){ + rc = sqliteOsRename(pPager->zJournal, zJournal); + if( rc ){ + sqliteFree(zNew); + return rc; + } + } + rc = sqliteOsRename(pPager->zFilename, zNew); + if( rc ){ + sqliteFree(zNew); + return rc; + } + if( pPager->zFilename!=(char*)&pPager[1] ){ + sqliteFree(pPager->zFilename); + } + pPager->zFilename = zNew; + return SQLITE_OK; +} + #ifdef SQLITE_TEST /* ** Print a listing of all referenced pages and their ref count. diff --git a/src/pager.h b/src/pager.h index bba8220ace..63963173c1 100644 --- a/src/pager.h +++ b/src/pager.h @@ -13,7 +13,7 @@ ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.21 2003/03/19 03:14:02 drh Exp $ +** @(#) $Id: pager.h,v 1.22 2003/04/06 20:44:45 drh Exp $ */ /* @@ -72,6 +72,8 @@ void sqlitepager_dont_rollback(void*); void sqlitepager_dont_write(Pager*, Pgno); int *sqlitepager_stats(Pager*); void sqlitepager_set_safety_level(Pager*,int); +const char *sqlitepager_filename(Pager*); +int sqlitepager_rename(Pager*, const char *zNewName); #ifdef SQLITE_TEST void sqlitepager_refdump(Pager*);