Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -7,11 +7,11 @@ ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.108 2004/05/03 19:49:33 drh Exp $ +** $Id: btree.c,v 1.109 2004/05/04 17:27:28 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: @@ -264,19 +264,19 @@ Pgno pgnoRoot; /* The root page of this tree */ MemPage *pPage; /* Page that contains the entry */ int idx; /* Index of the entry in pPage->aCell[] */ u8 wrFlag; /* True if writable */ u8 eSkip; /* Determines if next step operation is a no-op */ - u8 iMatch; /* compare result from last sqliteBtreeMoveto() */ + u8 iMatch; /* compare result from last sqlite3BtreeMoveto() */ }; /* ** Legal values for BtCursor.eSkip. */ #define SKIP_NONE 0 /* Always step the cursor */ -#define SKIP_NEXT 1 /* The next sqliteBtreeNext() is a no-op */ -#define SKIP_PREV 2 /* The next sqliteBtreePrevious() is a no-op */ +#define SKIP_NEXT 1 /* The next sqlite3BtreeNext() is a no-op */ +#define SKIP_PREV 2 /* The next sqlite3BtreePrevious() is a no-op */ #define SKIP_INVALID 3 /* Calls to Next() and Previous() are invalid */ /* ** Read or write a two-, four-, and eight-byte big-endian integer values. */ @@ -391,15 +391,15 @@ static void defragmentPage(MemPage *pPage){ int pc, i, n, addr; int start, hdr, size; int leftover; unsigned char *oldPage; - unsigned char newPage[SQLITE_PAGE_SIZE]; + unsigned char newPage[MX_PAGE_SIZE]; assert( sqlitepager_iswriteable(pPage->aData) ); assert( pPage->pBt!=0 ); - assert( pPage->pageSize <= SQLITE_PAGE_SIZE ); + assert( pPage->pageSize <= MX_PAGE_SIZE ); oldPage = pPage->aData; hdr = pPage->hdrOffset; addr = 3+hdr; n = 6+hdr; if( !pPage->leaf ){ @@ -827,13 +827,13 @@ ** for accessing the database. We do not open the database file ** until the first page is loaded. ** ** zFilename is the name of the database file. If zFilename is NULL ** a new database with a random name is created. This randomly named -** database file will be deleted when sqliteBtreeClose() is called. +** database file will be deleted when sqlite3BtreeClose() is called. */ -int sqliteBtreeOpen( +int sqlite3BtreeOpen( const char *zFilename, /* Name of the file containing the BTree database */ Btree **ppBtree, /* Pointer to new Btree object written here */ int nCache, /* Number of cache pages */ int flags /* Options */ ){ @@ -903,11 +903,11 @@ ** an abrupt power failure when synchronous is off, the database ** could be left in an inconsistent and unrecoverable state. ** Synchronous is on by default so database corruption is not ** normally a worry. */ -int sqilte3BtreeSetCacheSize(Btree *pBt, int mxPage){ +int sqlite3BtreeSetCacheSize(Btree *pBt, int mxPage){ sqlitepager_set_cachesize(pBt->pPager, mxPage); return SQLITE_OK; } /* @@ -1008,17 +1008,17 @@ ** ** A transaction must be started before attempting any changes ** to the database. None of the following routines will work ** unless a transaction is started first: ** -** sqliteBtreeCreateTable() -** sqliteBtreeCreateIndex() -** sqliteBtreeClearTable() -** sqliteBtreeDropTable() -** sqliteBtreeInsert() -** sqliteBtreeDelete() -** sqliteBtreeUpdateMeta() +** sqlite3BtreeCreateTable() +** sqlite3BtreeCreateIndex() +** sqlite3BtreeClearTable() +** sqlite3BtreeDropTable() +** sqlite3BtreeInsert() +** sqlite3BtreeDelete() +** sqlite3BtreeUpdateMeta() */ int sqlite3BtreeBeginTrans(Btree *pBt){ int rc; if( pBt->inTrans ) return SQLITE_ERROR; if( pBt->readOnly ) return SQLITE_READONLY; @@ -1186,11 +1186,11 @@ ** change as long as the cursor is open. This allows the cursor to ** do a sequential scan of the table without having to worry about ** entries being inserted or deleted during the scan. Cursors should ** be opened with wrFlag==0 only if this read-lock property is needed. ** That is to say, cursors should be opened with wrFlag==0 only if they -** intend to use the sqliteBtreeNext() system call. All other cursors +** intend to use the sqlite3BtreeNext() system call. All other cursors ** should be opened with wrFlag==1 even if they never really intend ** to write. ** ** No checking is done to make sure that page iTable really is the ** root page of a b-tree. If it is not, then the cursor acquired @@ -2951,11 +2951,11 @@ }else{ assert( pPage->leaf ); } insertCell(pPage, pCur->idx, &newCell, szNew); rc = balance(pPage); - /* sqliteBtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ + /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ /* fflush(stdout); */ moveToRoot(pCur); pCur->eSkip = SKIP_INVALID; return rc; } @@ -3159,40 +3159,43 @@ return rc; } /* -** Read the meta-information out of a database file. +** Read the meta-information out of a database file. Meta[0] +** is the number of free pages currently in the database. Meta[1] +** through meta[15] are available for use by higher layers. */ int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){ int rc; int i; unsigned char *pP1; - assert( idx>=0 && idx<15 ); + assert( idx>=0 && idx<=15 ); rc = sqlitepager_get(pBt->pPager, 1, (void**)&pP1); if( rc ) return rc; - *pMeta = get4byte(&pP1[40 + idx*4]); + *pMeta = get4byte(&pP1[36 + idx*4]); sqlitepager_unref(pP1); return SQLITE_OK; } /* -** Write meta-information back into the database. +** Write meta-information back into the database. Meta[0] is +** read-only and may not be written. */ int sqlite3BtreeUpdateMeta(Btree *pBt, int idx, u32 iMeta){ unsigned char *pP1; int rc, i; - assert( idx>=0 && idx<15 ); + assert( idx>=1 && idx<=15 ); if( !pBt->inTrans ){ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; } rc = sqlitepager_get(pBt->pPager, 1, (void**)&pP1); if( rc ) return rc; rc = sqlitepager_write(pP1); if( rc ) return rc; - put4byte(&pP1[40 + idx*4], iMeta); + put4byte(&pP1[36 + idx*4], iMeta); return SQLITE_OK; } /****************************************************************************** ** The complete implementation of the BTree subsystem is above this line. @@ -3203,11 +3206,11 @@ /* ** Print a disassembly of the given page on standard output. This routine ** is used for debugging and testing only. */ #ifdef SQLITE_TEST -static int fileBtreePageDump(Btree *pBt, int pgno, int recursive){ +int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ int rc; MemPage *pPage; int i, j; int nFree; u16 idx; Index: src/test3.c ================================================================== --- src/test3.c +++ src/test3.c @@ -11,11 +11,11 @@ ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test3.c,v 1.23 2003/04/13 18:26:52 paul Exp $ +** $Id: test3.c,v 1.24 2004/05/04 17:27:28 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include "btree.h" #include "tcl.h" @@ -47,11 +47,11 @@ } return zName; } /* -** Usage: btree_open FILENAME +** Usage: btree_open FILENAME NCACHE FLAGS ** ** Open a new database */ static int btree_open( void *NotUsed, @@ -58,18 +58,20 @@ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Btree *pBt; - int rc; + int rc, nCache, flags; char zBuf[100]; - if( argc!=2 ){ + if( argc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " FILENAME\"", 0); + " FILENAME NCACHE FLAGS\"", 0); return TCL_ERROR; } - rc = sqliteBtreeFactory(0, argv[1], 0, 1000, &pBt); + if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; + if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR; + rc = sqlite3BtreeOpen(argv[1], &pBt, nCache, flags); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sprintf(zBuf,"%p", pBt); @@ -97,11 +99,11 @@ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeClose(pBt); + rc = sqlite3BtreeClose(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; @@ -124,11 +126,11 @@ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeBeginTrans(pBt); + rc = sqlite3BtreeBeginTrans(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; @@ -151,11 +153,11 @@ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeRollback(pBt); + rc = sqlite3BtreeRollback(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; @@ -178,20 +180,20 @@ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeCommit(pBt); + rc = sqlite3BtreeCommit(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; } /* -** Usage: btree_create_table ID +** Usage: btree_create_table ID FLAGS ** ** Create a new table in the database */ static int btree_create_table( void *NotUsed, @@ -198,19 +200,20 @@ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Btree *pBt; - int rc, iTable; + int rc, iTable, flags; char zBuf[30]; - if( argc!=2 ){ + if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); + " ID FLAGS\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeCreateTable(pBt, &iTable); + if( Tcl_GetInt(interp, argv[2], &flags) ) return TCL_ERROR; + rc = sqlite3BtreeCreateTable(pBt, &iTable, flags); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sprintf(zBuf, "%d", iTable); @@ -237,11 +240,11 @@ " ID TABLENUM\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; - rc = sqliteBtreeDropTable(pBt, iTable); + rc = sqlite3BtreeDropTable(pBt, iTable); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; @@ -266,17 +269,19 @@ " ID TABLENUM\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; - rc = sqliteBtreeClearTable(pBt, iTable); + rc = sqlite3BtreeClearTable(pBt, iTable); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; } + +#define SQLITE_N_BTREE_META 16 /* ** Usage: btree_get_meta ID ** ** Return meta data @@ -288,25 +293,25 @@ const char **argv /* Text of each argument */ ){ Btree *pBt; int rc; int i; - int aMeta[SQLITE_N_BTREE_META]; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeGetMeta(pBt, aMeta); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } for(i=0; i