diff --git a/manifest b/manifest index 369995868a..f99a0d3469 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sfollow-on\schanges\sto\sthe\srecent\sATTACH\spatch.\s(CVS\s893) -D 2003-03-31T13:36:09 +C Add\sinfrastructure\sto\ssuport\smultiple\sbtree\simplementations\s(CVS\s894) +D 2003-04-01T21:16:42 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 dba4d12945228dd7e94de7da0e1d8638b70d99f2 -F src/btree.h 8209bfadf5845d4fdaa60f471bb360f894cd4095 +F src/btree.c 7eae5413a7f957bb0733bcab6fab31c6943c51d2 +F src/btree.h 024d2dd21310c202d648c6244dec885e48efa9ad F src/build.c 81d31f2e63d51683ee653df6399acc3c3a2e3672 F src/delete.c 58d698779a6b7f819718ecd45b310a9de8537088 F src/encode.c faf03741efe921755ec371cf4a6984536de00042 @@ -155,7 +155,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P e80afe75b33d4eacb40ef6128cf688f7c3253984 -R 8452f551322a2a47e2174b852766e085 -U drh -Z 7162b736d28f6cc7cea678e58590971b +P 11378c5bf988412f8564cdc0314fc241793b292e +R cc8e4c3807eb9ac6929fb512790ca871 +U paul +Z 048b3196e99f227ca8551c2b49ca1411 diff --git a/manifest.uuid b/manifest.uuid index 26292d8914..43967b3e83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -11378c5bf988412f8564cdc0314fc241793b292e \ No newline at end of file +79b3aed2a74a67cbad631c4e2e4a43469d80c162 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2779aef027..cd9f13dc5f 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.85 2003/03/30 18:41:22 drh Exp $ +** $Id: btree.c,v 1.86 2003/04/01 21:16:42 paul Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -49,11 +49,18 @@ ** BTree begins on page 2 of the file. (Pages are numbered beginning with ** 1, not 0.) Thus a minimum database contains 2 pages. */ +/* We don't want the btree function macros */ +#define SQLITE_NO_BTREE_DEFS + #include "sqliteInt.h" #include "pager.h" #include "btree.h" #include +/* Forward declarations */ +static BtOps sqliteBtreeOps; +static BtCursorOps sqliteBtreeCursorOps; + /* ** Macros used for byteswapping. B is a pointer to the Btree ** structure. This is needed to access the Btree.needSwab boolean @@ -340,6 +347,7 @@ struct MemPage { ** Everything we need to know about an open database */ struct Btree { + BtOps *pOps; /* Function table */ Pager *pPager; /* The page cache */ BtCursor *pCursor; /* A list of all open cursors */ PageOne *page1; /* First page of the database */ @@ -356,6 +364,7 @@ typedef Btree Bt; ** MemPage.apCell[] of the entry. */ struct BtCursor { + BtCursorOps *pOps; /* Function table */ Btree *pBt; /* The Btree to which this cursor belongs */ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ BtCursor *pShared; /* Loop of cursors with the same root page */ @@ -375,6 +384,9 @@ struct BtCursor { #define SKIP_PREV 2 /* The next sqliteBtreePrevious() is a no-op */ #define SKIP_INVALID 3 /* Calls to Next() and Previous() are invalid */ +/* Forward declarations */ +static int sqliteBtreeCloseCursor(BtCursor *pCur); + /* ** Routines for byte swapping. */ @@ -709,6 +721,7 @@ int sqliteBtreeOpen( pBt->pCursor = 0; pBt->page1 = 0; pBt->readOnly = sqlitepager_isreadonly(pBt->pPager); + pBt->pOps = &sqliteBtreeOps; *ppBtree = pBt; return SQLITE_OK; } @@ -716,7 +729,7 @@ int sqliteBtreeOpen( /* ** Close an open database and invalidate all cursors. */ -int sqliteBtreeClose(Btree *pBt){ +static int sqliteBtreeClose(Btree *pBt){ while( pBt->pCursor ){ sqliteBtreeCloseCursor(pBt->pCursor); } @@ -740,7 +753,7 @@ int sqliteBtreeClose(Btree *pBt){ ** Synchronous is on by default so database corruption is not ** normally a worry. */ -int sqliteBtreeSetCacheSize(Btree *pBt, int mxPage){ +static int sqliteBtreeSetCacheSize(Btree *pBt, int mxPage){ sqlitepager_set_cachesize(pBt->pPager, mxPage); return SQLITE_OK; } @@ -753,7 +766,7 @@ int sqliteBtreeSetCacheSize(Btree *pBt, int mxPage){ ** is a very low but non-zero probability of damage. Level 3 reduces the ** probability of damage to near zero but with a write performance reduction. */ -int sqliteBtreeSetSafetyLevel(Btree *pBt, int level){ +static int sqliteBtreeSetSafetyLevel(Btree *pBt, int level){ sqlitepager_set_safety_level(pBt->pPager, level); return SQLITE_OK; } @@ -860,7 +873,7 @@ static int newDatabase(Btree *pBt){ ** sqliteBtreeDelete() ** sqliteBtreeUpdateMeta() */ -int sqliteBtreeBeginTrans(Btree *pBt){ +static int sqliteBtreeBeginTrans(Btree *pBt){ int rc; if( pBt->inTrans ) return SQLITE_ERROR; if( pBt->readOnly ) return SQLITE_READONLY; @@ -889,7 +902,7 @@ int sqliteBtreeBeginTrans(Btree *pBt){ ** This will release the write lock on the database file. If there ** are no active cursors, it also releases the read lock. */ -int sqliteBtreeCommit(Btree *pBt){ +static int sqliteBtreeCommit(Btree *pBt){ int rc; rc = pBt->readOnly ? SQLITE_OK : sqlitepager_commit(pBt->pPager); pBt->inTrans = 0; @@ -907,7 +920,7 @@ int sqliteBtreeCommit(Btree *pBt){ ** This will release the write lock on the database file. If there ** are no active cursors, it also releases the read lock. */ -int sqliteBtreeRollback(Btree *pBt){ +static int sqliteBtreeRollback(Btree *pBt){ int rc; BtCursor *pCur; if( pBt->inTrans==0 ) return SQLITE_OK; @@ -934,7 +947,7 @@ int sqliteBtreeRollback(Btree *pBt){ ** Only one checkpoint may be active at a time. It is an error to try ** to start a new checkpoint if another checkpoint is already active. */ -int sqliteBtreeBeginCkpt(Btree *pBt){ +static int sqliteBtreeBeginCkpt(Btree *pBt){ int rc; if( !pBt->inTrans || pBt->inCkpt ){ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; @@ -949,7 +962,7 @@ int sqliteBtreeBeginCkpt(Btree *pBt){ ** Commit a checkpoint to transaction currently in progress. If no ** checkpoint is active, this is a no-op. */ -int sqliteBtreeCommitCkpt(Btree *pBt){ +static int sqliteBtreeCommitCkpt(Btree *pBt){ int rc; if( pBt->inCkpt && !pBt->readOnly ){ rc = sqlitepager_ckpt_commit(pBt->pPager); @@ -968,7 +981,7 @@ int sqliteBtreeCommitCkpt(Btree *pBt){ ** to use a cursor that was open at the beginning of this operation ** will result in an error. */ -int sqliteBtreeRollbackCkpt(Btree *pBt){ +static int sqliteBtreeRollbackCkpt(Btree *pBt){ int rc; BtCursor *pCur; if( pBt->inCkpt==0 || pBt->readOnly ) return SQLITE_OK; @@ -1019,7 +1032,7 @@ int sqliteBtreeRollbackCkpt(Btree *pBt){ ** root page of a b-tree. If it is not, then the cursor acquired ** will not work correctly. */ -int sqliteBtreeCursor(Btree *pBt, int iTable, int wrFlag, BtCursor **ppCur){ +static int sqliteBtreeCursor(Btree *pBt, int iTable, int wrFlag, BtCursor **ppCur){ int rc; BtCursor *pCur, *pRing; @@ -1044,6 +1057,7 @@ int sqliteBtreeCursor(Btree *pBt, int iTable, int wrFlag, BtCursor **ppCur){ if( rc!=SQLITE_OK ){ goto create_cursor_exception; } + pCur->pOps = &sqliteBtreeCursorOps; pCur->pBt = pBt; pCur->wrFlag = wrFlag; pCur->idx = 0; @@ -1079,7 +1093,7 @@ create_cursor_exception: ** Close a cursor. The read lock on the database file is released ** when the last cursor is closed. */ -int sqliteBtreeCloseCursor(BtCursor *pCur){ +static int sqliteBtreeCloseCursor(BtCursor *pCur){ Btree *pBt = pCur->pBt; if( pCur->pPrev ){ pCur->pPrev->pNext = pCur->pNext; @@ -1132,7 +1146,7 @@ static void releaseTempCursor(BtCursor *pCur){ ** pointing to an entry (which can happen, for example, if ** the database is empty) then *pSize is set to 0. */ -int sqliteBtreeKeySize(BtCursor *pCur, int *pSize){ +static int sqliteBtreeKeySize(BtCursor *pCur, int *pSize){ Cell *pCell; MemPage *pPage; @@ -1221,7 +1235,7 @@ static int getPayload(BtCursor *pCur, int offset, int amt, char *zBuf){ ** is raised. The change was made in an effort to boost performance ** by eliminating unneeded tests. */ -int sqliteBtreeKey(BtCursor *pCur, int offset, int amt, char *zBuf){ +static int sqliteBtreeKey(BtCursor *pCur, int offset, int amt, char *zBuf){ MemPage *pPage; assert( amt>=0 ); @@ -1243,7 +1257,7 @@ int sqliteBtreeKey(BtCursor *pCur, int offset, int amt, char *zBuf){ ** pointing to an entry (which can happen, for example, if ** the database is empty) then *pSize is set to 0. */ -int sqliteBtreeDataSize(BtCursor *pCur, int *pSize){ +static int sqliteBtreeDataSize(BtCursor *pCur, int *pSize){ Cell *pCell; MemPage *pPage; @@ -1266,7 +1280,7 @@ int sqliteBtreeDataSize(BtCursor *pCur, int *pSize){ ** amount requested if there are not enough bytes in the data ** to satisfy the request. */ -int sqliteBtreeData(BtCursor *pCur, int offset, int amt, char *zBuf){ +static int sqliteBtreeData(BtCursor *pCur, int offset, int amt, char *zBuf){ Cell *pCell; MemPage *pPage; @@ -1304,7 +1318,7 @@ int sqliteBtreeData(BtCursor *pCur, int offset, int amt, char *zBuf){ ** keys must be exactly the same length. (The length of the pCur key ** is the actual key length minus nIgnore bytes.) */ -int sqliteBtreeKeyCompare( +static int sqliteBtreeKeyCompare( BtCursor *pCur, /* Pointer to entry to compare against */ const void *pKey, /* Key to compare against entry that pCur points to */ int nKey, /* Number of bytes in pKey */ @@ -1503,7 +1517,7 @@ static int moveToRightmost(BtCursor *pCur){ ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. */ -int sqliteBtreeFirst(BtCursor *pCur, int *pRes){ +static int sqliteBtreeFirst(BtCursor *pCur, int *pRes){ int rc; if( pCur->pPage==0 ) return SQLITE_ABORT; rc = moveToRoot(pCur); @@ -1522,7 +1536,7 @@ int sqliteBtreeFirst(BtCursor *pCur, int *pRes){ ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. */ -int sqliteBtreeLast(BtCursor *pCur, int *pRes){ +static int sqliteBtreeLast(BtCursor *pCur, int *pRes){ int rc; if( pCur->pPage==0 ) return SQLITE_ABORT; rc = moveToRoot(pCur); @@ -1561,7 +1575,7 @@ int sqliteBtreeLast(BtCursor *pCur, int *pRes){ ** *pRes>0 The cursor is left pointing at an entry that ** is larger than pKey. */ -int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){ +static int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){ int rc; if( pCur->pPage==0 ) return SQLITE_ABORT; pCur->eSkip = SKIP_NONE; @@ -1614,7 +1628,7 @@ int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){ ** was already pointing to the last entry in the database before ** this routine was called, then set *pRes=1. */ -int sqliteBtreeNext(BtCursor *pCur, int *pRes){ +static int sqliteBtreeNext(BtCursor *pCur, int *pRes){ int rc; MemPage *pPage = pCur->pPage; assert( pRes!=0 ); @@ -1669,7 +1683,7 @@ int sqliteBtreeNext(BtCursor *pCur, int *pRes){ ** was already pointing to the first entry in the database before ** this routine was called, then set *pRes=1. */ -int sqliteBtreePrevious(BtCursor *pCur, int *pRes){ +static int sqliteBtreePrevious(BtCursor *pCur, int *pRes){ int rc; Pgno pgno; MemPage *pPage; @@ -2595,7 +2609,7 @@ static int checkReadLocks(BtCursor *pCur){ ** define what database the record should be inserted into. The cursor ** is left pointing at the new record. */ -int sqliteBtreeInsert( +static int sqliteBtreeInsert( BtCursor *pCur, /* Insert data into the table of this cursor */ const void *pKey, int nKey, /* The key of the new record */ const void *pData, int nData /* The data of the new record */ @@ -2663,7 +2677,7 @@ int sqliteBtreeInsert( ** sqliteBtreePrevious() will always leave the cursor pointing at the ** entry immediately before the one that was deleted. */ -int sqliteBtreeDelete(BtCursor *pCur){ +static int sqliteBtreeDelete(BtCursor *pCur){ MemPage *pPage = pCur->pPage; Cell *pCell; int rc; @@ -2750,7 +2764,7 @@ int sqliteBtreeDelete(BtCursor *pCur){ ** are restricted to having a 4-byte integer key and arbitrary data and ** BTree indices are restricted to having an arbitrary key and no data. */ -int sqliteBtreeCreateTable(Btree *pBt, int *piTable){ +static int sqliteBtreeCreateTable(Btree *pBt, int *piTable){ MemPage *pRoot; Pgno pgnoRoot; int rc; @@ -2779,7 +2793,7 @@ int sqliteBtreeCreateTable(Btree *pBt, int *piTable){ ** are restricted to having a 4-byte integer key and arbitrary data and ** BTree indices are restricted to having an arbitrary key and no data. */ -int sqliteBtreeCreateIndex(Btree *pBt, int *piIndex){ +static int sqliteBtreeCreateIndex(Btree *pBt, int *piIndex){ return sqliteBtreeCreateTable(pBt, piIndex); } @@ -2826,7 +2840,7 @@ static int clearDatabasePage(Btree *pBt, Pgno pgno, int freePageFlag){ /* ** Delete all information from a single table in the database. */ -int sqliteBtreeClearTable(Btree *pBt, int iTable){ +static int sqliteBtreeClearTable(Btree *pBt, int iTable){ int rc; BtCursor *pCur; if( !pBt->inTrans ){ @@ -2850,7 +2864,7 @@ int sqliteBtreeClearTable(Btree *pBt, int iTable){ ** the freelist. Except, the root of the principle table (the one on ** page 2) is never added to the freelist. */ -int sqliteBtreeDropTable(Btree *pBt, int iTable){ +static int sqliteBtreeDropTable(Btree *pBt, int iTable){ int rc; MemPage *pPage; BtCursor *pCur; @@ -2977,7 +2991,7 @@ static int copyDatabasePage( /* ** Read the meta-information out of a database file. */ -int sqliteBtreeGetMeta(Btree *pBt, int *aMeta){ +static int sqliteBtreeGetMeta(Btree *pBt, int *aMeta){ PageOne *pP1; int rc; int i; @@ -2995,7 +3009,7 @@ int sqliteBtreeGetMeta(Btree *pBt, int *aMeta){ /* ** Write meta-information back into the database. */ -int sqliteBtreeUpdateMeta(Btree *pBt, int *aMeta){ +static int sqliteBtreeUpdateMeta(Btree *pBt, int *aMeta){ PageOne *pP1; int rc, i; if( !pBt->inTrans ){ @@ -3021,7 +3035,7 @@ int sqliteBtreeUpdateMeta(Btree *pBt, int *aMeta){ ** is used for debugging and testing only. */ #ifdef SQLITE_TEST -int sqliteBtreePageDump(Btree *pBt, int pgno, int recursive){ +static int sqliteBtreePageDump(Btree *pBt, int pgno, int recursive){ int rc; MemPage *pPage; int i, j; @@ -3108,7 +3122,7 @@ int sqliteBtreePageDump(Btree *pBt, int pgno, int recursive){ ** ** This routine is used for testing and debugging only. */ -int sqliteBtreeCursorDump(BtCursor *pCur, int *aResult){ +static int sqliteBtreeCursorDump(BtCursor *pCur, int *aResult){ int cnt, idx; MemPage *pPage = pCur->pPage; Btree *pBt = pCur->pBt; @@ -3140,7 +3154,7 @@ int sqliteBtreeCursorDump(BtCursor *pCur, int *aResult){ ** Return the pager associated with a BTree. This routine is used for ** testing and debugging only. */ -Pager *sqliteBtreePager(Btree *pBt){ +static Pager *sqliteBtreePager(Btree *pBt){ return pBt->pPager; } #endif @@ -3480,3 +3494,47 @@ char *sqliteBtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ sqliteFree(sCheck.anRef); return sCheck.zErrMsg; } + +static BtOps sqliteBtreeOps = { + sqliteBtreeClose, + sqliteBtreeSetCacheSize, + sqliteBtreeSetSafetyLevel, + sqliteBtreeBeginTrans, + sqliteBtreeCommit, + sqliteBtreeRollback, + sqliteBtreeBeginCkpt, + sqliteBtreeCommitCkpt, + sqliteBtreeRollbackCkpt, + sqliteBtreeCreateTable, + sqliteBtreeCreateIndex, + sqliteBtreeDropTable, + sqliteBtreeClearTable, + sqliteBtreeCursor, + sqliteBtreeGetMeta, + sqliteBtreeUpdateMeta, + sqliteBtreeIntegrityCheck, + +#ifdef SQLITE_TEST + sqliteBtreePageDump, + sqliteBtreePager +#endif +}; + +static BtCursorOps sqliteBtreeCursorOps = { + sqliteBtreeMoveto, + sqliteBtreeDelete, + sqliteBtreeInsert, + sqliteBtreeFirst, + sqliteBtreeLast, + sqliteBtreeNext, + sqliteBtreePrevious, + sqliteBtreeKeySize, + sqliteBtreeKey, + sqliteBtreeKeyCompare, + sqliteBtreeDataSize, + sqliteBtreeData, + sqliteBtreeCloseCursor, +#ifdef SQLITE_TEST + sqliteBtreeCursorDump, +#endif +}; diff --git a/src/btree.h b/src/btree.h index ef6f781277..52c23d7759 100644 --- a/src/btree.h +++ b/src/btree.h @@ -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.28 2003/03/19 03:14:01 drh Exp $ +** @(#) $Id: btree.h,v 1.29 2003/04/01 21:16:43 paul Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -21,51 +21,141 @@ typedef struct Btree Btree; typedef struct BtCursor BtCursor; -int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree); -int sqliteBtreeClose(Btree*); -int sqliteBtreeSetCacheSize(Btree*, int); -int sqliteBtreeSetSafetyLevel(Btree*, int); +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 (*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 sqliteBtreeCopyTable(Btree *pFrom, int iFrom, Btree *pTo, int iTo); + 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 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*); + int (*sqliteBtreeCursor)(Btree*, int iTable, int wrFlag, BtCursor **ppCur); -#define SQLITE_N_BTREE_META 10 -int sqliteBtreeGetMeta(Btree*, int*); -int sqliteBtreeUpdateMeta(Btree*, int*); + int (*sqliteBtreeGetMeta)(Btree*, int*); + int (*sqliteBtreeUpdateMeta)(Btree*, int*); -char *sqliteBtreeIntegrityCheck(Btree*, int*, int); + char *(*sqliteBtreeIntegrityCheck)(Btree*, int*, int); #ifdef SQLITE_TEST -int sqliteBtreePageDump(Btree*, int, int); -int sqliteBtreeCursorDump(BtCursor*, int*); -struct Pager *sqliteBtreePager(Btree*); + 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; + +#define SQLITE_N_BTREE_META 10 + +int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree); + +#if !defined(SQLITE_NO_BTREE_DEFS) +#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 sqliteBtreeCreateIndex(pBt, piIndex)\ + (btOps(pBt)->sqliteBtreeCreateIndex(pBt, piIndex)) +#define sqliteBtreeDropTable(pBt, iTable)\ + (btOps(pBt)->sqliteBtreeDropTable(pBt, iTable)) +#define sqliteBtreeClearTable(pBt, iTable)\ + (btOps(pBt)->sqliteBtreeClearTable(pBt, iTable)) +#define sqliteBtreeCursor(pBt, iTable, wrFlag, ppCur)\ + (btOps(pBt)->sqliteBtreeCursor(pBt, iTable, wrFlag, ppCur)) +#define sqliteBtreeMoveto(pCur, pKey, nKey, pRes)\ + (btCOps(pCur)->sqliteBtreeMoveto(pCur, pKey, nKey, pRes)) +#define sqliteBtreeDelete(pCur)\ + (btCOps(pCur)->sqliteBtreeDelete(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) ) +#define sqliteBtreeKey(pCur, offset, amt, zBuf)\ + (btCOps(pCur)->sqliteBtreeKey(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)) +#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)) +#define sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot)\ + (btOps(pBt)->sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot)) +#endif + +#ifdef SQLITE_TEST +#if !defined(SQLITE_NO_BTREE_DEFS) +#define sqliteBtreePageDump(pBt, pgno, recursive)\ + (btOps(pBt)->sqliteBtreePageDump(pBt, pgno, recursive)) +#define sqliteBtreeCursorDump(pCur, aResult)\ + (btCOps(pCur)->sqliteBtreeCursorDump(pCur, aResult)) +#define sqliteBtreePager(pBt)\ + (btOps(pBt)->sqliteBtreePager(pBt)) +#endif + int btree_native_byte_order; #endif