** 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
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 */
/*
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;
**
** 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 */
** 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;
}
** 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;
** 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.
**
}
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;
/*
-** 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;
}
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;
}
** 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;
** 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"
}
/*
-** Usage: btree_open FILENAME
+** Usage: btree_open FILENAME NCACHE FLAGS
**
** Open a new database
*/
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;
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_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_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_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;
}
/*
-** Usage: btree_create_table ID
+** Usage: btree_create_table ID FLAGS
**
** Create a new table in the database
*/
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;
}
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;
}
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
**
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<SQLITE_N_BTREE_META; i++){
char zBuf[30];
- sprintf(zBuf,"%d",aMeta[i]);
+ unsigned int v;
+ rc = sqlite3BtreeGetMeta(pBt, i, &v);
+ if( rc!=SQLITE_OK ){
+ Tcl_AppendResult(interp, errorName(rc), 0);
+ return TCL_ERROR;
+ }
+ sprintf(zBuf,"%d",v);
Tcl_AppendElement(interp, zBuf);
}
return TCL_OK;
Btree *pBt;
int rc;
int i;
- int aMeta[SQLITE_N_BTREE_META];
+ int aMeta[SQLITE_N_BTREE_META-1];
if( argc!=2+SQLITE_N_BTREE_META ){
char zBuf[30];
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
- for(i=0; i<SQLITE_N_BTREE_META; i++){
+ for(i=0; i<SQLITE_N_BTREE_META-1; i++){
if( Tcl_GetInt(interp, argv[i+2], &aMeta[i]) ) return TCL_ERROR;
}
- rc = sqliteBtreeUpdateMeta(pBt, aMeta);
- if( rc!=SQLITE_OK ){
- Tcl_AppendResult(interp, errorName(rc), 0);
- return TCL_ERROR;
+ for(i=0; i<SQLITE_N_BTREE_META-1; i++){
+ rc = sqlite3BtreeUpdateMeta(pBt, i+1, aMeta[i]);
+ if( rc!=SQLITE_OK ){
+ Tcl_AppendResult(interp, errorName(rc), 0);
+ return TCL_ERROR;
+ }
}
return TCL_OK;
}
}
if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR;
- rc = sqliteBtreePageDump(pBt, iPage, 0);
+ rc = sqlite3BtreePageDump(pBt, iPage, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR;
- rc = sqliteBtreePageDump(pBt, iPage, 1);
+ rc = sqlite3BtreePageDump(pBt, iPage, 1);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
- a = sqlitepager_stats(sqliteBtreePager(pBt));
+ a = sqlitepager_stats(sqlite3BtreePager(pBt));
for(i=0; i<9; i++){
static char *zName[] = {
"ref", "page", "max", "size", "state", "err",
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
- sqlitepager_refdump(sqliteBtreePager(pBt));
+ sqlitepager_refdump(sqlite3BtreePager(pBt));
return TCL_OK;
}
for(i=0; i<argc-2; i++){
if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR;
}
- zResult = sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot);
+ zResult = sqlite3BtreeIntegrityCheck(pBt, aRoot, nRoot);
if( zResult ){
Tcl_AppendResult(interp, zResult, 0);
sqliteFree(zResult);
if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
- rc = sqliteBtreeCursor(pBt, iTable, wrFlag, &pCur);
+ rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, &pCur);
if( rc ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
- rc = sqliteBtreeCloseCursor(pCur);
+ rc = sqlite3BtreeCloseCursor(pCur);
if( rc ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
- rc = sqliteBtreeMoveto(pCur, argv[2], strlen(argv[2]), &res);
+ rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), &res);
if( rc ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;