source: trunk/src/3rdparty/sqlite/test2.c@ 205

Last change on this file since 205 was 205, checked in by rudi, 14 years ago

Added SQLite 2.8.17 sources. This allows to build at least one of the sql drivers / plugins.

File size: 16.2 KB
Line 
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.16 2004/02/10 01:54:28 drh Exp $
17*/
18#include "os.h"
19#include "sqliteInt.h"
20#include "pager.h"
21#include "tcl.h"
22#include <stdlib.h>
23#include <string.h>
24
25/*
26** Interpret an SQLite error number
27*/
28static char *errorName(int rc){
29 char *zName;
30 switch( rc ){
31 case SQLITE_OK: zName = "SQLITE_OK"; break;
32 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
33 case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
34 case SQLITE_PERM: zName = "SQLITE_PERM"; break;
35 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
36 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
37 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
38 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
39 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
40 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
41 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
42 case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
43 case SQLITE_FULL: zName = "SQLITE_FULL"; break;
44 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
45 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
46 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
47 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
48 case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break;
49 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
50 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
51 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
52 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
53 default: zName = "SQLITE_Unknown"; break;
54 }
55 return zName;
56}
57
58/*
59** Usage: pager_open FILENAME N-PAGE
60**
61** Open a new pager
62*/
63static int pager_open(
64 void *NotUsed,
65 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
66 int argc, /* Number of arguments */
67 const char **argv /* Text of each argument */
68){
69 Pager *pPager;
70 int nPage;
71 int rc;
72 char zBuf[100];
73 if( argc!=3 ){
74 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
75 " FILENAME N-PAGE\"", 0);
76 return TCL_ERROR;
77 }
78 if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
79 rc = sqlitepager_open(&pPager, argv[1], nPage, 0, 1);
80 if( rc!=SQLITE_OK ){
81 Tcl_AppendResult(interp, errorName(rc), 0);
82 return TCL_ERROR;
83 }
84 sprintf(zBuf,"0x%x",(int)pPager);
85 Tcl_AppendResult(interp, zBuf, 0);
86 return TCL_OK;
87}
88
89/*
90** Usage: pager_close ID
91**
92** Close the given pager.
93*/
94static int pager_close(
95 void *NotUsed,
96 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
97 int argc, /* Number of arguments */
98 const char **argv /* Text of each argument */
99){
100 Pager *pPager;
101 int rc;
102 if( argc!=2 ){
103 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
104 " ID\"", 0);
105 return TCL_ERROR;
106 }
107 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
108 rc = sqlitepager_close(pPager);
109 if( rc!=SQLITE_OK ){
110 Tcl_AppendResult(interp, errorName(rc), 0);
111 return TCL_ERROR;
112 }
113 return TCL_OK;
114}
115
116/*
117** Usage: pager_rollback ID
118**
119** Rollback changes
120*/
121static int pager_rollback(
122 void *NotUsed,
123 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
124 int argc, /* Number of arguments */
125 const char **argv /* Text of each argument */
126){
127 Pager *pPager;
128 int rc;
129 if( argc!=2 ){
130 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
131 " ID\"", 0);
132 return TCL_ERROR;
133 }
134 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
135 rc = sqlitepager_rollback(pPager);
136 if( rc!=SQLITE_OK ){
137 Tcl_AppendResult(interp, errorName(rc), 0);
138 return TCL_ERROR;
139 }
140 return TCL_OK;
141}
142
143/*
144** Usage: pager_commit ID
145**
146** Commit all changes
147*/
148static int pager_commit(
149 void *NotUsed,
150 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
151 int argc, /* Number of arguments */
152 const char **argv /* Text of each argument */
153){
154 Pager *pPager;
155 int rc;
156 if( argc!=2 ){
157 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
158 " ID\"", 0);
159 return TCL_ERROR;
160 }
161 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
162 rc = sqlitepager_commit(pPager);
163 if( rc!=SQLITE_OK ){
164 Tcl_AppendResult(interp, errorName(rc), 0);
165 return TCL_ERROR;
166 }
167 return TCL_OK;
168}
169
170/*
171** Usage: pager_ckpt_begin ID
172**
173** Start a new checkpoint.
174*/
175static int pager_ckpt_begin(
176 void *NotUsed,
177 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
178 int argc, /* Number of arguments */
179 const char **argv /* Text of each argument */
180){
181 Pager *pPager;
182 int rc;
183 if( argc!=2 ){
184 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
185 " ID\"", 0);
186 return TCL_ERROR;
187 }
188 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
189 rc = sqlitepager_ckpt_begin(pPager);
190 if( rc!=SQLITE_OK ){
191 Tcl_AppendResult(interp, errorName(rc), 0);
192 return TCL_ERROR;
193 }
194 return TCL_OK;
195}
196
197/*
198** Usage: pager_ckpt_rollback ID
199**
200** Rollback changes to a checkpoint
201*/
202static int pager_ckpt_rollback(
203 void *NotUsed,
204 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
205 int argc, /* Number of arguments */
206 const char **argv /* Text of each argument */
207){
208 Pager *pPager;
209 int rc;
210 if( argc!=2 ){
211 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
212 " ID\"", 0);
213 return TCL_ERROR;
214 }
215 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
216 rc = sqlitepager_ckpt_rollback(pPager);
217 if( rc!=SQLITE_OK ){
218 Tcl_AppendResult(interp, errorName(rc), 0);
219 return TCL_ERROR;
220 }
221 return TCL_OK;
222}
223
224/*
225** Usage: pager_ckpt_commit ID
226**
227** Commit changes to a checkpoint
228*/
229static int pager_ckpt_commit(
230 void *NotUsed,
231 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
232 int argc, /* Number of arguments */
233 const char **argv /* Text of each argument */
234){
235 Pager *pPager;
236 int rc;
237 if( argc!=2 ){
238 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
239 " ID\"", 0);
240 return TCL_ERROR;
241 }
242 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
243 rc = sqlitepager_ckpt_commit(pPager);
244 if( rc!=SQLITE_OK ){
245 Tcl_AppendResult(interp, errorName(rc), 0);
246 return TCL_ERROR;
247 }
248 return TCL_OK;
249}
250
251/*
252** Usage: pager_stats ID
253**
254** Return pager statistics.
255*/
256static int pager_stats(
257 void *NotUsed,
258 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
259 int argc, /* Number of arguments */
260 const char **argv /* Text of each argument */
261){
262 Pager *pPager;
263 int i, *a;
264 if( argc!=2 ){
265 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
266 " ID\"", 0);
267 return TCL_ERROR;
268 }
269 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
270 a = sqlitepager_stats(pPager);
271 for(i=0; i<9; i++){
272 static char *zName[] = {
273 "ref", "page", "max", "size", "state", "err",
274 "hit", "miss", "ovfl",
275 };
276 char zBuf[100];
277 Tcl_AppendElement(interp, zName[i]);
278 sprintf(zBuf,"%d",a[i]);
279 Tcl_AppendElement(interp, zBuf);
280 }
281 return TCL_OK;
282}
283
284/*
285** Usage: pager_pagecount ID
286**
287** Return the size of the database file.
288*/
289static int pager_pagecount(
290 void *NotUsed,
291 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
292 int argc, /* Number of arguments */
293 const char **argv /* Text of each argument */
294){
295 Pager *pPager;
296 char zBuf[100];
297 if( argc!=2 ){
298 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
299 " ID\"", 0);
300 return TCL_ERROR;
301 }
302 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
303 sprintf(zBuf,"%d",sqlitepager_pagecount(pPager));
304 Tcl_AppendResult(interp, zBuf, 0);
305 return TCL_OK;
306}
307
308/*
309** Usage: page_get ID PGNO
310**
311** Return a pointer to a page from the database.
312*/
313static int page_get(
314 void *NotUsed,
315 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
316 int argc, /* Number of arguments */
317 const char **argv /* Text of each argument */
318){
319 Pager *pPager;
320 char zBuf[100];
321 void *pPage;
322 int pgno;
323 int rc;
324 if( argc!=3 ){
325 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
326 " ID PGNO\"", 0);
327 return TCL_ERROR;
328 }
329 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
330 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
331 rc = sqlitepager_get(pPager, pgno, &pPage);
332 if( rc!=SQLITE_OK ){
333 Tcl_AppendResult(interp, errorName(rc), 0);
334 return TCL_ERROR;
335 }
336 sprintf(zBuf,"0x%x",(int)pPage);
337 Tcl_AppendResult(interp, zBuf, 0);
338 return TCL_OK;
339}
340
341/*
342** Usage: page_lookup ID PGNO
343**
344** Return a pointer to a page if the page is already in cache.
345** If not in cache, return an empty string.
346*/
347static int page_lookup(
348 void *NotUsed,
349 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
350 int argc, /* Number of arguments */
351 const char **argv /* Text of each argument */
352){
353 Pager *pPager;
354 char zBuf[100];
355 void *pPage;
356 int pgno;
357 if( argc!=3 ){
358 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
359 " ID PGNO\"", 0);
360 return TCL_ERROR;
361 }
362 if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR;
363 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
364 pPage = sqlitepager_lookup(pPager, pgno);
365 if( pPage ){
366 sprintf(zBuf,"0x%x",(int)pPage);
367 Tcl_AppendResult(interp, zBuf, 0);
368 }
369 return TCL_OK;
370}
371
372/*
373** Usage: page_unref PAGE
374**
375** Drop a pointer to a page.
376*/
377static int page_unref(
378 void *NotUsed,
379 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
380 int argc, /* Number of arguments */
381 const char **argv /* Text of each argument */
382){
383 void *pPage;
384 int rc;
385 if( argc!=2 ){
386 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
387 " PAGE\"", 0);
388 return TCL_ERROR;
389 }
390 if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR;
391 rc = sqlitepager_unref(pPage);
392 if( rc!=SQLITE_OK ){
393 Tcl_AppendResult(interp, errorName(rc), 0);
394 return TCL_ERROR;
395 }
396 return TCL_OK;
397}
398
399/*
400** Usage: page_read PAGE
401**
402** Return the content of a page
403*/
404static int page_read(
405 void *NotUsed,
406 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
407 int argc, /* Number of arguments */
408 const char **argv /* Text of each argument */
409){
410 char zBuf[100];
411 void *pPage;
412 if( argc!=2 ){
413 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
414 " PAGE\"", 0);
415 return TCL_ERROR;
416 }
417 if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR;
418 memcpy(zBuf, pPage, sizeof(zBuf));
419 Tcl_AppendResult(interp, zBuf, 0);
420 return TCL_OK;
421}
422
423/*
424** Usage: page_number PAGE
425**
426** Return the page number for a page.
427*/
428static int page_number(
429 void *NotUsed,
430 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
431 int argc, /* Number of arguments */
432 const char **argv /* Text of each argument */
433){
434 char zBuf[100];
435 void *pPage;
436 if( argc!=2 ){
437 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
438 " PAGE\"", 0);
439 return TCL_ERROR;
440 }
441 if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR;
442 sprintf(zBuf, "%d", sqlitepager_pagenumber(pPage));
443 Tcl_AppendResult(interp, zBuf, 0);
444 return TCL_OK;
445}
446
447/*
448** Usage: page_write PAGE DATA
449**
450** Write something into a page.
451*/
452static int page_write(
453 void *NotUsed,
454 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
455 int argc, /* Number of arguments */
456 const char **argv /* Text of each argument */
457){
458 void *pPage;
459 int rc;
460 if( argc!=3 ){
461 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
462 " PAGE DATA\"", 0);
463 return TCL_ERROR;
464 }
465 if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR;
466 rc = sqlitepager_write(pPage);
467 if( rc!=SQLITE_OK ){
468 Tcl_AppendResult(interp, errorName(rc), 0);
469 return TCL_ERROR;
470 }
471 strncpy((char*)pPage, argv[2], SQLITE_USABLE_SIZE-1);
472 ((char*)pPage)[SQLITE_USABLE_SIZE-1] = 0;
473 return TCL_OK;
474}
475
476/*
477** Usage: fake_big_file N FILENAME
478**
479** Write a few bytes at the N megabyte point of FILENAME. This will
480** create a large file. If the file was a valid SQLite database, then
481** the next time the database is opened, SQLite will begin allocating
482** new pages after N. If N is 2096 or bigger, this will test the
483** ability of SQLite to write to large files.
484*/
485static int fake_big_file(
486 void *NotUsed,
487 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
488 int argc, /* Number of arguments */
489 const char **argv /* Text of each argument */
490){
491 int rc;
492 int n;
493 off_t offset;
494 OsFile fd;
495 int readOnly = 0;
496 if( argc!=3 ){
497 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
498 " N-MEGABYTES FILE\"", 0);
499 return TCL_ERROR;
500 }
501 if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
502 rc = sqliteOsOpenReadWrite(argv[2], &fd, &readOnly);
503 if( rc ){
504 Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
505 return TCL_ERROR;
506 }
507 offset = n;
508 offset *= 1024*1024;
509 rc = sqliteOsSeek(&fd, offset);
510 if( rc ){
511 Tcl_AppendResult(interp, "seek failed: ", errorName(rc), 0);
512 return TCL_ERROR;
513 }
514 rc = sqliteOsWrite(&fd, "Hello, World!", 14);
515 sqliteOsClose(&fd);
516 if( rc ){
517 Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
518 return TCL_ERROR;
519 }
520 return TCL_OK;
521}
522
523/*
524** Register commands with the TCL interpreter.
525*/
526int Sqlitetest2_Init(Tcl_Interp *interp){
527 extern int sqlite_io_error_pending;
528 char zBuf[100];
529 static struct {
530 char *zName;
531 Tcl_CmdProc *xProc;
532 } aCmd[] = {
533 { "pager_open", (Tcl_CmdProc*)pager_open },
534 { "pager_close", (Tcl_CmdProc*)pager_close },
535 { "pager_commit", (Tcl_CmdProc*)pager_commit },
536 { "pager_rollback", (Tcl_CmdProc*)pager_rollback },
537 { "pager_ckpt_begin", (Tcl_CmdProc*)pager_ckpt_begin },
538 { "pager_ckpt_commit", (Tcl_CmdProc*)pager_ckpt_commit },
539 { "pager_ckpt_rollback", (Tcl_CmdProc*)pager_ckpt_rollback },
540 { "pager_stats", (Tcl_CmdProc*)pager_stats },
541 { "pager_pagecount", (Tcl_CmdProc*)pager_pagecount },
542 { "page_get", (Tcl_CmdProc*)page_get },
543 { "page_lookup", (Tcl_CmdProc*)page_lookup },
544 { "page_unref", (Tcl_CmdProc*)page_unref },
545 { "page_read", (Tcl_CmdProc*)page_read },
546 { "page_write", (Tcl_CmdProc*)page_write },
547 { "page_number", (Tcl_CmdProc*)page_number },
548 { "fake_big_file", (Tcl_CmdProc*)fake_big_file },
549 };
550 int i;
551 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
552 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
553 }
554 Tcl_LinkVar(interp, "sqlite_io_error_pending",
555 (char*)&sqlite_io_error_pending, TCL_LINK_INT);
556#ifdef SQLITE_TEST
557 Tcl_LinkVar(interp, "journal_format",
558 (char*)&journal_format, TCL_LINK_INT);
559#endif
560 sprintf(zBuf, "%d", SQLITE_PAGE_SIZE);
561 Tcl_SetVar(interp, "SQLITE_PAGE_SIZE", zBuf, TCL_GLOBAL_ONLY);
562 sprintf(zBuf, "%d", SQLITE_PAGE_RESERVE);
563 Tcl_SetVar(interp, "SQLITE_PAGE_RESERVE", zBuf, TCL_GLOBAL_ONLY);
564 sprintf(zBuf, "%d", SQLITE_USABLE_SIZE);
565 Tcl_SetVar(interp, "SQLITE_USABLE_SIZE", zBuf, TCL_GLOBAL_ONLY);
566 return TCL_OK;
567}
Note: See TracBrowser for help on using the repository browser.