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 |