Main Page | Directories | File List

test3.c

00001 /*
00002 ** 2001 September 15
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** Code for testing the btree.c module in SQLite.  This code
00013 ** is not included in the SQLite library.  It is used for automated
00014 ** testing of the SQLite library.
00015 **
00016 ** $Id: test3.c,v 1.23 2003/04/13 18:26:52 paul Exp $
00017 */
00018 #include "sqliteInt.h"
00019 #include "pager.h"
00020 #include "btree.h"
00021 #include "tcl.h"
00022 #include <stdlib.h>
00023 #include <string.h>
00024 
00025 /*
00026 ** Interpret an SQLite error number
00027 */
00028 static char *errorName(int rc){
00029   char *zName;
00030   switch( rc ){
00031     case SQLITE_OK:         zName = "SQLITE_OK";          break;
00032     case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
00033     case SQLITE_INTERNAL:   zName = "SQLITE_INTERNAL";    break;
00034     case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
00035     case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
00036     case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
00037     case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
00038     case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
00039     case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
00040     case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
00041     case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
00042     case SQLITE_NOTFOUND:   zName = "SQLITE_NOTFOUND";    break;
00043     case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
00044     case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
00045     case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
00046     default:                zName = "SQLITE_Unknown";     break;
00047   }
00048   return zName;
00049 }
00050 
00051 /*
00052 ** Usage:   btree_open FILENAME
00053 **
00054 ** Open a new database
00055 */
00056 static int btree_open(
00057   void *NotUsed,
00058   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00059   int argc,              /* Number of arguments */
00060   const char **argv      /* Text of each argument */
00061 ){
00062   Btree *pBt;
00063   int rc;
00064   char zBuf[100];
00065   if( argc!=2 ){
00066     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00067        " FILENAME\"", 0);
00068     return TCL_ERROR;
00069   }
00070   rc = sqliteBtreeFactory(0, argv[1], 0, 1000, &pBt);
00071   if( rc!=SQLITE_OK ){
00072     Tcl_AppendResult(interp, errorName(rc), 0);
00073     return TCL_ERROR;
00074   }
00075   sprintf(zBuf,"%p", pBt);
00076   if( strncmp(zBuf,"0x",2) ){
00077     sprintf(zBuf, "0x%p", pBt);
00078   }
00079   Tcl_AppendResult(interp, zBuf, 0);
00080   return TCL_OK;
00081 }
00082 
00083 /*
00084 ** Usage:   btree_close ID
00085 **
00086 ** Close the given database.
00087 */
00088 static int btree_close(
00089   void *NotUsed,
00090   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00091   int argc,              /* Number of arguments */
00092   const char **argv      /* Text of each argument */
00093 ){
00094   Btree *pBt;
00095   int rc;
00096   if( argc!=2 ){
00097     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00098        " ID\"", 0);
00099     return TCL_ERROR;
00100   }
00101   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00102   rc = sqliteBtreeClose(pBt);
00103   if( rc!=SQLITE_OK ){
00104     Tcl_AppendResult(interp, errorName(rc), 0);
00105     return TCL_ERROR;
00106   }
00107   return TCL_OK;
00108 }
00109 
00110 /*
00111 ** Usage:   btree_begin_transaction ID
00112 **
00113 ** Start a new transaction
00114 */
00115 static int btree_begin_transaction(
00116   void *NotUsed,
00117   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00118   int argc,              /* Number of arguments */
00119   const char **argv      /* Text of each argument */
00120 ){
00121   Btree *pBt;
00122   int rc;
00123   if( argc!=2 ){
00124     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00125        " ID\"", 0);
00126     return TCL_ERROR;
00127   }
00128   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00129   rc = sqliteBtreeBeginTrans(pBt);
00130   if( rc!=SQLITE_OK ){
00131     Tcl_AppendResult(interp, errorName(rc), 0);
00132     return TCL_ERROR;
00133   }
00134   return TCL_OK;
00135 }
00136 
00137 /*
00138 ** Usage:   btree_rollback ID
00139 **
00140 ** Rollback changes
00141 */
00142 static int btree_rollback(
00143   void *NotUsed,
00144   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00145   int argc,              /* Number of arguments */
00146   const char **argv      /* Text of each argument */
00147 ){
00148   Btree *pBt;
00149   int rc;
00150   if( argc!=2 ){
00151     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00152        " ID\"", 0);
00153     return TCL_ERROR;
00154   }
00155   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00156   rc = sqliteBtreeRollback(pBt);
00157   if( rc!=SQLITE_OK ){
00158     Tcl_AppendResult(interp, errorName(rc), 0);
00159     return TCL_ERROR;
00160   }
00161   return TCL_OK;
00162 }
00163 
00164 /*
00165 ** Usage:   btree_commit ID
00166 **
00167 ** Commit all changes
00168 */
00169 static int btree_commit(
00170   void *NotUsed,
00171   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00172   int argc,              /* Number of arguments */
00173   const char **argv      /* Text of each argument */
00174 ){
00175   Btree *pBt;
00176   int rc;
00177   if( argc!=2 ){
00178     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00179        " ID\"", 0);
00180     return TCL_ERROR;
00181   }
00182   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00183   rc = sqliteBtreeCommit(pBt);
00184   if( rc!=SQLITE_OK ){
00185     Tcl_AppendResult(interp, errorName(rc), 0);
00186     return TCL_ERROR;
00187   }
00188   return TCL_OK;
00189 }
00190 
00191 /*
00192 ** Usage:   btree_create_table ID
00193 **
00194 ** Create a new table in the database
00195 */
00196 static int btree_create_table(
00197   void *NotUsed,
00198   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00199   int argc,              /* Number of arguments */
00200   const char **argv      /* Text of each argument */
00201 ){
00202   Btree *pBt;
00203   int rc, iTable;
00204   char zBuf[30];
00205   if( argc!=2 ){
00206     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00207        " ID\"", 0);
00208     return TCL_ERROR;
00209   }
00210   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00211   rc = sqliteBtreeCreateTable(pBt, &iTable);
00212   if( rc!=SQLITE_OK ){
00213     Tcl_AppendResult(interp, errorName(rc), 0);
00214     return TCL_ERROR;
00215   }
00216   sprintf(zBuf, "%d", iTable);
00217   Tcl_AppendResult(interp, zBuf, 0);
00218   return TCL_OK;
00219 }
00220 
00221 /*
00222 ** Usage:   btree_drop_table ID TABLENUM
00223 **
00224 ** Delete an entire table from the database
00225 */
00226 static int btree_drop_table(
00227   void *NotUsed,
00228   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00229   int argc,              /* Number of arguments */
00230   const char **argv      /* Text of each argument */
00231 ){
00232   Btree *pBt;
00233   int iTable;
00234   int rc;
00235   if( argc!=3 ){
00236     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00237        " ID TABLENUM\"", 0);
00238     return TCL_ERROR;
00239   }
00240   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00241   if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
00242   rc = sqliteBtreeDropTable(pBt, iTable);
00243   if( rc!=SQLITE_OK ){
00244     Tcl_AppendResult(interp, errorName(rc), 0);
00245     return TCL_ERROR;
00246   }
00247   return TCL_OK;
00248 }
00249 
00250 /*
00251 ** Usage:   btree_clear_table ID TABLENUM
00252 **
00253 ** Remove all entries from the given table but keep the table around.
00254 */
00255 static int btree_clear_table(
00256   void *NotUsed,
00257   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00258   int argc,              /* Number of arguments */
00259   const char **argv      /* Text of each argument */
00260 ){
00261   Btree *pBt;
00262   int iTable;
00263   int rc;
00264   if( argc!=3 ){
00265     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00266        " ID TABLENUM\"", 0);
00267     return TCL_ERROR;
00268   }
00269   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00270   if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
00271   rc = sqliteBtreeClearTable(pBt, iTable);
00272   if( rc!=SQLITE_OK ){
00273     Tcl_AppendResult(interp, errorName(rc), 0);
00274     return TCL_ERROR;
00275   }
00276   return TCL_OK;
00277 }
00278 
00279 /*
00280 ** Usage:   btree_get_meta ID
00281 **
00282 ** Return meta data
00283 */
00284 static int btree_get_meta(
00285   void *NotUsed,
00286   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00287   int argc,              /* Number of arguments */
00288   const char **argv      /* Text of each argument */
00289 ){
00290   Btree *pBt;
00291   int rc;
00292   int i;
00293   int aMeta[SQLITE_N_BTREE_META];
00294   if( argc!=2 ){
00295     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00296        " ID\"", 0);
00297     return TCL_ERROR;
00298   }
00299   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00300   rc = sqliteBtreeGetMeta(pBt, aMeta);
00301   if( rc!=SQLITE_OK ){
00302     Tcl_AppendResult(interp, errorName(rc), 0);
00303     return TCL_ERROR;
00304   }
00305   for(i=0; i<SQLITE_N_BTREE_META; i++){
00306     char zBuf[30];
00307     sprintf(zBuf,"%d",aMeta[i]);
00308     Tcl_AppendElement(interp, zBuf);
00309   }
00310   return TCL_OK;
00311 }
00312 
00313 /*
00314 ** Usage:   btree_update_meta ID METADATA...
00315 **
00316 ** Return meta data
00317 */
00318 static int btree_update_meta(
00319   void *NotUsed,
00320   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00321   int argc,              /* Number of arguments */
00322   const char **argv      /* Text of each argument */
00323 ){
00324   Btree *pBt;
00325   int rc;
00326   int i;
00327   int aMeta[SQLITE_N_BTREE_META];
00328 
00329   if( argc!=2+SQLITE_N_BTREE_META ){
00330     char zBuf[30];
00331     sprintf(zBuf,"%d",SQLITE_N_BTREE_META);
00332     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00333        " ID METADATA...\" (METADATA is ", zBuf, " integers)", 0);
00334     return TCL_ERROR;
00335   }
00336   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00337   for(i=0; i<SQLITE_N_BTREE_META; i++){
00338     if( Tcl_GetInt(interp, argv[i+2], &aMeta[i]) ) return TCL_ERROR;
00339   }
00340   rc = sqliteBtreeUpdateMeta(pBt, aMeta);
00341   if( rc!=SQLITE_OK ){
00342     Tcl_AppendResult(interp, errorName(rc), 0);
00343     return TCL_ERROR;
00344   }
00345   return TCL_OK;
00346 }
00347 
00348 /*
00349 ** Usage:   btree_page_dump ID PAGENUM
00350 **
00351 ** Print a disassembly of a page on standard output
00352 */
00353 static int btree_page_dump(
00354   void *NotUsed,
00355   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00356   int argc,              /* Number of arguments */
00357   const char **argv      /* Text of each argument */
00358 ){
00359   Btree *pBt;
00360   int iPage;
00361   int rc;
00362 
00363   if( argc!=3 ){
00364     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00365        " ID\"", 0);
00366     return TCL_ERROR;
00367   }
00368   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00369   if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR;
00370   rc = sqliteBtreePageDump(pBt, iPage, 0);
00371   if( rc!=SQLITE_OK ){
00372     Tcl_AppendResult(interp, errorName(rc), 0);
00373     return TCL_ERROR;
00374   }
00375   return TCL_OK;
00376 }
00377 
00378 /*
00379 ** Usage:   btree_tree_dump ID PAGENUM
00380 **
00381 ** Print a disassembly of a page and all its child pages on standard output
00382 */
00383 static int btree_tree_dump(
00384   void *NotUsed,
00385   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00386   int argc,              /* Number of arguments */
00387   const char **argv      /* Text of each argument */
00388 ){
00389   Btree *pBt;
00390   int iPage;
00391   int rc;
00392 
00393   if( argc!=3 ){
00394     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00395        " ID\"", 0);
00396     return TCL_ERROR;
00397   }
00398   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00399   if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR;
00400   rc = sqliteBtreePageDump(pBt, iPage, 1);
00401   if( rc!=SQLITE_OK ){
00402     Tcl_AppendResult(interp, errorName(rc), 0);
00403     return TCL_ERROR;
00404   }
00405   return TCL_OK;
00406 }
00407 
00408 /*
00409 ** Usage:   btree_pager_stats ID
00410 **
00411 ** Returns pager statistics
00412 */
00413 static int btree_pager_stats(
00414   void *NotUsed,
00415   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00416   int argc,              /* Number of arguments */
00417   const char **argv      /* Text of each argument */
00418 ){
00419   Btree *pBt;
00420   int i;
00421   int *a;
00422 
00423   if( argc!=2 ){
00424     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00425        " ID\"", 0);
00426     return TCL_ERROR;
00427   }
00428   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00429   a = sqlitepager_stats(sqliteBtreePager(pBt));
00430   for(i=0; i<9; i++){
00431     static char *zName[] = {
00432       "ref", "page", "max", "size", "state", "err",
00433       "hit", "miss", "ovfl",
00434     };
00435     char zBuf[100];
00436     Tcl_AppendElement(interp, zName[i]);
00437     sprintf(zBuf,"%d",a[i]);
00438     Tcl_AppendElement(interp, zBuf);
00439   }
00440   return TCL_OK;
00441 }
00442 
00443 /*
00444 ** Usage:   btree_pager_ref_dump ID
00445 **
00446 ** Print out all outstanding pages.
00447 */
00448 static int btree_pager_ref_dump(
00449   void *NotUsed,
00450   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00451   int argc,              /* Number of arguments */
00452   const char **argv      /* Text of each argument */
00453 ){
00454   Btree *pBt;
00455 
00456   if( argc!=2 ){
00457     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00458        " ID\"", 0);
00459     return TCL_ERROR;
00460   }
00461   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00462   sqlitepager_refdump(sqliteBtreePager(pBt));
00463   return TCL_OK;
00464 }
00465 
00466 /*
00467 ** Usage:   btree_integrity_check ID ROOT ...
00468 **
00469 ** Look through every page of the given BTree file to verify correct
00470 ** formatting and linkage.  Return a line of text for each problem found.
00471 ** Return an empty string if everything worked.
00472 */
00473 static int btree_integrity_check(
00474   void *NotUsed,
00475   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00476   int argc,              /* Number of arguments */
00477   const char **argv      /* Text of each argument */
00478 ){
00479   Btree *pBt;
00480   char *zResult;
00481   int nRoot;
00482   int *aRoot;
00483   int i;
00484 
00485   if( argc<3 ){
00486     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00487        " ID ROOT ...\"", 0);
00488     return TCL_ERROR;
00489   }
00490   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00491   nRoot = argc-2;
00492   aRoot = malloc( sizeof(int)*(argc-2) );
00493   for(i=0; i<argc-2; i++){
00494     if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR;
00495   }
00496   zResult = sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot);
00497   if( zResult ){
00498     Tcl_AppendResult(interp, zResult, 0);
00499     sqliteFree(zResult); 
00500   }
00501   return TCL_OK;
00502 }
00503 
00504 /*
00505 ** Usage:   btree_cursor ID TABLENUM WRITEABLE
00506 **
00507 ** Create a new cursor.  Return the ID for the cursor.
00508 */
00509 static int btree_cursor(
00510   void *NotUsed,
00511   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00512   int argc,              /* Number of arguments */
00513   const char **argv      /* Text of each argument */
00514 ){
00515   Btree *pBt;
00516   int iTable;
00517   BtCursor *pCur;
00518   int rc;
00519   int wrFlag;
00520   char zBuf[30];
00521 
00522   if( argc!=4 ){
00523     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00524        " ID TABLENUM WRITEABLE\"", 0);
00525     return TCL_ERROR;
00526   }
00527   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
00528   if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
00529   if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
00530   rc = sqliteBtreeCursor(pBt, iTable, wrFlag, &pCur);
00531   if( rc ){
00532     Tcl_AppendResult(interp, errorName(rc), 0);
00533     return TCL_ERROR;
00534   }
00535   sprintf(zBuf,"0x%x", (int)pCur);
00536   Tcl_AppendResult(interp, zBuf, 0);
00537   return SQLITE_OK;
00538 }
00539 
00540 /*
00541 ** Usage:   btree_close_cursor ID
00542 **
00543 ** Close a cursor opened using btree_cursor.
00544 */
00545 static int btree_close_cursor(
00546   void *NotUsed,
00547   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00548   int argc,              /* Number of arguments */
00549   const char **argv      /* Text of each argument */
00550 ){
00551   BtCursor *pCur;
00552   int rc;
00553 
00554   if( argc!=2 ){
00555     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00556        " ID\"", 0);
00557     return TCL_ERROR;
00558   }
00559   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00560   rc = sqliteBtreeCloseCursor(pCur);
00561   if( rc ){
00562     Tcl_AppendResult(interp, errorName(rc), 0);
00563     return TCL_ERROR;
00564   }
00565   return SQLITE_OK;
00566 }
00567 
00568 /*
00569 ** Usage:   btree_move_to ID KEY
00570 **
00571 ** Move the cursor to the entry with the given key.
00572 */
00573 static int btree_move_to(
00574   void *NotUsed,
00575   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00576   int argc,              /* Number of arguments */
00577   const char **argv      /* Text of each argument */
00578 ){
00579   BtCursor *pCur;
00580   int rc;
00581   int res;
00582   char zBuf[20];
00583 
00584   if( argc!=3 ){
00585     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00586        " ID KEY\"", 0);
00587     return TCL_ERROR;
00588   }
00589   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00590   rc = sqliteBtreeMoveto(pCur, argv[2], strlen(argv[2]), &res);  
00591   if( rc ){
00592     Tcl_AppendResult(interp, errorName(rc), 0);
00593     return TCL_ERROR;
00594   }
00595   if( res<0 ) res = -1;
00596   if( res>0 ) res = 1;
00597   sprintf(zBuf,"%d",res);
00598   Tcl_AppendResult(interp, zBuf, 0);
00599   return SQLITE_OK;
00600 }
00601 
00602 /*
00603 ** Usage:   btree_delete ID
00604 **
00605 ** Delete the entry that the cursor is pointing to
00606 */
00607 static int btree_delete(
00608   void *NotUsed,
00609   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00610   int argc,              /* Number of arguments */
00611   const char **argv      /* Text of each argument */
00612 ){
00613   BtCursor *pCur;
00614   int rc;
00615 
00616   if( argc!=2 ){
00617     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00618        " ID\"", 0);
00619     return TCL_ERROR;
00620   }
00621   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00622   rc = sqliteBtreeDelete(pCur);
00623   if( rc ){
00624     Tcl_AppendResult(interp, errorName(rc), 0);
00625     return TCL_ERROR;
00626   }
00627   return SQLITE_OK;
00628 }
00629 
00630 /*
00631 ** Usage:   btree_insert ID KEY DATA
00632 **
00633 ** Create a new entry with the given key and data.  If an entry already
00634 ** exists with the same key the old entry is overwritten.
00635 */
00636 static int btree_insert(
00637   void *NotUsed,
00638   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00639   int argc,              /* Number of arguments */
00640   const char **argv      /* Text of each argument */
00641 ){
00642   BtCursor *pCur;
00643   int rc;
00644 
00645   if( argc!=4 ){
00646     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00647        " ID KEY DATA\"", 0);
00648     return TCL_ERROR;
00649   }
00650   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00651   rc = sqliteBtreeInsert(pCur, argv[2], strlen(argv[2]),
00652                          argv[3], strlen(argv[3]));
00653   if( rc ){
00654     Tcl_AppendResult(interp, errorName(rc), 0);
00655     return TCL_ERROR;
00656   }
00657   return SQLITE_OK;
00658 }
00659 
00660 /*
00661 ** Usage:   btree_next ID
00662 **
00663 ** Move the cursor to the next entry in the table.  Return 0 on success
00664 ** or 1 if the cursor was already on the last entry in the table or if
00665 ** the table is empty.
00666 */
00667 static int btree_next(
00668   void *NotUsed,
00669   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00670   int argc,              /* Number of arguments */
00671   const char **argv      /* Text of each argument */
00672 ){
00673   BtCursor *pCur;
00674   int rc;
00675   int res = 0;
00676   char zBuf[100];
00677 
00678   if( argc!=2 ){
00679     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00680        " ID\"", 0);
00681     return TCL_ERROR;
00682   }
00683   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00684   rc = sqliteBtreeNext(pCur, &res);
00685   if( rc ){
00686     Tcl_AppendResult(interp, errorName(rc), 0);
00687     return TCL_ERROR;
00688   }
00689   sprintf(zBuf,"%d",res);
00690   Tcl_AppendResult(interp, zBuf, 0);
00691   return SQLITE_OK;
00692 }
00693 
00694 /*
00695 ** Usage:   btree_prev ID
00696 **
00697 ** Move the cursor to the previous entry in the table.  Return 0 on
00698 ** success and 1 if the cursor was already on the first entry in
00699 ** the table or if the table was empty.
00700 */
00701 static int btree_prev(
00702   void *NotUsed,
00703   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00704   int argc,              /* Number of arguments */
00705   const char **argv      /* Text of each argument */
00706 ){
00707   BtCursor *pCur;
00708   int rc;
00709   int res = 0;
00710   char zBuf[100];
00711 
00712   if( argc!=2 ){
00713     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00714        " ID\"", 0);
00715     return TCL_ERROR;
00716   }
00717   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00718   rc = sqliteBtreePrevious(pCur, &res);
00719   if( rc ){
00720     Tcl_AppendResult(interp, errorName(rc), 0);
00721     return TCL_ERROR;
00722   }
00723   sprintf(zBuf,"%d",res);
00724   Tcl_AppendResult(interp, zBuf, 0);
00725   return SQLITE_OK;
00726 }
00727 
00728 /*
00729 ** Usage:   btree_first ID
00730 **
00731 ** Move the cursor to the first entry in the table.  Return 0 if the
00732 ** cursor was left point to something and 1 if the table is empty.
00733 */
00734 static int btree_first(
00735   void *NotUsed,
00736   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00737   int argc,              /* Number of arguments */
00738   const char **argv      /* Text of each argument */
00739 ){
00740   BtCursor *pCur;
00741   int rc;
00742   int res = 0;
00743   char zBuf[100];
00744 
00745   if( argc!=2 ){
00746     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00747        " ID\"", 0);
00748     return TCL_ERROR;
00749   }
00750   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00751   rc = sqliteBtreeFirst(pCur, &res);
00752   if( rc ){
00753     Tcl_AppendResult(interp, errorName(rc), 0);
00754     return TCL_ERROR;
00755   }
00756   sprintf(zBuf,"%d",res);
00757   Tcl_AppendResult(interp, zBuf, 0);
00758   return SQLITE_OK;
00759 }
00760 
00761 /*
00762 ** Usage:   btree_last ID
00763 **
00764 ** Move the cursor to the last entry in the table.  Return 0 if the
00765 ** cursor was left point to something and 1 if the table is empty.
00766 */
00767 static int btree_last(
00768   void *NotUsed,
00769   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00770   int argc,              /* Number of arguments */
00771   const char **argv      /* Text of each argument */
00772 ){
00773   BtCursor *pCur;
00774   int rc;
00775   int res = 0;
00776   char zBuf[100];
00777 
00778   if( argc!=2 ){
00779     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00780        " ID\"", 0);
00781     return TCL_ERROR;
00782   }
00783   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00784   rc = sqliteBtreeLast(pCur, &res);
00785   if( rc ){
00786     Tcl_AppendResult(interp, errorName(rc), 0);
00787     return TCL_ERROR;
00788   }
00789   sprintf(zBuf,"%d",res);
00790   Tcl_AppendResult(interp, zBuf, 0);
00791   return SQLITE_OK;
00792 }
00793 
00794 /*
00795 ** Usage:   btree_key ID
00796 **
00797 ** Return the key for the entry at which the cursor is pointing.
00798 */
00799 static int btree_key(
00800   void *NotUsed,
00801   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00802   int argc,              /* Number of arguments */
00803   const char **argv      /* Text of each argument */
00804 ){
00805   BtCursor *pCur;
00806   int rc;
00807   int n;
00808   char *zBuf;
00809 
00810   if( argc!=2 ){
00811     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00812        " ID\"", 0);
00813     return TCL_ERROR;
00814   }
00815   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00816   sqliteBtreeKeySize(pCur, &n);
00817   zBuf = malloc( n+1 );
00818   rc = sqliteBtreeKey(pCur, 0, n, zBuf);
00819   if( rc!=n ){
00820     char zMsg[100];
00821     free(zBuf);
00822     sprintf(zMsg, "truncated key: got %d of %d bytes", rc, n);
00823     Tcl_AppendResult(interp, zMsg, 0);
00824     return TCL_ERROR;
00825   }
00826   zBuf[n] = 0;
00827   Tcl_AppendResult(interp, zBuf, 0);
00828   free(zBuf);
00829   return SQLITE_OK;
00830 }
00831 
00832 /*
00833 ** Usage:   btree_data ID
00834 **
00835 ** Return the data for the entry at which the cursor is pointing.
00836 */
00837 static int btree_data(
00838   void *NotUsed,
00839   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00840   int argc,              /* Number of arguments */
00841   const char **argv      /* Text of each argument */
00842 ){
00843   BtCursor *pCur;
00844   int rc;
00845   int n;
00846   char *zBuf;
00847 
00848   if( argc!=2 ){
00849     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00850        " ID\"", 0);
00851     return TCL_ERROR;
00852   }
00853   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00854   sqliteBtreeDataSize(pCur, &n);
00855   zBuf = malloc( n+1 );
00856   rc = sqliteBtreeData(pCur, 0, n, zBuf);
00857   if( rc!=n ){
00858     char zMsg[100];
00859     free(zBuf);
00860     sprintf(zMsg, "truncated data: got %d of %d bytes", rc, n);
00861     Tcl_AppendResult(interp, zMsg, 0);
00862     return TCL_ERROR;
00863   }
00864   zBuf[n] = 0;
00865   Tcl_AppendResult(interp, zBuf, 0);
00866   free(zBuf);
00867   return SQLITE_OK;
00868 }
00869 
00870 /*
00871 ** Usage:   btree_payload_size ID
00872 **
00873 ** Return the number of bytes of payload
00874 */
00875 static int btree_payload_size(
00876   void *NotUsed,
00877   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00878   int argc,              /* Number of arguments */
00879   const char **argv      /* Text of each argument */
00880 ){
00881   BtCursor *pCur;
00882   int n1, n2;
00883   char zBuf[50];
00884 
00885   if( argc!=2 ){
00886     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00887        " ID\"", 0);
00888     return TCL_ERROR;
00889   }
00890   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00891   sqliteBtreeKeySize(pCur, &n1);
00892   sqliteBtreeDataSize(pCur, &n2);
00893   sprintf(zBuf, "%d", n1+n2);
00894   Tcl_AppendResult(interp, zBuf, 0);
00895   return SQLITE_OK;
00896 }
00897 
00898 /*
00899 ** Usage:   btree_cursor_dump ID
00900 **
00901 ** Return eight integers containing information about the entry the
00902 ** cursor is pointing to:
00903 **
00904 **   aResult[0] =  The page number
00905 **   aResult[1] =  The entry number
00906 **   aResult[2] =  Total number of entries on this page
00907 **   aResult[3] =  Size of this entry
00908 **   aResult[4] =  Number of free bytes on this page
00909 **   aResult[5] =  Number of free blocks on the page
00910 **   aResult[6] =  Page number of the left child of this entry
00911 **   aResult[7] =  Page number of the right child for the whole page
00912 */
00913 static int btree_cursor_dump(
00914   void *NotUsed,
00915   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
00916   int argc,              /* Number of arguments */
00917   const char **argv      /* Text of each argument */
00918 ){
00919   BtCursor *pCur;
00920   int rc;
00921   int i, j;
00922   int aResult[8];
00923   char zBuf[400];
00924 
00925   if( argc!=2 ){
00926     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00927        " ID\"", 0);
00928     return TCL_ERROR;
00929   }
00930   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
00931   rc = sqliteBtreeCursorDump(pCur, aResult);
00932   if( rc ){
00933     Tcl_AppendResult(interp, errorName(rc), 0);
00934     return TCL_ERROR;
00935   }
00936   j = 0;
00937   for(i=0; i<sizeof(aResult)/sizeof(aResult[0]); i++){
00938     sprintf(&zBuf[j]," %d", aResult[i]);
00939     j += strlen(&zBuf[j]);
00940   }
00941   Tcl_AppendResult(interp, &zBuf[1], 0);
00942   return SQLITE_OK;
00943 }
00944 
00945 /*
00946 ** Register commands with the TCL interpreter.
00947 */
00948 int Sqlitetest3_Init(Tcl_Interp *interp){
00949   static struct {
00950      char *zName;
00951      Tcl_CmdProc *xProc;
00952   } aCmd[] = {
00953      { "btree_open",               (Tcl_CmdProc*)btree_open               },
00954      { "btree_close",              (Tcl_CmdProc*)btree_close              },
00955      { "btree_begin_transaction",  (Tcl_CmdProc*)btree_begin_transaction  },
00956      { "btree_commit",             (Tcl_CmdProc*)btree_commit             },
00957      { "btree_rollback",           (Tcl_CmdProc*)btree_rollback           },
00958      { "btree_create_table",       (Tcl_CmdProc*)btree_create_table       },
00959      { "btree_drop_table",         (Tcl_CmdProc*)btree_drop_table         },
00960      { "btree_clear_table",        (Tcl_CmdProc*)btree_clear_table        },
00961      { "btree_get_meta",           (Tcl_CmdProc*)btree_get_meta           },
00962      { "btree_update_meta",        (Tcl_CmdProc*)btree_update_meta        },
00963      { "btree_page_dump",          (Tcl_CmdProc*)btree_page_dump          },
00964      { "btree_tree_dump",          (Tcl_CmdProc*)btree_tree_dump          },
00965      { "btree_pager_stats",        (Tcl_CmdProc*)btree_pager_stats        },
00966      { "btree_pager_ref_dump",     (Tcl_CmdProc*)btree_pager_ref_dump     },
00967      { "btree_cursor",             (Tcl_CmdProc*)btree_cursor             },
00968      { "btree_close_cursor",       (Tcl_CmdProc*)btree_close_cursor       },
00969      { "btree_move_to",            (Tcl_CmdProc*)btree_move_to            },
00970      { "btree_delete",             (Tcl_CmdProc*)btree_delete             },
00971      { "btree_insert",             (Tcl_CmdProc*)btree_insert             },
00972      { "btree_next",               (Tcl_CmdProc*)btree_next               },
00973      { "btree_prev",               (Tcl_CmdProc*)btree_prev               },
00974      { "btree_key",                (Tcl_CmdProc*)btree_key                },
00975      { "btree_data",               (Tcl_CmdProc*)btree_data               },
00976      { "btree_payload_size",       (Tcl_CmdProc*)btree_payload_size       },
00977      { "btree_first",              (Tcl_CmdProc*)btree_first              },
00978      { "btree_last",               (Tcl_CmdProc*)btree_last               },
00979      { "btree_cursor_dump",        (Tcl_CmdProc*)btree_cursor_dump        },
00980      { "btree_integrity_check",    (Tcl_CmdProc*)btree_integrity_check    },
00981   };
00982   int i;
00983 
00984   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
00985     Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
00986   }
00987   Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager_refinfo_enable,
00988      TCL_LINK_INT);
00989   Tcl_LinkVar(interp, "btree_native_byte_order",(char*)&btree_native_byte_order,
00990      TCL_LINK_INT);
00991   return TCL_OK;
00992 }

Generated on Sun Dec 25 12:29:52 2005 for sqlite 2.8.17 by  doxygen 1.4.2