blob: 083cc13a47046b9934f8386c24a26678c9747f13 [file] [log] [blame]
drh5c4d9702001-08-20 00:33:58 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh5c4d9702001-08-20 00:33:58 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh5c4d9702001-08-20 00:33:58 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** 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.
drh5c4d9702001-08-20 00:33:58 +000010**
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**
danielk197771d5d2c2008-09-29 11:49:47 +000016** $Id: test2.c,v 1.62 2008/09/29 11:49:48 danielk1977 Exp $
drh5c4d9702001-08-20 00:33:58 +000017*/
18#include "sqliteInt.h"
drh5c4d9702001-08-20 00:33:58 +000019#include "tcl.h"
20#include <stdlib.h>
21#include <string.h>
drh3088d592008-03-21 16:45:47 +000022#include <ctype.h>
drh5c4d9702001-08-20 00:33:58 +000023
24/*
25** Interpret an SQLite error number
26*/
27static 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;
drh5c4d9702001-08-20 00:33:58 +000032 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;
drh5c4d9702001-08-20 00:33:58 +000040 case SQLITE_FULL: zName = "SQLITE_FULL"; break;
41 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
42 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
drh247be432002-05-10 05:44:55 +000043 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
44 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
drh247be432002-05-10 05:44:55 +000045 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
46 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
47 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
drh8766c342002-11-09 00:33:15 +000048 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
drh5c4d9702001-08-20 00:33:58 +000049 default: zName = "SQLITE_Unknown"; break;
50 }
51 return zName;
52}
53
54/*
drh90f5ecb2004-07-22 01:19:35 +000055** Page size and reserved size used for testing.
56*/
57static int test_pagesize = 1024;
58
59/*
drh5c4d9702001-08-20 00:33:58 +000060** Usage: pager_open FILENAME N-PAGE
61**
62** Open a new pager
63*/
64static int pager_open(
65 void *NotUsed,
66 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
67 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +000068 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +000069){
danielk1977a1644fd2007-08-29 12:31:25 +000070 u16 pageSize;
drh5c4d9702001-08-20 00:33:58 +000071 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;
danielk197771d5d2c2008-09-29 11:49:47 +000081 rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0,
drh33f4e022007-09-03 15:19:34 +000082 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
drh5c4d9702001-08-20 00:33:58 +000083 if( rc!=SQLITE_OK ){
84 Tcl_AppendResult(interp, errorName(rc), 0);
85 return TCL_ERROR;
86 }
danielk19773b8a05f2007-03-19 17:44:26 +000087 sqlite3PagerSetCachesize(pPager, nPage);
danielk1977a1644fd2007-08-29 12:31:25 +000088 pageSize = test_pagesize;
89 sqlite3PagerSetPagesize(pPager, &pageSize);
drhfe63d1c2004-09-08 20:13:04 +000090 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPager);
drh5c4d9702001-08-20 00:33:58 +000091 Tcl_AppendResult(interp, zBuf, 0);
92 return TCL_OK;
93}
94
95/*
96** Usage: pager_close ID
97**
98** Close the given pager.
99*/
100static int pager_close(
101 void *NotUsed,
102 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
103 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000104 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000105){
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 }
drhe8f52c52008-07-12 14:52:20 +0000113 pPager = sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000114 rc = sqlite3PagerClose(pPager);
drh5c4d9702001-08-20 00:33:58 +0000115 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*/
127static int pager_rollback(
128 void *NotUsed,
129 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
130 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000131 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000132){
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 }
drhe8f52c52008-07-12 14:52:20 +0000140 pPager = sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000141 rc = sqlite3PagerRollback(pPager);
drh5c4d9702001-08-20 00:33:58 +0000142 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*/
154static int pager_commit(
155 void *NotUsed,
156 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
157 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000158 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000159){
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 }
drhe8f52c52008-07-12 14:52:20 +0000167 pPager = sqlite3TestTextToPtr(argv[1]);
danielk1977f653d782008-03-20 11:04:21 +0000168 rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0, 0);
drh80e35f42007-03-30 14:06:34 +0000169 if( rc!=SQLITE_OK ){
170 Tcl_AppendResult(interp, errorName(rc), 0);
171 return TCL_ERROR;
172 }
173 rc = sqlite3PagerCommitPhaseTwo(pPager);
drh5c4d9702001-08-20 00:33:58 +0000174 if( rc!=SQLITE_OK ){
175 Tcl_AppendResult(interp, errorName(rc), 0);
176 return TCL_ERROR;
177 }
178 return TCL_OK;
179}
180
181/*
drh3aac2dd2004-04-26 14:10:20 +0000182** Usage: pager_stmt_begin ID
drhfa86c412002-02-02 15:01:15 +0000183**
184** Start a new checkpoint.
185*/
drh3aac2dd2004-04-26 14:10:20 +0000186static int pager_stmt_begin(
drhfa86c412002-02-02 15:01:15 +0000187 void *NotUsed,
188 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
189 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000190 const char **argv /* Text of each argument */
drhfa86c412002-02-02 15:01:15 +0000191){
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 }
drhe8f52c52008-07-12 14:52:20 +0000199 pPager = sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000200 rc = sqlite3PagerStmtBegin(pPager);
drhfa86c412002-02-02 15:01:15 +0000201 if( rc!=SQLITE_OK ){
202 Tcl_AppendResult(interp, errorName(rc), 0);
203 return TCL_ERROR;
204 }
205 return TCL_OK;
206}
207
208/*
drh3aac2dd2004-04-26 14:10:20 +0000209** Usage: pager_stmt_rollback ID
drhfa86c412002-02-02 15:01:15 +0000210**
211** Rollback changes to a checkpoint
212*/
drh3aac2dd2004-04-26 14:10:20 +0000213static int pager_stmt_rollback(
drhfa86c412002-02-02 15:01:15 +0000214 void *NotUsed,
215 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
216 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000217 const char **argv /* Text of each argument */
drhfa86c412002-02-02 15:01:15 +0000218){
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 }
drhe8f52c52008-07-12 14:52:20 +0000226 pPager = sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000227 rc = sqlite3PagerStmtRollback(pPager);
drhfa86c412002-02-02 15:01:15 +0000228 if( rc!=SQLITE_OK ){
229 Tcl_AppendResult(interp, errorName(rc), 0);
230 return TCL_ERROR;
231 }
232 return TCL_OK;
233}
234
235/*
drh3aac2dd2004-04-26 14:10:20 +0000236** Usage: pager_stmt_commit ID
drhfa86c412002-02-02 15:01:15 +0000237**
238** Commit changes to a checkpoint
239*/
drh3aac2dd2004-04-26 14:10:20 +0000240static int pager_stmt_commit(
drhfa86c412002-02-02 15:01:15 +0000241 void *NotUsed,
242 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
243 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000244 const char **argv /* Text of each argument */
drhfa86c412002-02-02 15:01:15 +0000245){
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 }
drhe8f52c52008-07-12 14:52:20 +0000253 pPager = sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000254 rc = sqlite3PagerStmtCommit(pPager);
drhfa86c412002-02-02 15:01:15 +0000255 if( rc!=SQLITE_OK ){
256 Tcl_AppendResult(interp, errorName(rc), 0);
257 return TCL_ERROR;
258 }
259 return TCL_OK;
260}
261
262/*
drh5c4d9702001-08-20 00:33:58 +0000263** Usage: pager_stats ID
264**
265** Return pager statistics.
266*/
267static int pager_stats(
268 void *NotUsed,
269 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
270 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000271 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000272){
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 }
drhe8f52c52008-07-12 14:52:20 +0000280 pPager = sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000281 a = sqlite3PagerStats(pPager);
drh5c4d9702001-08-20 00:33:58 +0000282 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]);
drhfe63d1c2004-09-08 20:13:04 +0000289 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",a[i]);
drh5c4d9702001-08-20 00:33:58 +0000290 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*/
300static int pager_pagecount(
301 void *NotUsed,
302 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
303 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000304 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000305){
306 Pager *pPager;
307 char zBuf[100];
danielk1977ad0132d2008-06-07 08:58:22 +0000308 int nPage;
drh5c4d9702001-08-20 00:33:58 +0000309 if( argc!=2 ){
310 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
311 " ID\"", 0);
312 return TCL_ERROR;
313 }
drhe8f52c52008-07-12 14:52:20 +0000314 pPager = sqlite3TestTextToPtr(argv[1]);
danielk1977ad0132d2008-06-07 08:58:22 +0000315 sqlite3PagerPagecount(pPager, &nPage);
316 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nPage);
drh5c4d9702001-08-20 00:33:58 +0000317 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*/
326static int page_get(
327 void *NotUsed,
328 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
329 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000330 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000331){
332 Pager *pPager;
333 char zBuf[100];
danielk19773b8a05f2007-03-19 17:44:26 +0000334 DbPage *pPage;
drh5c4d9702001-08-20 00:33:58 +0000335 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 }
drhe8f52c52008-07-12 14:52:20 +0000342 pPager = sqlite3TestTextToPtr(argv[1]);
drh5c4d9702001-08-20 00:33:58 +0000343 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
danielk19773b8a05f2007-03-19 17:44:26 +0000344 rc = sqlite3PagerGet(pPager, pgno, &pPage);
drh5c4d9702001-08-20 00:33:58 +0000345 if( rc!=SQLITE_OK ){
346 Tcl_AppendResult(interp, errorName(rc), 0);
347 return TCL_ERROR;
348 }
drhfe63d1c2004-09-08 20:13:04 +0000349 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
drh5c4d9702001-08-20 00:33:58 +0000350 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*/
360static int page_lookup(
361 void *NotUsed,
362 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
363 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000364 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000365){
366 Pager *pPager;
367 char zBuf[100];
danielk19773b8a05f2007-03-19 17:44:26 +0000368 DbPage *pPage;
drh5c4d9702001-08-20 00:33:58 +0000369 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 }
drhe8f52c52008-07-12 14:52:20 +0000375 pPager = sqlite3TestTextToPtr(argv[1]);
drh5c4d9702001-08-20 00:33:58 +0000376 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
danielk19773b8a05f2007-03-19 17:44:26 +0000377 pPage = sqlite3PagerLookup(pPager, pgno);
drh5c4d9702001-08-20 00:33:58 +0000378 if( pPage ){
drhfe63d1c2004-09-08 20:13:04 +0000379 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
drh5c4d9702001-08-20 00:33:58 +0000380 Tcl_AppendResult(interp, zBuf, 0);
381 }
382 return TCL_OK;
383}
384
385/*
danielk1977aca790a2005-01-13 11:07:52 +0000386** Usage: pager_truncate ID PGNO
387*/
388static 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 }
drhe8f52c52008-07-12 14:52:20 +0000402 pPager = sqlite3TestTextToPtr(argv[1]);
danielk1977aca790a2005-01-13 11:07:52 +0000403 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
danielk19773b8a05f2007-03-19 17:44:26 +0000404 rc = sqlite3PagerTruncate(pPager, pgno);
danielk1977aca790a2005-01-13 11:07:52 +0000405 if( rc!=SQLITE_OK ){
406 Tcl_AppendResult(interp, errorName(rc), 0);
407 return TCL_ERROR;
408 }
409 return TCL_OK;
410}
411
412
413/*
drh5c4d9702001-08-20 00:33:58 +0000414** Usage: page_unref PAGE
415**
416** Drop a pointer to a page.
417*/
418static int page_unref(
419 void *NotUsed,
420 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
421 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000422 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000423){
danielk19773b8a05f2007-03-19 17:44:26 +0000424 DbPage *pPage;
drh5c4d9702001-08-20 00:33:58 +0000425 int rc;
426 if( argc!=2 ){
427 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
428 " PAGE\"", 0);
429 return TCL_ERROR;
430 }
drhe8f52c52008-07-12 14:52:20 +0000431 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000432 rc = sqlite3PagerUnref(pPage);
drh5c4d9702001-08-20 00:33:58 +0000433 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*/
445static int page_read(
446 void *NotUsed,
447 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
448 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000449 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000450){
451 char zBuf[100];
danielk19773b8a05f2007-03-19 17:44:26 +0000452 DbPage *pPage;
drh5c4d9702001-08-20 00:33:58 +0000453 if( argc!=2 ){
454 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
455 " PAGE\"", 0);
456 return TCL_ERROR;
457 }
drhe8f52c52008-07-12 14:52:20 +0000458 pPage = sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000459 memcpy(zBuf, sqlite3PagerGetData(pPage), sizeof(zBuf));
drh5c4d9702001-08-20 00:33:58 +0000460 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*/
469static int page_number(
470 void *NotUsed,
471 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
472 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000473 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000474){
475 char zBuf[100];
danielk19773b8a05f2007-03-19 17:44:26 +0000476 DbPage *pPage;
drh5c4d9702001-08-20 00:33:58 +0000477 if( argc!=2 ){
478 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
479 " PAGE\"", 0);
480 return TCL_ERROR;
481 }
drhe8f52c52008-07-12 14:52:20 +0000482 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000483 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3PagerPagenumber(pPage));
drh5c4d9702001-08-20 00:33:58 +0000484 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*/
493static int page_write(
494 void *NotUsed,
495 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
496 int argc, /* Number of arguments */
drhc2eef3b2002-08-31 18:53:06 +0000497 const char **argv /* Text of each argument */
drh5c4d9702001-08-20 00:33:58 +0000498){
danielk19773b8a05f2007-03-19 17:44:26 +0000499 DbPage *pPage;
500 char *pData;
drh5c4d9702001-08-20 00:33:58 +0000501 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 }
drhe8f52c52008-07-12 14:52:20 +0000507 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
danielk19773b8a05f2007-03-19 17:44:26 +0000508 rc = sqlite3PagerWrite(pPage);
drh5c4d9702001-08-20 00:33:58 +0000509 if( rc!=SQLITE_OK ){
510 Tcl_AppendResult(interp, errorName(rc), 0);
511 return TCL_ERROR;
512 }
danielk19773b8a05f2007-03-19 17:44:26 +0000513 pData = sqlite3PagerGetData(pPage);
514 strncpy(pData, argv[2], test_pagesize-1);
515 pData[test_pagesize-1] = 0;
drh5c4d9702001-08-20 00:33:58 +0000516 return TCL_OK;
517}
518
danielk197744ee5bf2005-05-27 09:41:12 +0000519#ifndef SQLITE_OMIT_DISKIO
drh5c4d9702001-08-20 00:33:58 +0000520/*
drhd0d006e2002-12-01 02:00:57 +0000521** 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*/
529static 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){
danielk1977b4b47412007-08-17 15:53:36 +0000535 sqlite3_vfs *pVfs;
536 sqlite3_file *fd = 0;
drhd0d006e2002-12-01 02:00:57 +0000537 int rc;
538 int n;
drheb206252004-10-01 02:00:31 +0000539 i64 offset;
drhd0d006e2002-12-01 02:00:57 +0000540 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;
danielk1977b4b47412007-08-17 15:53:36 +0000546
drhd677b3d2007-08-20 22:48:41 +0000547 pVfs = sqlite3_vfs_find(0);
danielk1977fee2d252007-08-18 10:59:19 +0000548 rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd,
danielk1977967a4a12007-08-20 14:23:44 +0000549 (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0
danielk1977fee2d252007-08-18 10:59:19 +0000550 );
drhd0d006e2002-12-01 02:00:57 +0000551 if( rc ){
552 Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
553 return TCL_ERROR;
554 }
555 offset = n;
556 offset *= 1024*1024;
danielk197762079062007-08-15 17:08:46 +0000557 rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
danielk1977b4b47412007-08-17 15:53:36 +0000558 sqlite3OsCloseFree(fd);
drhd0d006e2002-12-01 02:00:57 +0000559 if( rc ){
560 Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
561 return TCL_ERROR;
562 }
drhd0d006e2002-12-01 02:00:57 +0000563 return TCL_OK;
564}
danielk197744ee5bf2005-05-27 09:41:12 +0000565#endif
drhd0d006e2002-12-01 02:00:57 +0000566
drh3088d592008-03-21 16:45:47 +0000567
drhd0d006e2002-12-01 02:00:57 +0000568/*
drh3088d592008-03-21 16:45:47 +0000569** sqlite3BitvecBuiltinTest SIZE PROGRAM
570**
571** Invoke the SQLITE_TESTCTRL_BITVEC_TEST operator on test_control.
572** See comments on sqlite3BitvecBuiltinTest() for additional information.
drhf5e7bb52008-02-18 14:47:33 +0000573*/
drh3088d592008-03-21 16:45:47 +0000574static int testBitvecBuiltinTest(
drhf5e7bb52008-02-18 14:47:33 +0000575 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){
drh3088d592008-03-21 16:45:47 +0000580 int sz, rc;
581 int nProg = 0;
582 int aProg[100];
583 const char *z;
drhf5e7bb52008-02-18 14:47:33 +0000584 if( argc!=3 ){
drh3088d592008-03-21 16:45:47 +0000585 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
586 " SIZE PROGRAM\"", (void*)0);
drhf5e7bb52008-02-18 14:47:33 +0000587 }
drh3088d592008-03-21 16:45:47 +0000588 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));
drhf5e7bb52008-02-18 14:47:33 +0000599 return TCL_OK;
600}
drhf5e7bb52008-02-18 14:47:33 +0000601
602/*
drh5c4d9702001-08-20 00:33:58 +0000603** Register commands with the TCL interpreter.
604*/
605int Sqlitetest2_Init(Tcl_Interp *interp){
drhd5eb79e2007-03-15 12:17:42 +0000606 extern int sqlite3_io_error_persist;
danielk19776f8a5032004-05-10 10:34:51 +0000607 extern int sqlite3_io_error_pending;
drhc9ac5ca2005-11-04 22:03:30 +0000608 extern int sqlite3_io_error_hit;
drh1aa5af12008-03-07 19:51:14 +0000609 extern int sqlite3_io_error_hardhit;
drh047d4832004-10-01 14:38:02 +0000610 extern int sqlite3_diskfull_pending;
drhf307a4a2005-09-09 10:46:19 +0000611 extern int sqlite3_diskfull;
danielk197724168722007-04-02 05:07:47 +0000612 extern int sqlite3_pager_n_sort_bucket;
drhc2eef3b2002-08-31 18:53:06 +0000613 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 },
drh3aac2dd2004-04-26 14:10:20 +0000621 { "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 },
drhc2eef3b2002-08-31 18:53:06 +0000624 { "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 },
danielk1977aca790a2005-01-13 11:07:52 +0000632 { "pager_truncate", (Tcl_CmdProc*)pager_truncate },
danielk197744ee5bf2005-05-27 09:41:12 +0000633#ifndef SQLITE_OMIT_DISKIO
drhd0d006e2002-12-01 02:00:57 +0000634 { "fake_big_file", (Tcl_CmdProc*)fake_big_file },
danielk197744ee5bf2005-05-27 09:41:12 +0000635#endif
drh3088d592008-03-21 16:45:47 +0000636 { "sqlite3BitvecBuiltinTest",(Tcl_CmdProc*)testBitvecBuiltinTest},
drhc2eef3b2002-08-31 18:53:06 +0000637 };
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 }
danielk1977369f27e2004-06-15 11:40:04 +0000642 Tcl_LinkVar(interp, "sqlite_io_error_pending",
danielk19776f8a5032004-05-10 10:34:51 +0000643 (char*)&sqlite3_io_error_pending, TCL_LINK_INT);
drhd5eb79e2007-03-15 12:17:42 +0000644 Tcl_LinkVar(interp, "sqlite_io_error_persist",
645 (char*)&sqlite3_io_error_persist, TCL_LINK_INT);
drhc9ac5ca2005-11-04 22:03:30 +0000646 Tcl_LinkVar(interp, "sqlite_io_error_hit",
647 (char*)&sqlite3_io_error_hit, TCL_LINK_INT);
drh1aa5af12008-03-07 19:51:14 +0000648 Tcl_LinkVar(interp, "sqlite_io_error_hardhit",
649 (char*)&sqlite3_io_error_hardhit, TCL_LINK_INT);
drh047d4832004-10-01 14:38:02 +0000650 Tcl_LinkVar(interp, "sqlite_diskfull_pending",
651 (char*)&sqlite3_diskfull_pending, TCL_LINK_INT);
drhf307a4a2005-09-09 10:46:19 +0000652 Tcl_LinkVar(interp, "sqlite_diskfull",
653 (char*)&sqlite3_diskfull, TCL_LINK_INT);
danielk1977fd5f5b62005-09-16 09:52:29 +0000654 Tcl_LinkVar(interp, "sqlite_pending_byte",
655 (char*)&sqlite3_pending_byte, TCL_LINK_INT);
danielk197724168722007-04-02 05:07:47 +0000656 Tcl_LinkVar(interp, "sqlite_pager_n_sort_bucket",
657 (char*)&sqlite3_pager_n_sort_bucket, TCL_LINK_INT);
drh5c4d9702001-08-20 00:33:58 +0000658 return TCL_OK;
659}