source: trunk/src/3rdparty/sqlite/test3.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: 27.3 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 btree.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: test3.c,v 1.23 2003/04/13 18:26:52 paul Exp $
17*/
18#include "sqliteInt.h"
19#include "pager.h"
20#include "btree.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 default: zName = "SQLITE_Unknown"; break;
47 }
48 return zName;
49}
50
51/*
52** Usage: btree_open FILENAME
53**
54** Open a new database
55*/
56static int btree_open(
57 void *NotUsed,
58 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
59 int argc, /* Number of arguments */
60 const char **argv /* Text of each argument */
61){
62 Btree *pBt;
63 int rc;
64 char zBuf[100];
65 if( argc!=2 ){
66 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
67 " FILENAME\"", 0);
68 return TCL_ERROR;
69 }
70 rc = sqliteBtreeFactory(0, argv[1], 0, 1000, &pBt);
71 if( rc!=SQLITE_OK ){
72 Tcl_AppendResult(interp, errorName(rc), 0);
73 return TCL_ERROR;
74 }
75 sprintf(zBuf,"%p", pBt);
76 if( strncmp(zBuf,"0x",2) ){
77 sprintf(zBuf, "0x%p", pBt);
78 }
79 Tcl_AppendResult(interp, zBuf, 0);
80 return TCL_OK;
81}
82
83/*
84** Usage: btree_close ID
85**
86** Close the given database.
87*/
88static int btree_close(
89 void *NotUsed,
90 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
91 int argc, /* Number of arguments */
92 const char **argv /* Text of each argument */
93){
94 Btree *pBt;
95 int rc;
96 if( argc!=2 ){
97 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
98 " ID\"", 0);
99 return TCL_ERROR;
100 }
101 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
102 rc = sqliteBtreeClose(pBt);
103 if( rc!=SQLITE_OK ){
104 Tcl_AppendResult(interp, errorName(rc), 0);
105 return TCL_ERROR;
106 }
107 return TCL_OK;
108}
109
110/*
111** Usage: btree_begin_transaction ID
112**
113** Start a new transaction
114*/
115static int btree_begin_transaction(
116 void *NotUsed,
117 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
118 int argc, /* Number of arguments */
119 const char **argv /* Text of each argument */
120){
121 Btree *pBt;
122 int rc;
123 if( argc!=2 ){
124 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
125 " ID\"", 0);
126 return TCL_ERROR;
127 }
128 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
129 rc = sqliteBtreeBeginTrans(pBt);
130 if( rc!=SQLITE_OK ){
131 Tcl_AppendResult(interp, errorName(rc), 0);
132 return TCL_ERROR;
133 }
134 return TCL_OK;
135}
136
137/*
138** Usage: btree_rollback ID
139**
140** Rollback changes
141*/
142static int btree_rollback(
143 void *NotUsed,
144 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
145 int argc, /* Number of arguments */
146 const char **argv /* Text of each argument */
147){
148 Btree *pBt;
149 int rc;
150 if( argc!=2 ){
151 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
152 " ID\"", 0);
153 return TCL_ERROR;
154 }
155 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
156 rc = sqliteBtreeRollback(pBt);
157 if( rc!=SQLITE_OK ){
158 Tcl_AppendResult(interp, errorName(rc), 0);
159 return TCL_ERROR;
160 }
161 return TCL_OK;
162}
163
164/*
165** Usage: btree_commit ID
166**
167** Commit all changes
168*/
169static int btree_commit(
170 void *NotUsed,
171 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
172 int argc, /* Number of arguments */
173 const char **argv /* Text of each argument */
174){
175 Btree *pBt;
176 int rc;
177 if( argc!=2 ){
178 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
179 " ID\"", 0);
180 return TCL_ERROR;
181 }
182 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
183 rc = sqliteBtreeCommit(pBt);
184 if( rc!=SQLITE_OK ){
185 Tcl_AppendResult(interp, errorName(rc), 0);
186 return TCL_ERROR;
187 }
188 return TCL_OK;
189}
190
191/*
192** Usage: btree_create_table ID
193**
194** Create a new table in the database
195*/
196static int btree_create_table(
197 void *NotUsed,
198 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
199 int argc, /* Number of arguments */
200 const char **argv /* Text of each argument */
201){
202 Btree *pBt;
203 int rc, iTable;
204 char zBuf[30];
205 if( argc!=2 ){
206 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
207 " ID\"", 0);
208 return TCL_ERROR;
209 }
210 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
211 rc = sqliteBtreeCreateTable(pBt, &iTable);
212 if( rc!=SQLITE_OK ){
213 Tcl_AppendResult(interp, errorName(rc), 0);
214 return TCL_ERROR;
215 }
216 sprintf(zBuf, "%d", iTable);
217 Tcl_AppendResult(interp, zBuf, 0);
218 return TCL_OK;
219}
220
221/*
222** Usage: btree_drop_table ID TABLENUM
223**
224** Delete an entire table from the database
225*/
226static int btree_drop_table(
227 void *NotUsed,
228 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
229 int argc, /* Number of arguments */
230 const char **argv /* Text of each argument */
231){
232 Btree *pBt;
233 int iTable;
234 int rc;
235 if( argc!=3 ){
236 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
237 " ID TABLENUM\"", 0);
238 return TCL_ERROR;
239 }
240 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
241 if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
242 rc = sqliteBtreeDropTable(pBt, iTable);
243 if( rc!=SQLITE_OK ){
244 Tcl_AppendResult(interp, errorName(rc), 0);
245 return TCL_ERROR;
246 }
247 return TCL_OK;
248}
249
250/*
251** Usage: btree_clear_table ID TABLENUM
252**
253** Remove all entries from the given table but keep the table around.
254*/
255static int btree_clear_table(
256 void *NotUsed,
257 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
258 int argc, /* Number of arguments */
259 const char **argv /* Text of each argument */
260){
261 Btree *pBt;
262 int iTable;
263 int rc;
264 if( argc!=3 ){
265 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
266 " ID TABLENUM\"", 0);
267 return TCL_ERROR;
268 }
269 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
270 if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
271 rc = sqliteBtreeClearTable(pBt, iTable);
272 if( rc!=SQLITE_OK ){
273 Tcl_AppendResult(interp, errorName(rc), 0);
274 return TCL_ERROR;
275 }
276 return TCL_OK;
277}
278
279/*
280** Usage: btree_get_meta ID
281**
282** Return meta data
283*/
284static int btree_get_meta(
285 void *NotUsed,
286 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
287 int argc, /* Number of arguments */
288 const char **argv /* Text of each argument */
289){
290 Btree *pBt;
291 int rc;
292 int i;
293 int aMeta[SQLITE_N_BTREE_META];
294 if( argc!=2 ){
295 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
296 " ID\"", 0);
297 return TCL_ERROR;
298 }
299 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
300 rc = sqliteBtreeGetMeta(pBt, aMeta);
301 if( rc!=SQLITE_OK ){
302 Tcl_AppendResult(interp, errorName(rc), 0);
303 return TCL_ERROR;
304 }
305 for(i=0; i<SQLITE_N_BTREE_META; i++){
306 char zBuf[30];
307 sprintf(zBuf,"%d",aMeta[i]);
308 Tcl_AppendElement(interp, zBuf);
309 }
310 return TCL_OK;
311}
312
313/*
314** Usage: btree_update_meta ID METADATA...
315**
316** Return meta data
317*/
318static int btree_update_meta(
319 void *NotUsed,
320 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
321 int argc, /* Number of arguments */
322 const char **argv /* Text of each argument */
323){
324 Btree *pBt;
325 int rc;
326 int i;
327 int aMeta[SQLITE_N_BTREE_META];
328
329 if( argc!=2+SQLITE_N_BTREE_META ){
330 char zBuf[30];
331 sprintf(zBuf,"%d",SQLITE_N_BTREE_META);
332 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
333 " ID METADATA...\" (METADATA is ", zBuf, " integers)", 0);
334 return TCL_ERROR;
335 }
336 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
337 for(i=0; i<SQLITE_N_BTREE_META; i++){
338 if( Tcl_GetInt(interp, argv[i+2], &aMeta[i]) ) return TCL_ERROR;
339 }
340 rc = sqliteBtreeUpdateMeta(pBt, aMeta);
341 if( rc!=SQLITE_OK ){
342 Tcl_AppendResult(interp, errorName(rc), 0);
343 return TCL_ERROR;
344 }
345 return TCL_OK;
346}
347
348/*
349** Usage: btree_page_dump ID PAGENUM
350**
351** Print a disassembly of a page on standard output
352*/
353static int btree_page_dump(
354 void *NotUsed,
355 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
356 int argc, /* Number of arguments */
357 const char **argv /* Text of each argument */
358){
359 Btree *pBt;
360 int iPage;
361 int rc;
362
363 if( argc!=3 ){
364 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
365 " ID\"", 0);
366 return TCL_ERROR;
367 }
368 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
369 if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR;
370 rc = sqliteBtreePageDump(pBt, iPage, 0);
371 if( rc!=SQLITE_OK ){
372 Tcl_AppendResult(interp, errorName(rc), 0);
373 return TCL_ERROR;
374 }
375 return TCL_OK;
376}
377
378/*
379** Usage: btree_tree_dump ID PAGENUM
380**
381** Print a disassembly of a page and all its child pages on standard output
382*/
383static int btree_tree_dump(
384 void *NotUsed,
385 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
386 int argc, /* Number of arguments */
387 const char **argv /* Text of each argument */
388){
389 Btree *pBt;
390 int iPage;
391 int rc;
392
393 if( argc!=3 ){
394 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
395 " ID\"", 0);
396 return TCL_ERROR;
397 }
398 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
399 if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR;
400 rc = sqliteBtreePageDump(pBt, iPage, 1);
401 if( rc!=SQLITE_OK ){
402 Tcl_AppendResult(interp, errorName(rc), 0);
403 return TCL_ERROR;
404 }
405 return TCL_OK;
406}
407
408/*
409** Usage: btree_pager_stats ID
410**
411** Returns pager statistics
412*/
413static int btree_pager_stats(
414 void *NotUsed,
415 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
416 int argc, /* Number of arguments */
417 const char **argv /* Text of each argument */
418){
419 Btree *pBt;
420 int i;
421 int *a;
422
423 if( argc!=2 ){
424 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
425 " ID\"", 0);
426 return TCL_ERROR;
427 }
428 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
429 a = sqlitepager_stats(sqliteBtreePager(pBt));
430 for(i=0; i<9; i++){
431 static char *zName[] = {
432 "ref", "page", "max", "size", "state", "err",
433 "hit", "miss", "ovfl",
434 };
435 char zBuf[100];
436 Tcl_AppendElement(interp, zName[i]);
437 sprintf(zBuf,"%d",a[i]);
438 Tcl_AppendElement(interp, zBuf);
439 }
440 return TCL_OK;
441}
442
443/*
444** Usage: btree_pager_ref_dump ID
445**
446** Print out all outstanding pages.
447*/
448static int btree_pager_ref_dump(
449 void *NotUsed,
450 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
451 int argc, /* Number of arguments */
452 const char **argv /* Text of each argument */
453){
454 Btree *pBt;
455
456 if( argc!=2 ){
457 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
458 " ID\"", 0);
459 return TCL_ERROR;
460 }
461 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
462 sqlitepager_refdump(sqliteBtreePager(pBt));
463 return TCL_OK;
464}
465
466/*
467** Usage: btree_integrity_check ID ROOT ...
468**
469** Look through every page of the given BTree file to verify correct
470** formatting and linkage. Return a line of text for each problem found.
471** Return an empty string if everything worked.
472*/
473static int btree_integrity_check(
474 void *NotUsed,
475 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
476 int argc, /* Number of arguments */
477 const char **argv /* Text of each argument */
478){
479 Btree *pBt;
480 char *zResult;
481 int nRoot;
482 int *aRoot;
483 int i;
484
485 if( argc<3 ){
486 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
487 " ID ROOT ...\"", 0);
488 return TCL_ERROR;
489 }
490 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
491 nRoot = argc-2;
492 aRoot = malloc( sizeof(int)*(argc-2) );
493 for(i=0; i<argc-2; i++){
494 if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR;
495 }
496 zResult = sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot);
497 if( zResult ){
498 Tcl_AppendResult(interp, zResult, 0);
499 sqliteFree(zResult);
500 }
501 return TCL_OK;
502}
503
504/*
505** Usage: btree_cursor ID TABLENUM WRITEABLE
506**
507** Create a new cursor. Return the ID for the cursor.
508*/
509static int btree_cursor(
510 void *NotUsed,
511 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
512 int argc, /* Number of arguments */
513 const char **argv /* Text of each argument */
514){
515 Btree *pBt;
516 int iTable;
517 BtCursor *pCur;
518 int rc;
519 int wrFlag;
520 char zBuf[30];
521
522 if( argc!=4 ){
523 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
524 " ID TABLENUM WRITEABLE\"", 0);
525 return TCL_ERROR;
526 }
527 if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
528 if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
529 if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
530 rc = sqliteBtreeCursor(pBt, iTable, wrFlag, &pCur);
531 if( rc ){
532 Tcl_AppendResult(interp, errorName(rc), 0);
533 return TCL_ERROR;
534 }
535 sprintf(zBuf,"0x%x", (int)pCur);
536 Tcl_AppendResult(interp, zBuf, 0);
537 return SQLITE_OK;
538}
539
540/*
541** Usage: btree_close_cursor ID
542**
543** Close a cursor opened using btree_cursor.
544*/
545static int btree_close_cursor(
546 void *NotUsed,
547 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
548 int argc, /* Number of arguments */
549 const char **argv /* Text of each argument */
550){
551 BtCursor *pCur;
552 int rc;
553
554 if( argc!=2 ){
555 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
556 " ID\"", 0);
557 return TCL_ERROR;
558 }
559 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
560 rc = sqliteBtreeCloseCursor(pCur);
561 if( rc ){
562 Tcl_AppendResult(interp, errorName(rc), 0);
563 return TCL_ERROR;
564 }
565 return SQLITE_OK;
566}
567
568/*
569** Usage: btree_move_to ID KEY
570**
571** Move the cursor to the entry with the given key.
572*/
573static int btree_move_to(
574 void *NotUsed,
575 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
576 int argc, /* Number of arguments */
577 const char **argv /* Text of each argument */
578){
579 BtCursor *pCur;
580 int rc;
581 int res;
582 char zBuf[20];
583
584 if( argc!=3 ){
585 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
586 " ID KEY\"", 0);
587 return TCL_ERROR;
588 }
589 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
590 rc = sqliteBtreeMoveto(pCur, argv[2], strlen(argv[2]), &res);
591 if( rc ){
592 Tcl_AppendResult(interp, errorName(rc), 0);
593 return TCL_ERROR;
594 }
595 if( res<0 ) res = -1;
596 if( res>0 ) res = 1;
597 sprintf(zBuf,"%d",res);
598 Tcl_AppendResult(interp, zBuf, 0);
599 return SQLITE_OK;
600}
601
602/*
603** Usage: btree_delete ID
604**
605** Delete the entry that the cursor is pointing to
606*/
607static int btree_delete(
608 void *NotUsed,
609 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
610 int argc, /* Number of arguments */
611 const char **argv /* Text of each argument */
612){
613 BtCursor *pCur;
614 int rc;
615
616 if( argc!=2 ){
617 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
618 " ID\"", 0);
619 return TCL_ERROR;
620 }
621 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
622 rc = sqliteBtreeDelete(pCur);
623 if( rc ){
624 Tcl_AppendResult(interp, errorName(rc), 0);
625 return TCL_ERROR;
626 }
627 return SQLITE_OK;
628}
629
630/*
631** Usage: btree_insert ID KEY DATA
632**
633** Create a new entry with the given key and data. If an entry already
634** exists with the same key the old entry is overwritten.
635*/
636static int btree_insert(
637 void *NotUsed,
638 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
639 int argc, /* Number of arguments */
640 const char **argv /* Text of each argument */
641){
642 BtCursor *pCur;
643 int rc;
644
645 if( argc!=4 ){
646 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
647 " ID KEY DATA\"", 0);
648 return TCL_ERROR;
649 }
650 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
651 rc = sqliteBtreeInsert(pCur, argv[2], strlen(argv[2]),
652 argv[3], strlen(argv[3]));
653 if( rc ){
654 Tcl_AppendResult(interp, errorName(rc), 0);
655 return TCL_ERROR;
656 }
657 return SQLITE_OK;
658}
659
660/*
661** Usage: btree_next ID
662**
663** Move the cursor to the next entry in the table. Return 0 on success
664** or 1 if the cursor was already on the last entry in the table or if
665** the table is empty.
666*/
667static int btree_next(
668 void *NotUsed,
669 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
670 int argc, /* Number of arguments */
671 const char **argv /* Text of each argument */
672){
673 BtCursor *pCur;
674 int rc;
675 int res = 0;
676 char zBuf[100];
677
678 if( argc!=2 ){
679 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
680 " ID\"", 0);
681 return TCL_ERROR;
682 }
683 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
684 rc = sqliteBtreeNext(pCur, &res);
685 if( rc ){
686 Tcl_AppendResult(interp, errorName(rc), 0);
687 return TCL_ERROR;
688 }
689 sprintf(zBuf,"%d",res);
690 Tcl_AppendResult(interp, zBuf, 0);
691 return SQLITE_OK;
692}
693
694/*
695** Usage: btree_prev ID
696**
697** Move the cursor to the previous entry in the table. Return 0 on
698** success and 1 if the cursor was already on the first entry in
699** the table or if the table was empty.
700*/
701static int btree_prev(
702 void *NotUsed,
703 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
704 int argc, /* Number of arguments */
705 const char **argv /* Text of each argument */
706){
707 BtCursor *pCur;
708 int rc;
709 int res = 0;
710 char zBuf[100];
711
712 if( argc!=2 ){
713 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
714 " ID\"", 0);
715 return TCL_ERROR;
716 }
717 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
718 rc = sqliteBtreePrevious(pCur, &res);
719 if( rc ){
720 Tcl_AppendResult(interp, errorName(rc), 0);
721 return TCL_ERROR;
722 }
723 sprintf(zBuf,"%d",res);
724 Tcl_AppendResult(interp, zBuf, 0);
725 return SQLITE_OK;
726}
727
728/*
729** Usage: btree_first ID
730**
731** Move the cursor to the first entry in the table. Return 0 if the
732** cursor was left point to something and 1 if the table is empty.
733*/
734static int btree_first(
735 void *NotUsed,
736 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
737 int argc, /* Number of arguments */
738 const char **argv /* Text of each argument */
739){
740 BtCursor *pCur;
741 int rc;
742 int res = 0;
743 char zBuf[100];
744
745 if( argc!=2 ){
746 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
747 " ID\"", 0);
748 return TCL_ERROR;
749 }
750 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
751 rc = sqliteBtreeFirst(pCur, &res);
752 if( rc ){
753 Tcl_AppendResult(interp, errorName(rc), 0);
754 return TCL_ERROR;
755 }
756 sprintf(zBuf,"%d",res);
757 Tcl_AppendResult(interp, zBuf, 0);
758 return SQLITE_OK;
759}
760
761/*
762** Usage: btree_last ID
763**
764** Move the cursor to the last entry in the table. Return 0 if the
765** cursor was left point to something and 1 if the table is empty.
766*/
767static int btree_last(
768 void *NotUsed,
769 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
770 int argc, /* Number of arguments */
771 const char **argv /* Text of each argument */
772){
773 BtCursor *pCur;
774 int rc;
775 int res = 0;
776 char zBuf[100];
777
778 if( argc!=2 ){
779 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
780 " ID\"", 0);
781 return TCL_ERROR;
782 }
783 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
784 rc = sqliteBtreeLast(pCur, &res);
785 if( rc ){
786 Tcl_AppendResult(interp, errorName(rc), 0);
787 return TCL_ERROR;
788 }
789 sprintf(zBuf,"%d",res);
790 Tcl_AppendResult(interp, zBuf, 0);
791 return SQLITE_OK;
792}
793
794/*
795** Usage: btree_key ID
796**
797** Return the key for the entry at which the cursor is pointing.
798*/
799static int btree_key(
800 void *NotUsed,
801 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
802 int argc, /* Number of arguments */
803 const char **argv /* Text of each argument */
804){
805 BtCursor *pCur;
806 int rc;
807 int n;
808 char *zBuf;
809
810 if( argc!=2 ){
811 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
812 " ID\"", 0);
813 return TCL_ERROR;
814 }
815 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
816 sqliteBtreeKeySize(pCur, &n);
817 zBuf = malloc( n+1 );
818 rc = sqliteBtreeKey(pCur, 0, n, zBuf);
819 if( rc!=n ){
820 char zMsg[100];
821 free(zBuf);
822 sprintf(zMsg, "truncated key: got %d of %d bytes", rc, n);
823 Tcl_AppendResult(interp, zMsg, 0);
824 return TCL_ERROR;
825 }
826 zBuf[n] = 0;
827 Tcl_AppendResult(interp, zBuf, 0);
828 free(zBuf);
829 return SQLITE_OK;
830}
831
832/*
833** Usage: btree_data ID
834**
835** Return the data for the entry at which the cursor is pointing.
836*/
837static int btree_data(
838 void *NotUsed,
839 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
840 int argc, /* Number of arguments */
841 const char **argv /* Text of each argument */
842){
843 BtCursor *pCur;
844 int rc;
845 int n;
846 char *zBuf;
847
848 if( argc!=2 ){
849 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
850 " ID\"", 0);
851 return TCL_ERROR;
852 }
853 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
854 sqliteBtreeDataSize(pCur, &n);
855 zBuf = malloc( n+1 );
856 rc = sqliteBtreeData(pCur, 0, n, zBuf);
857 if( rc!=n ){
858 char zMsg[100];
859 free(zBuf);
860 sprintf(zMsg, "truncated data: got %d of %d bytes", rc, n);
861 Tcl_AppendResult(interp, zMsg, 0);
862 return TCL_ERROR;
863 }
864 zBuf[n] = 0;
865 Tcl_AppendResult(interp, zBuf, 0);
866 free(zBuf);
867 return SQLITE_OK;
868}
869
870/*
871** Usage: btree_payload_size ID
872**
873** Return the number of bytes of payload
874*/
875static int btree_payload_size(
876 void *NotUsed,
877 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
878 int argc, /* Number of arguments */
879 const char **argv /* Text of each argument */
880){
881 BtCursor *pCur;
882 int n1, n2;
883 char zBuf[50];
884
885 if( argc!=2 ){
886 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
887 " ID\"", 0);
888 return TCL_ERROR;
889 }
890 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
891 sqliteBtreeKeySize(pCur, &n1);
892 sqliteBtreeDataSize(pCur, &n2);
893 sprintf(zBuf, "%d", n1+n2);
894 Tcl_AppendResult(interp, zBuf, 0);
895 return SQLITE_OK;
896}
897
898/*
899** Usage: btree_cursor_dump ID
900**
901** Return eight integers containing information about the entry the
902** cursor is pointing to:
903**
904** aResult[0] = The page number
905** aResult[1] = The entry number
906** aResult[2] = Total number of entries on this page
907** aResult[3] = Size of this entry
908** aResult[4] = Number of free bytes on this page
909** aResult[5] = Number of free blocks on the page
910** aResult[6] = Page number of the left child of this entry
911** aResult[7] = Page number of the right child for the whole page
912*/
913static int btree_cursor_dump(
914 void *NotUsed,
915 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
916 int argc, /* Number of arguments */
917 const char **argv /* Text of each argument */
918){
919 BtCursor *pCur;
920 int rc;
921 int i, j;
922 int aResult[8];
923 char zBuf[400];
924
925 if( argc!=2 ){
926 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
927 " ID\"", 0);
928 return TCL_ERROR;
929 }
930 if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
931 rc = sqliteBtreeCursorDump(pCur, aResult);
932 if( rc ){
933 Tcl_AppendResult(interp, errorName(rc), 0);
934 return TCL_ERROR;
935 }
936 j = 0;
937 for(i=0; i<sizeof(aResult)/sizeof(aResult[0]); i++){
938 sprintf(&zBuf[j]," %d", aResult[i]);
939 j += strlen(&zBuf[j]);
940 }
941 Tcl_AppendResult(interp, &zBuf[1], 0);
942 return SQLITE_OK;
943}
944
945/*
946** Register commands with the TCL interpreter.
947*/
948int Sqlitetest3_Init(Tcl_Interp *interp){
949 static struct {
950 char *zName;
951 Tcl_CmdProc *xProc;
952 } aCmd[] = {
953 { "btree_open", (Tcl_CmdProc*)btree_open },
954 { "btree_close", (Tcl_CmdProc*)btree_close },
955 { "btree_begin_transaction", (Tcl_CmdProc*)btree_begin_transaction },
956 { "btree_commit", (Tcl_CmdProc*)btree_commit },
957 { "btree_rollback", (Tcl_CmdProc*)btree_rollback },
958 { "btree_create_table", (Tcl_CmdProc*)btree_create_table },
959 { "btree_drop_table", (Tcl_CmdProc*)btree_drop_table },
960 { "btree_clear_table", (Tcl_CmdProc*)btree_clear_table },
961 { "btree_get_meta", (Tcl_CmdProc*)btree_get_meta },
962 { "btree_update_meta", (Tcl_CmdProc*)btree_update_meta },
963 { "btree_page_dump", (Tcl_CmdProc*)btree_page_dump },
964 { "btree_tree_dump", (Tcl_CmdProc*)btree_tree_dump },
965 { "btree_pager_stats", (Tcl_CmdProc*)btree_pager_stats },
966 { "btree_pager_ref_dump", (Tcl_CmdProc*)btree_pager_ref_dump },
967 { "btree_cursor", (Tcl_CmdProc*)btree_cursor },
968 { "btree_close_cursor", (Tcl_CmdProc*)btree_close_cursor },
969 { "btree_move_to", (Tcl_CmdProc*)btree_move_to },
970 { "btree_delete", (Tcl_CmdProc*)btree_delete },
971 { "btree_insert", (Tcl_CmdProc*)btree_insert },
972 { "btree_next", (Tcl_CmdProc*)btree_next },
973 { "btree_prev", (Tcl_CmdProc*)btree_prev },
974 { "btree_key", (Tcl_CmdProc*)btree_key },
975 { "btree_data", (Tcl_CmdProc*)btree_data },
976 { "btree_payload_size", (Tcl_CmdProc*)btree_payload_size },
977 { "btree_first", (Tcl_CmdProc*)btree_first },
978 { "btree_last", (Tcl_CmdProc*)btree_last },
979 { "btree_cursor_dump", (Tcl_CmdProc*)btree_cursor_dump },
980 { "btree_integrity_check", (Tcl_CmdProc*)btree_integrity_check },
981 };
982 int i;
983
984 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
985 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
986 }
987 Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager_refinfo_enable,
988 TCL_LINK_INT);
989 Tcl_LinkVar(interp, "btree_native_byte_order",(char*)&btree_native_byte_order,
990 TCL_LINK_INT);
991 return TCL_OK;
992}
Note: See TracBrowser for help on using the repository browser.