|
1 /* |
|
2 ** 2001 September 15 |
|
3 ** |
|
4 ** The author disclaims copyright to this source code. In place of |
|
5 ** a legal notice, here is a blessing: |
|
6 ** |
|
7 ** May you do good and not evil. |
|
8 ** May you find forgiveness for yourself and forgive others. |
|
9 ** May you share freely, never taking more than you give. |
|
10 ** |
|
11 ************************************************************************* |
|
12 ** Code for testing the pager.c module in SQLite. This code |
|
13 ** is not included in the SQLite library. It is used for automated |
|
14 ** testing of the SQLite library. |
|
15 ** |
|
16 ** $Id: test2.c,v 1.62 2008/09/29 11:49:48 danielk1977 Exp $ |
|
17 */ |
|
18 #include "sqliteInt.h" |
|
19 #include "tcl.h" |
|
20 #include <stdlib.h> |
|
21 #include <string.h> |
|
22 #include <ctype.h> |
|
23 |
|
24 /* |
|
25 ** Interpret an SQLite error number |
|
26 */ |
|
27 static char *errorName(int rc){ |
|
28 char *zName; |
|
29 switch( rc ){ |
|
30 case SQLITE_OK: zName = "SQLITE_OK"; break; |
|
31 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; |
|
32 case SQLITE_PERM: zName = "SQLITE_PERM"; break; |
|
33 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; |
|
34 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; |
|
35 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; |
|
36 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; |
|
37 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; |
|
38 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; |
|
39 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; |
|
40 case SQLITE_FULL: zName = "SQLITE_FULL"; break; |
|
41 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; |
|
42 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; |
|
43 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; |
|
44 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; |
|
45 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; |
|
46 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; |
|
47 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; |
|
48 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; |
|
49 default: zName = "SQLITE_Unknown"; break; |
|
50 } |
|
51 return zName; |
|
52 } |
|
53 |
|
54 /* |
|
55 ** Page size and reserved size used for testing. |
|
56 */ |
|
57 static int test_pagesize = 1024; |
|
58 |
|
59 /* |
|
60 ** Usage: pager_open FILENAME N-PAGE |
|
61 ** |
|
62 ** Open a new pager |
|
63 */ |
|
64 static int pager_open( |
|
65 void *NotUsed, |
|
66 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
67 int argc, /* Number of arguments */ |
|
68 const char **argv /* Text of each argument */ |
|
69 ){ |
|
70 u16 pageSize; |
|
71 Pager *pPager; |
|
72 int nPage; |
|
73 int rc; |
|
74 char zBuf[100]; |
|
75 if( argc!=3 ){ |
|
76 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
77 " FILENAME N-PAGE\"", 0); |
|
78 return TCL_ERROR; |
|
79 } |
|
80 if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR; |
|
81 rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0, |
|
82 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB); |
|
83 if( rc!=SQLITE_OK ){ |
|
84 Tcl_AppendResult(interp, errorName(rc), 0); |
|
85 return TCL_ERROR; |
|
86 } |
|
87 sqlite3PagerSetCachesize(pPager, nPage); |
|
88 pageSize = test_pagesize; |
|
89 sqlite3PagerSetPagesize(pPager, &pageSize); |
|
90 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPager); |
|
91 Tcl_AppendResult(interp, zBuf, 0); |
|
92 return TCL_OK; |
|
93 } |
|
94 |
|
95 /* |
|
96 ** Usage: pager_close ID |
|
97 ** |
|
98 ** Close the given pager. |
|
99 */ |
|
100 static int pager_close( |
|
101 void *NotUsed, |
|
102 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
103 int argc, /* Number of arguments */ |
|
104 const char **argv /* Text of each argument */ |
|
105 ){ |
|
106 Pager *pPager; |
|
107 int rc; |
|
108 if( argc!=2 ){ |
|
109 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
110 " ID\"", 0); |
|
111 return TCL_ERROR; |
|
112 } |
|
113 pPager = sqlite3TestTextToPtr(argv[1]); |
|
114 rc = sqlite3PagerClose(pPager); |
|
115 if( rc!=SQLITE_OK ){ |
|
116 Tcl_AppendResult(interp, errorName(rc), 0); |
|
117 return TCL_ERROR; |
|
118 } |
|
119 return TCL_OK; |
|
120 } |
|
121 |
|
122 /* |
|
123 ** Usage: pager_rollback ID |
|
124 ** |
|
125 ** Rollback changes |
|
126 */ |
|
127 static int pager_rollback( |
|
128 void *NotUsed, |
|
129 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
130 int argc, /* Number of arguments */ |
|
131 const char **argv /* Text of each argument */ |
|
132 ){ |
|
133 Pager *pPager; |
|
134 int rc; |
|
135 if( argc!=2 ){ |
|
136 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
137 " ID\"", 0); |
|
138 return TCL_ERROR; |
|
139 } |
|
140 pPager = sqlite3TestTextToPtr(argv[1]); |
|
141 rc = sqlite3PagerRollback(pPager); |
|
142 if( rc!=SQLITE_OK ){ |
|
143 Tcl_AppendResult(interp, errorName(rc), 0); |
|
144 return TCL_ERROR; |
|
145 } |
|
146 return TCL_OK; |
|
147 } |
|
148 |
|
149 /* |
|
150 ** Usage: pager_commit ID |
|
151 ** |
|
152 ** Commit all changes |
|
153 */ |
|
154 static int pager_commit( |
|
155 void *NotUsed, |
|
156 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
157 int argc, /* Number of arguments */ |
|
158 const char **argv /* Text of each argument */ |
|
159 ){ |
|
160 Pager *pPager; |
|
161 int rc; |
|
162 if( argc!=2 ){ |
|
163 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
164 " ID\"", 0); |
|
165 return TCL_ERROR; |
|
166 } |
|
167 pPager = sqlite3TestTextToPtr(argv[1]); |
|
168 rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0, 0); |
|
169 if( rc!=SQLITE_OK ){ |
|
170 Tcl_AppendResult(interp, errorName(rc), 0); |
|
171 return TCL_ERROR; |
|
172 } |
|
173 rc = sqlite3PagerCommitPhaseTwo(pPager); |
|
174 if( rc!=SQLITE_OK ){ |
|
175 Tcl_AppendResult(interp, errorName(rc), 0); |
|
176 return TCL_ERROR; |
|
177 } |
|
178 return TCL_OK; |
|
179 } |
|
180 |
|
181 /* |
|
182 ** Usage: pager_stmt_begin ID |
|
183 ** |
|
184 ** Start a new checkpoint. |
|
185 */ |
|
186 static int pager_stmt_begin( |
|
187 void *NotUsed, |
|
188 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
189 int argc, /* Number of arguments */ |
|
190 const char **argv /* Text of each argument */ |
|
191 ){ |
|
192 Pager *pPager; |
|
193 int rc; |
|
194 if( argc!=2 ){ |
|
195 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
196 " ID\"", 0); |
|
197 return TCL_ERROR; |
|
198 } |
|
199 pPager = sqlite3TestTextToPtr(argv[1]); |
|
200 rc = sqlite3PagerStmtBegin(pPager); |
|
201 if( rc!=SQLITE_OK ){ |
|
202 Tcl_AppendResult(interp, errorName(rc), 0); |
|
203 return TCL_ERROR; |
|
204 } |
|
205 return TCL_OK; |
|
206 } |
|
207 |
|
208 /* |
|
209 ** Usage: pager_stmt_rollback ID |
|
210 ** |
|
211 ** Rollback changes to a checkpoint |
|
212 */ |
|
213 static int pager_stmt_rollback( |
|
214 void *NotUsed, |
|
215 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
216 int argc, /* Number of arguments */ |
|
217 const char **argv /* Text of each argument */ |
|
218 ){ |
|
219 Pager *pPager; |
|
220 int rc; |
|
221 if( argc!=2 ){ |
|
222 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
223 " ID\"", 0); |
|
224 return TCL_ERROR; |
|
225 } |
|
226 pPager = sqlite3TestTextToPtr(argv[1]); |
|
227 rc = sqlite3PagerStmtRollback(pPager); |
|
228 if( rc!=SQLITE_OK ){ |
|
229 Tcl_AppendResult(interp, errorName(rc), 0); |
|
230 return TCL_ERROR; |
|
231 } |
|
232 return TCL_OK; |
|
233 } |
|
234 |
|
235 /* |
|
236 ** Usage: pager_stmt_commit ID |
|
237 ** |
|
238 ** Commit changes to a checkpoint |
|
239 */ |
|
240 static int pager_stmt_commit( |
|
241 void *NotUsed, |
|
242 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
243 int argc, /* Number of arguments */ |
|
244 const char **argv /* Text of each argument */ |
|
245 ){ |
|
246 Pager *pPager; |
|
247 int rc; |
|
248 if( argc!=2 ){ |
|
249 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
250 " ID\"", 0); |
|
251 return TCL_ERROR; |
|
252 } |
|
253 pPager = sqlite3TestTextToPtr(argv[1]); |
|
254 rc = sqlite3PagerStmtCommit(pPager); |
|
255 if( rc!=SQLITE_OK ){ |
|
256 Tcl_AppendResult(interp, errorName(rc), 0); |
|
257 return TCL_ERROR; |
|
258 } |
|
259 return TCL_OK; |
|
260 } |
|
261 |
|
262 /* |
|
263 ** Usage: pager_stats ID |
|
264 ** |
|
265 ** Return pager statistics. |
|
266 */ |
|
267 static int pager_stats( |
|
268 void *NotUsed, |
|
269 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
270 int argc, /* Number of arguments */ |
|
271 const char **argv /* Text of each argument */ |
|
272 ){ |
|
273 Pager *pPager; |
|
274 int i, *a; |
|
275 if( argc!=2 ){ |
|
276 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
277 " ID\"", 0); |
|
278 return TCL_ERROR; |
|
279 } |
|
280 pPager = sqlite3TestTextToPtr(argv[1]); |
|
281 a = sqlite3PagerStats(pPager); |
|
282 for(i=0; i<9; i++){ |
|
283 static char *zName[] = { |
|
284 "ref", "page", "max", "size", "state", "err", |
|
285 "hit", "miss", "ovfl", |
|
286 }; |
|
287 char zBuf[100]; |
|
288 Tcl_AppendElement(interp, zName[i]); |
|
289 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",a[i]); |
|
290 Tcl_AppendElement(interp, zBuf); |
|
291 } |
|
292 return TCL_OK; |
|
293 } |
|
294 |
|
295 /* |
|
296 ** Usage: pager_pagecount ID |
|
297 ** |
|
298 ** Return the size of the database file. |
|
299 */ |
|
300 static int pager_pagecount( |
|
301 void *NotUsed, |
|
302 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
303 int argc, /* Number of arguments */ |
|
304 const char **argv /* Text of each argument */ |
|
305 ){ |
|
306 Pager *pPager; |
|
307 char zBuf[100]; |
|
308 int nPage; |
|
309 if( argc!=2 ){ |
|
310 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
311 " ID\"", 0); |
|
312 return TCL_ERROR; |
|
313 } |
|
314 pPager = sqlite3TestTextToPtr(argv[1]); |
|
315 sqlite3PagerPagecount(pPager, &nPage); |
|
316 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nPage); |
|
317 Tcl_AppendResult(interp, zBuf, 0); |
|
318 return TCL_OK; |
|
319 } |
|
320 |
|
321 /* |
|
322 ** Usage: page_get ID PGNO |
|
323 ** |
|
324 ** Return a pointer to a page from the database. |
|
325 */ |
|
326 static int page_get( |
|
327 void *NotUsed, |
|
328 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
329 int argc, /* Number of arguments */ |
|
330 const char **argv /* Text of each argument */ |
|
331 ){ |
|
332 Pager *pPager; |
|
333 char zBuf[100]; |
|
334 DbPage *pPage; |
|
335 int pgno; |
|
336 int rc; |
|
337 if( argc!=3 ){ |
|
338 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
339 " ID PGNO\"", 0); |
|
340 return TCL_ERROR; |
|
341 } |
|
342 pPager = sqlite3TestTextToPtr(argv[1]); |
|
343 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; |
|
344 rc = sqlite3PagerGet(pPager, pgno, &pPage); |
|
345 if( rc!=SQLITE_OK ){ |
|
346 Tcl_AppendResult(interp, errorName(rc), 0); |
|
347 return TCL_ERROR; |
|
348 } |
|
349 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage); |
|
350 Tcl_AppendResult(interp, zBuf, 0); |
|
351 return TCL_OK; |
|
352 } |
|
353 |
|
354 /* |
|
355 ** Usage: page_lookup ID PGNO |
|
356 ** |
|
357 ** Return a pointer to a page if the page is already in cache. |
|
358 ** If not in cache, return an empty string. |
|
359 */ |
|
360 static int page_lookup( |
|
361 void *NotUsed, |
|
362 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
363 int argc, /* Number of arguments */ |
|
364 const char **argv /* Text of each argument */ |
|
365 ){ |
|
366 Pager *pPager; |
|
367 char zBuf[100]; |
|
368 DbPage *pPage; |
|
369 int pgno; |
|
370 if( argc!=3 ){ |
|
371 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
372 " ID PGNO\"", 0); |
|
373 return TCL_ERROR; |
|
374 } |
|
375 pPager = sqlite3TestTextToPtr(argv[1]); |
|
376 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; |
|
377 pPage = sqlite3PagerLookup(pPager, pgno); |
|
378 if( pPage ){ |
|
379 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage); |
|
380 Tcl_AppendResult(interp, zBuf, 0); |
|
381 } |
|
382 return TCL_OK; |
|
383 } |
|
384 |
|
385 /* |
|
386 ** Usage: pager_truncate ID PGNO |
|
387 */ |
|
388 static int pager_truncate( |
|
389 void *NotUsed, |
|
390 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
391 int argc, /* Number of arguments */ |
|
392 const char **argv /* Text of each argument */ |
|
393 ){ |
|
394 Pager *pPager; |
|
395 int rc; |
|
396 int pgno; |
|
397 if( argc!=3 ){ |
|
398 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
399 " ID PGNO\"", 0); |
|
400 return TCL_ERROR; |
|
401 } |
|
402 pPager = sqlite3TestTextToPtr(argv[1]); |
|
403 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; |
|
404 rc = sqlite3PagerTruncate(pPager, pgno); |
|
405 if( rc!=SQLITE_OK ){ |
|
406 Tcl_AppendResult(interp, errorName(rc), 0); |
|
407 return TCL_ERROR; |
|
408 } |
|
409 return TCL_OK; |
|
410 } |
|
411 |
|
412 |
|
413 /* |
|
414 ** Usage: page_unref PAGE |
|
415 ** |
|
416 ** Drop a pointer to a page. |
|
417 */ |
|
418 static int page_unref( |
|
419 void *NotUsed, |
|
420 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
421 int argc, /* Number of arguments */ |
|
422 const char **argv /* Text of each argument */ |
|
423 ){ |
|
424 DbPage *pPage; |
|
425 int rc; |
|
426 if( argc!=2 ){ |
|
427 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
428 " PAGE\"", 0); |
|
429 return TCL_ERROR; |
|
430 } |
|
431 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]); |
|
432 rc = sqlite3PagerUnref(pPage); |
|
433 if( rc!=SQLITE_OK ){ |
|
434 Tcl_AppendResult(interp, errorName(rc), 0); |
|
435 return TCL_ERROR; |
|
436 } |
|
437 return TCL_OK; |
|
438 } |
|
439 |
|
440 /* |
|
441 ** Usage: page_read PAGE |
|
442 ** |
|
443 ** Return the content of a page |
|
444 */ |
|
445 static int page_read( |
|
446 void *NotUsed, |
|
447 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
448 int argc, /* Number of arguments */ |
|
449 const char **argv /* Text of each argument */ |
|
450 ){ |
|
451 char zBuf[100]; |
|
452 DbPage *pPage; |
|
453 if( argc!=2 ){ |
|
454 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
455 " PAGE\"", 0); |
|
456 return TCL_ERROR; |
|
457 } |
|
458 pPage = sqlite3TestTextToPtr(argv[1]); |
|
459 memcpy(zBuf, sqlite3PagerGetData(pPage), sizeof(zBuf)); |
|
460 Tcl_AppendResult(interp, zBuf, 0); |
|
461 return TCL_OK; |
|
462 } |
|
463 |
|
464 /* |
|
465 ** Usage: page_number PAGE |
|
466 ** |
|
467 ** Return the page number for a page. |
|
468 */ |
|
469 static int page_number( |
|
470 void *NotUsed, |
|
471 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
472 int argc, /* Number of arguments */ |
|
473 const char **argv /* Text of each argument */ |
|
474 ){ |
|
475 char zBuf[100]; |
|
476 DbPage *pPage; |
|
477 if( argc!=2 ){ |
|
478 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
479 " PAGE\"", 0); |
|
480 return TCL_ERROR; |
|
481 } |
|
482 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]); |
|
483 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3PagerPagenumber(pPage)); |
|
484 Tcl_AppendResult(interp, zBuf, 0); |
|
485 return TCL_OK; |
|
486 } |
|
487 |
|
488 /* |
|
489 ** Usage: page_write PAGE DATA |
|
490 ** |
|
491 ** Write something into a page. |
|
492 */ |
|
493 static int page_write( |
|
494 void *NotUsed, |
|
495 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
496 int argc, /* Number of arguments */ |
|
497 const char **argv /* Text of each argument */ |
|
498 ){ |
|
499 DbPage *pPage; |
|
500 char *pData; |
|
501 int rc; |
|
502 if( argc!=3 ){ |
|
503 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
504 " PAGE DATA\"", 0); |
|
505 return TCL_ERROR; |
|
506 } |
|
507 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]); |
|
508 rc = sqlite3PagerWrite(pPage); |
|
509 if( rc!=SQLITE_OK ){ |
|
510 Tcl_AppendResult(interp, errorName(rc), 0); |
|
511 return TCL_ERROR; |
|
512 } |
|
513 pData = sqlite3PagerGetData(pPage); |
|
514 strncpy(pData, argv[2], test_pagesize-1); |
|
515 pData[test_pagesize-1] = 0; |
|
516 return TCL_OK; |
|
517 } |
|
518 |
|
519 #ifndef SQLITE_OMIT_DISKIO |
|
520 /* |
|
521 ** Usage: fake_big_file N FILENAME |
|
522 ** |
|
523 ** Write a few bytes at the N megabyte point of FILENAME. This will |
|
524 ** create a large file. If the file was a valid SQLite database, then |
|
525 ** the next time the database is opened, SQLite will begin allocating |
|
526 ** new pages after N. If N is 2096 or bigger, this will test the |
|
527 ** ability of SQLite to write to large files. |
|
528 */ |
|
529 static int fake_big_file( |
|
530 void *NotUsed, |
|
531 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
532 int argc, /* Number of arguments */ |
|
533 const char **argv /* Text of each argument */ |
|
534 ){ |
|
535 sqlite3_vfs *pVfs; |
|
536 sqlite3_file *fd = 0; |
|
537 int rc; |
|
538 int n; |
|
539 i64 offset; |
|
540 if( argc!=3 ){ |
|
541 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
542 " N-MEGABYTES FILE\"", 0); |
|
543 return TCL_ERROR; |
|
544 } |
|
545 if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; |
|
546 |
|
547 pVfs = sqlite3_vfs_find(0); |
|
548 rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd, |
|
549 (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0 |
|
550 ); |
|
551 if( rc ){ |
|
552 Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0); |
|
553 return TCL_ERROR; |
|
554 } |
|
555 offset = n; |
|
556 offset *= 1024*1024; |
|
557 rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset); |
|
558 sqlite3OsCloseFree(fd); |
|
559 if( rc ){ |
|
560 Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0); |
|
561 return TCL_ERROR; |
|
562 } |
|
563 return TCL_OK; |
|
564 } |
|
565 #endif |
|
566 |
|
567 |
|
568 /* |
|
569 ** sqlite3BitvecBuiltinTest SIZE PROGRAM |
|
570 ** |
|
571 ** Invoke the SQLITE_TESTCTRL_BITVEC_TEST operator on test_control. |
|
572 ** See comments on sqlite3BitvecBuiltinTest() for additional information. |
|
573 */ |
|
574 static int testBitvecBuiltinTest( |
|
575 void *NotUsed, |
|
576 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
|
577 int argc, /* Number of arguments */ |
|
578 const char **argv /* Text of each argument */ |
|
579 ){ |
|
580 int sz, rc; |
|
581 int nProg = 0; |
|
582 int aProg[100]; |
|
583 const char *z; |
|
584 if( argc!=3 ){ |
|
585 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
|
586 " SIZE PROGRAM\"", (void*)0); |
|
587 } |
|
588 if( Tcl_GetInt(interp, argv[1], &sz) ) return TCL_ERROR; |
|
589 z = argv[2]; |
|
590 while( nProg<99 && *z ){ |
|
591 while( *z && !isdigit(*z) ){ z++; } |
|
592 if( *z==0 ) break; |
|
593 aProg[nProg++] = atoi(z); |
|
594 while( isdigit(*z) ){ z++; } |
|
595 } |
|
596 aProg[nProg] = 0; |
|
597 rc = sqlite3_test_control(SQLITE_TESTCTRL_BITVEC_TEST, sz, aProg); |
|
598 Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); |
|
599 return TCL_OK; |
|
600 } |
|
601 |
|
602 /* |
|
603 ** Register commands with the TCL interpreter. |
|
604 */ |
|
605 int Sqlitetest2_Init(Tcl_Interp *interp){ |
|
606 extern int sqlite3_io_error_persist; |
|
607 extern int sqlite3_io_error_pending; |
|
608 extern int sqlite3_io_error_hit; |
|
609 extern int sqlite3_io_error_hardhit; |
|
610 extern int sqlite3_diskfull_pending; |
|
611 extern int sqlite3_diskfull; |
|
612 extern int sqlite3_pager_n_sort_bucket; |
|
613 static struct { |
|
614 char *zName; |
|
615 Tcl_CmdProc *xProc; |
|
616 } aCmd[] = { |
|
617 { "pager_open", (Tcl_CmdProc*)pager_open }, |
|
618 { "pager_close", (Tcl_CmdProc*)pager_close }, |
|
619 { "pager_commit", (Tcl_CmdProc*)pager_commit }, |
|
620 { "pager_rollback", (Tcl_CmdProc*)pager_rollback }, |
|
621 { "pager_stmt_begin", (Tcl_CmdProc*)pager_stmt_begin }, |
|
622 { "pager_stmt_commit", (Tcl_CmdProc*)pager_stmt_commit }, |
|
623 { "pager_stmt_rollback", (Tcl_CmdProc*)pager_stmt_rollback }, |
|
624 { "pager_stats", (Tcl_CmdProc*)pager_stats }, |
|
625 { "pager_pagecount", (Tcl_CmdProc*)pager_pagecount }, |
|
626 { "page_get", (Tcl_CmdProc*)page_get }, |
|
627 { "page_lookup", (Tcl_CmdProc*)page_lookup }, |
|
628 { "page_unref", (Tcl_CmdProc*)page_unref }, |
|
629 { "page_read", (Tcl_CmdProc*)page_read }, |
|
630 { "page_write", (Tcl_CmdProc*)page_write }, |
|
631 { "page_number", (Tcl_CmdProc*)page_number }, |
|
632 { "pager_truncate", (Tcl_CmdProc*)pager_truncate }, |
|
633 #ifndef SQLITE_OMIT_DISKIO |
|
634 { "fake_big_file", (Tcl_CmdProc*)fake_big_file }, |
|
635 #endif |
|
636 { "sqlite3BitvecBuiltinTest",(Tcl_CmdProc*)testBitvecBuiltinTest}, |
|
637 }; |
|
638 int i; |
|
639 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ |
|
640 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); |
|
641 } |
|
642 Tcl_LinkVar(interp, "sqlite_io_error_pending", |
|
643 (char*)&sqlite3_io_error_pending, TCL_LINK_INT); |
|
644 Tcl_LinkVar(interp, "sqlite_io_error_persist", |
|
645 (char*)&sqlite3_io_error_persist, TCL_LINK_INT); |
|
646 Tcl_LinkVar(interp, "sqlite_io_error_hit", |
|
647 (char*)&sqlite3_io_error_hit, TCL_LINK_INT); |
|
648 Tcl_LinkVar(interp, "sqlite_io_error_hardhit", |
|
649 (char*)&sqlite3_io_error_hardhit, TCL_LINK_INT); |
|
650 Tcl_LinkVar(interp, "sqlite_diskfull_pending", |
|
651 (char*)&sqlite3_diskfull_pending, TCL_LINK_INT); |
|
652 Tcl_LinkVar(interp, "sqlite_diskfull", |
|
653 (char*)&sqlite3_diskfull, TCL_LINK_INT); |
|
654 Tcl_LinkVar(interp, "sqlite_pending_byte", |
|
655 (char*)&sqlite3_pending_byte, TCL_LINK_INT); |
|
656 Tcl_LinkVar(interp, "sqlite_pager_n_sort_bucket", |
|
657 (char*)&sqlite3_pager_n_sort_bucket, TCL_LINK_INT); |
|
658 return TCL_OK; |
|
659 } |