| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2001 September 15 | 2 ** 2001 September 15 |
| 3 ** | 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
| 6 ** | 6 ** |
| 7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
| 10 ** | 10 ** |
| 11 ************************************************************************* | 11 ************************************************************************* |
| 12 ** Code for testing the btree.c module in SQLite. This code | 12 ** Code for testing the btree.c module in SQLite. This code |
| 13 ** is not included in the SQLite library. It is used for automated | 13 ** is not included in the SQLite library. It is used for automated |
| 14 ** testing of the SQLite library. | 14 ** testing of the SQLite library. |
| 15 */ | 15 */ |
| 16 #include "sqliteInt.h" | 16 #include "sqliteInt.h" |
| 17 #include "btreeInt.h" | 17 #include "btreeInt.h" |
| 18 #include "tcl.h" | 18 #include "tcl.h" |
| 19 #include <stdlib.h> | 19 #include <stdlib.h> |
| 20 #include <string.h> | 20 #include <string.h> |
| 21 | 21 |
| 22 /* | 22 extern const char *sqlite3ErrName(int); |
| 23 ** Interpret an SQLite error number | |
| 24 */ | |
| 25 static char *errorName(int rc){ | |
| 26 char *zName; | |
| 27 switch( rc ){ | |
| 28 case SQLITE_OK: zName = "SQLITE_OK"; break; | |
| 29 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; | |
| 30 case SQLITE_PERM: zName = "SQLITE_PERM"; break; | |
| 31 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; | |
| 32 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; | |
| 33 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; | |
| 34 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; | |
| 35 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; | |
| 36 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; | |
| 37 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; | |
| 38 case SQLITE_FULL: zName = "SQLITE_FULL"; break; | |
| 39 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; | |
| 40 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; | |
| 41 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; | |
| 42 case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; | |
| 43 default: zName = "SQLITE_Unknown"; break; | |
| 44 } | |
| 45 return zName; | |
| 46 } | |
| 47 | 23 |
| 48 /* | 24 /* |
| 49 ** A bogus sqlite3 connection structure for use in the btree | 25 ** A bogus sqlite3 connection structure for use in the btree |
| 50 ** tests. | 26 ** tests. |
| 51 */ | 27 */ |
| 52 static sqlite3 sDb; | 28 static sqlite3 sDb; |
| 53 static int nRefSqlite3 = 0; | 29 static int nRefSqlite3 = 0; |
| 54 | 30 |
| 55 /* | 31 /* |
| 56 ** Usage: btree_open FILENAME NCACHE | 32 ** Usage: btree_open FILENAME NCACHE |
| 57 ** | 33 ** |
| 58 ** Open a new database | 34 ** Open a new database |
| 59 */ | 35 */ |
| 60 static int btree_open( | 36 static int btree_open( |
| 61 void *NotUsed, | 37 void *NotUsed, |
| 62 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ | 38 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
| 63 int argc, /* Number of arguments */ | 39 int argc, /* Number of arguments */ |
| 64 const char **argv /* Text of each argument */ | 40 const char **argv /* Text of each argument */ |
| 65 ){ | 41 ){ |
| 66 Btree *pBt; | 42 Btree *pBt; |
| 67 int rc, nCache; | 43 int rc, nCache; |
| 68 char zBuf[100]; | 44 char zBuf[100]; |
| 45 int n; |
| 46 char *zFilename; |
| 69 if( argc!=3 ){ | 47 if( argc!=3 ){ |
| 70 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], | 48 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
| 71 " FILENAME NCACHE FLAGS\"", 0); | 49 " FILENAME NCACHE FLAGS\"", 0); |
| 72 return TCL_ERROR; | 50 return TCL_ERROR; |
| 73 } | 51 } |
| 74 if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; | 52 if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; |
| 75 nRefSqlite3++; | 53 nRefSqlite3++; |
| 76 if( nRefSqlite3==1 ){ | 54 if( nRefSqlite3==1 ){ |
| 77 sDb.pVfs = sqlite3_vfs_find(0); | 55 sDb.pVfs = sqlite3_vfs_find(0); |
| 78 sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); | 56 sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); |
| 79 sqlite3_mutex_enter(sDb.mutex); | 57 sqlite3_mutex_enter(sDb.mutex); |
| 80 } | 58 } |
| 81 rc = sqlite3BtreeOpen(argv[1], &sDb, &pBt, 0, | 59 n = (int)strlen(argv[1]); |
| 60 zFilename = sqlite3_malloc( n+2 ); |
| 61 if( zFilename==0 ) return TCL_ERROR; |
| 62 memcpy(zFilename, argv[1], n+1); |
| 63 zFilename[n+1] = 0; |
| 64 rc = sqlite3BtreeOpen(sDb.pVfs, zFilename, &sDb, &pBt, 0, |
| 82 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB); | 65 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB); |
| 66 sqlite3_free(zFilename); |
| 83 if( rc!=SQLITE_OK ){ | 67 if( rc!=SQLITE_OK ){ |
| 84 Tcl_AppendResult(interp, errorName(rc), 0); | 68 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
| 85 return TCL_ERROR; | 69 return TCL_ERROR; |
| 86 } | 70 } |
| 87 sqlite3BtreeSetCacheSize(pBt, nCache); | 71 sqlite3BtreeSetCacheSize(pBt, nCache); |
| 88 sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pBt); | 72 sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pBt); |
| 89 Tcl_AppendResult(interp, zBuf, 0); | 73 Tcl_AppendResult(interp, zBuf, 0); |
| 90 return TCL_OK; | 74 return TCL_OK; |
| 91 } | 75 } |
| 92 | 76 |
| 93 /* | 77 /* |
| 94 ** Usage: btree_close ID | 78 ** Usage: btree_close ID |
| 95 ** | 79 ** |
| 96 ** Close the given database. | 80 ** Close the given database. |
| 97 */ | 81 */ |
| 98 static int btree_close( | 82 static int btree_close( |
| 99 void *NotUsed, | 83 void *NotUsed, |
| 100 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ | 84 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
| 101 int argc, /* Number of arguments */ | 85 int argc, /* Number of arguments */ |
| 102 const char **argv /* Text of each argument */ | 86 const char **argv /* Text of each argument */ |
| 103 ){ | 87 ){ |
| 104 Btree *pBt; | 88 Btree *pBt; |
| 105 int rc; | 89 int rc; |
| 106 if( argc!=2 ){ | 90 if( argc!=2 ){ |
| 107 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], | 91 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
| 108 " ID\"", 0); | 92 " ID\"", 0); |
| 109 return TCL_ERROR; | 93 return TCL_ERROR; |
| 110 } | 94 } |
| 111 pBt = sqlite3TestTextToPtr(argv[1]); | 95 pBt = sqlite3TestTextToPtr(argv[1]); |
| 112 rc = sqlite3BtreeClose(pBt); | 96 rc = sqlite3BtreeClose(pBt); |
| 113 if( rc!=SQLITE_OK ){ | 97 if( rc!=SQLITE_OK ){ |
| 114 Tcl_AppendResult(interp, errorName(rc), 0); | 98 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
| 115 return TCL_ERROR; | 99 return TCL_ERROR; |
| 116 } | 100 } |
| 117 nRefSqlite3--; | 101 nRefSqlite3--; |
| 118 if( nRefSqlite3==0 ){ | 102 if( nRefSqlite3==0 ){ |
| 119 sqlite3_mutex_leave(sDb.mutex); | 103 sqlite3_mutex_leave(sDb.mutex); |
| 120 sqlite3_mutex_free(sDb.mutex); | 104 sqlite3_mutex_free(sDb.mutex); |
| 121 sDb.mutex = 0; | 105 sDb.mutex = 0; |
| 122 sDb.pVfs = 0; | 106 sDb.pVfs = 0; |
| 123 } | 107 } |
| 124 return TCL_OK; | 108 return TCL_OK; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 141 if( argc!=2 ){ | 125 if( argc!=2 ){ |
| 142 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], | 126 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
| 143 " ID\"", 0); | 127 " ID\"", 0); |
| 144 return TCL_ERROR; | 128 return TCL_ERROR; |
| 145 } | 129 } |
| 146 pBt = sqlite3TestTextToPtr(argv[1]); | 130 pBt = sqlite3TestTextToPtr(argv[1]); |
| 147 sqlite3BtreeEnter(pBt); | 131 sqlite3BtreeEnter(pBt); |
| 148 rc = sqlite3BtreeBeginTrans(pBt, 1); | 132 rc = sqlite3BtreeBeginTrans(pBt, 1); |
| 149 sqlite3BtreeLeave(pBt); | 133 sqlite3BtreeLeave(pBt); |
| 150 if( rc!=SQLITE_OK ){ | 134 if( rc!=SQLITE_OK ){ |
| 151 Tcl_AppendResult(interp, errorName(rc), 0); | 135 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
| 152 return TCL_ERROR; | 136 return TCL_ERROR; |
| 153 } | 137 } |
| 154 return TCL_OK; | 138 return TCL_OK; |
| 155 } | 139 } |
| 156 | 140 |
| 157 /* | 141 /* |
| 158 ** Usage: btree_pager_stats ID | 142 ** Usage: btree_pager_stats ID |
| 159 ** | 143 ** |
| 160 ** Returns pager statistics | 144 ** Returns pager statistics |
| 161 */ | 145 */ |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 sqlite3BtreeEnter(pBt); | 219 sqlite3BtreeEnter(pBt); |
| 236 #ifndef SQLITE_OMIT_SHARED_CACHE | 220 #ifndef SQLITE_OMIT_SHARED_CACHE |
| 237 rc = sqlite3BtreeLockTable(pBt, iTable, wrFlag); | 221 rc = sqlite3BtreeLockTable(pBt, iTable, wrFlag); |
| 238 #endif | 222 #endif |
| 239 if( rc==SQLITE_OK ){ | 223 if( rc==SQLITE_OK ){ |
| 240 rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur); | 224 rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur); |
| 241 } | 225 } |
| 242 sqlite3BtreeLeave(pBt); | 226 sqlite3BtreeLeave(pBt); |
| 243 if( rc ){ | 227 if( rc ){ |
| 244 ckfree((char *)pCur); | 228 ckfree((char *)pCur); |
| 245 Tcl_AppendResult(interp, errorName(rc), 0); | 229 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
| 246 return TCL_ERROR; | 230 return TCL_ERROR; |
| 247 } | 231 } |
| 248 sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur); | 232 sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur); |
| 249 Tcl_AppendResult(interp, zBuf, 0); | 233 Tcl_AppendResult(interp, zBuf, 0); |
| 250 return SQLITE_OK; | 234 return SQLITE_OK; |
| 251 } | 235 } |
| 252 | 236 |
| 253 /* | 237 /* |
| 254 ** Usage: btree_close_cursor ID | 238 ** Usage: btree_close_cursor ID |
| 255 ** | 239 ** |
| (...skipping 14 matching lines...) Expand all Loading... |
| 270 " ID\"", 0); | 254 " ID\"", 0); |
| 271 return TCL_ERROR; | 255 return TCL_ERROR; |
| 272 } | 256 } |
| 273 pCur = sqlite3TestTextToPtr(argv[1]); | 257 pCur = sqlite3TestTextToPtr(argv[1]); |
| 274 pBt = pCur->pBtree; | 258 pBt = pCur->pBtree; |
| 275 sqlite3BtreeEnter(pBt); | 259 sqlite3BtreeEnter(pBt); |
| 276 rc = sqlite3BtreeCloseCursor(pCur); | 260 rc = sqlite3BtreeCloseCursor(pCur); |
| 277 sqlite3BtreeLeave(pBt); | 261 sqlite3BtreeLeave(pBt); |
| 278 ckfree((char *)pCur); | 262 ckfree((char *)pCur); |
| 279 if( rc ){ | 263 if( rc ){ |
| 280 Tcl_AppendResult(interp, errorName(rc), 0); | 264 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
| 281 return TCL_ERROR; | 265 return TCL_ERROR; |
| 282 } | 266 } |
| 283 return SQLITE_OK; | 267 return SQLITE_OK; |
| 284 } | 268 } |
| 285 | 269 |
| 286 /* | 270 /* |
| 287 ** Usage: btree_next ID | 271 ** Usage: btree_next ID |
| 288 ** | 272 ** |
| 289 ** Move the cursor to the next entry in the table. Return 0 on success | 273 ** Move the cursor to the next entry in the table. Return 0 on success |
| 290 ** or 1 if the cursor was already on the last entry in the table or if | 274 ** or 1 if the cursor was already on the last entry in the table or if |
| (...skipping 13 matching lines...) Expand all Loading... |
| 304 if( argc!=2 ){ | 288 if( argc!=2 ){ |
| 305 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], | 289 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
| 306 " ID\"", 0); | 290 " ID\"", 0); |
| 307 return TCL_ERROR; | 291 return TCL_ERROR; |
| 308 } | 292 } |
| 309 pCur = sqlite3TestTextToPtr(argv[1]); | 293 pCur = sqlite3TestTextToPtr(argv[1]); |
| 310 sqlite3BtreeEnter(pCur->pBtree); | 294 sqlite3BtreeEnter(pCur->pBtree); |
| 311 rc = sqlite3BtreeNext(pCur, &res); | 295 rc = sqlite3BtreeNext(pCur, &res); |
| 312 sqlite3BtreeLeave(pCur->pBtree); | 296 sqlite3BtreeLeave(pCur->pBtree); |
| 313 if( rc ){ | 297 if( rc ){ |
| 314 Tcl_AppendResult(interp, errorName(rc), 0); | 298 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
| 315 return TCL_ERROR; | 299 return TCL_ERROR; |
| 316 } | 300 } |
| 317 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res); | 301 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res); |
| 318 Tcl_AppendResult(interp, zBuf, 0); | 302 Tcl_AppendResult(interp, zBuf, 0); |
| 319 return SQLITE_OK; | 303 return SQLITE_OK; |
| 320 } | 304 } |
| 321 | 305 |
| 322 /* | 306 /* |
| 323 ** Usage: btree_first ID | 307 ** Usage: btree_first ID |
| 324 ** | 308 ** |
| (...skipping 14 matching lines...) Expand all Loading... |
| 339 if( argc!=2 ){ | 323 if( argc!=2 ){ |
| 340 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], | 324 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
| 341 " ID\"", 0); | 325 " ID\"", 0); |
| 342 return TCL_ERROR; | 326 return TCL_ERROR; |
| 343 } | 327 } |
| 344 pCur = sqlite3TestTextToPtr(argv[1]); | 328 pCur = sqlite3TestTextToPtr(argv[1]); |
| 345 sqlite3BtreeEnter(pCur->pBtree); | 329 sqlite3BtreeEnter(pCur->pBtree); |
| 346 rc = sqlite3BtreeFirst(pCur, &res); | 330 rc = sqlite3BtreeFirst(pCur, &res); |
| 347 sqlite3BtreeLeave(pCur->pBtree); | 331 sqlite3BtreeLeave(pCur->pBtree); |
| 348 if( rc ){ | 332 if( rc ){ |
| 349 Tcl_AppendResult(interp, errorName(rc), 0); | 333 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
| 350 return TCL_ERROR; | 334 return TCL_ERROR; |
| 351 } | 335 } |
| 352 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res); | 336 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res); |
| 353 Tcl_AppendResult(interp, zBuf, 0); | 337 Tcl_AppendResult(interp, zBuf, 0); |
| 354 return SQLITE_OK; | 338 return SQLITE_OK; |
| 355 } | 339 } |
| 356 | 340 |
| 357 /* | 341 /* |
| 358 ** Usage: btree_eof ID | 342 ** Usage: btree_eof ID |
| 359 ** | 343 ** |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], | 434 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
| 451 " START MULTIPLIER COUNT INCREMENT\"", 0); | 435 " START MULTIPLIER COUNT INCREMENT\"", 0); |
| 452 return TCL_ERROR; | 436 return TCL_ERROR; |
| 453 } | 437 } |
| 454 if( Tcl_GetInt(interp, argv[1], (int*)&start) ) return TCL_ERROR; | 438 if( Tcl_GetInt(interp, argv[1], (int*)&start) ) return TCL_ERROR; |
| 455 if( Tcl_GetInt(interp, argv[2], (int*)&mult) ) return TCL_ERROR; | 439 if( Tcl_GetInt(interp, argv[2], (int*)&mult) ) return TCL_ERROR; |
| 456 if( Tcl_GetInt(interp, argv[3], (int*)&count) ) return TCL_ERROR; | 440 if( Tcl_GetInt(interp, argv[3], (int*)&count) ) return TCL_ERROR; |
| 457 if( Tcl_GetInt(interp, argv[4], (int*)&incr) ) return TCL_ERROR; | 441 if( Tcl_GetInt(interp, argv[4], (int*)&incr) ) return TCL_ERROR; |
| 458 in = start; | 442 in = start; |
| 459 in *= mult; | 443 in *= mult; |
| 460 for(i=0; i<count; i++){ | 444 for(i=0; i<(int)count; i++){ |
| 461 char zErr[200]; | 445 char zErr[200]; |
| 462 n1 = putVarint(zBuf, in); | 446 n1 = putVarint(zBuf, in); |
| 463 if( n1>9 || n1<1 ){ | 447 if( n1>9 || n1<1 ){ |
| 464 sprintf(zErr, "putVarint returned %d - should be between 1 and 9", n1); | 448 sprintf(zErr, "putVarint returned %d - should be between 1 and 9", n1); |
| 465 Tcl_AppendResult(interp, zErr, 0); | 449 Tcl_AppendResult(interp, zErr, 0); |
| 466 return TCL_ERROR; | 450 return TCL_ERROR; |
| 467 } | 451 } |
| 468 n2 = getVarint(zBuf, &out); | 452 n2 = getVarint(zBuf, &out); |
| 469 if( n1!=n2 ){ | 453 if( n1!=n2 ){ |
| 470 sprintf(zErr, "putVarint returned %d and getVarint returned %d", n1, n2); | 454 sprintf(zErr, "putVarint returned %d and getVarint returned %d", n1, n2); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 { "btree_set_cache_size", (Tcl_CmdProc*)btree_set_cache_size } | 619 { "btree_set_cache_size", (Tcl_CmdProc*)btree_set_cache_size } |
| 636 }; | 620 }; |
| 637 int i; | 621 int i; |
| 638 | 622 |
| 639 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ | 623 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ |
| 640 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); | 624 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); |
| 641 } | 625 } |
| 642 | 626 |
| 643 return TCL_OK; | 627 return TCL_OK; |
| 644 } | 628 } |
| OLD | NEW |