Annotation of embedaddon/sqlite3/src/test3.c, revision 1.1.1.1
1.1 misho 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: #include "sqliteInt.h"
17: #include "btreeInt.h"
18: #include "tcl.h"
19: #include <stdlib.h>
20: #include <string.h>
21:
22: /*
23: ** Interpret an SQLite error number
24: */
25: static char *errorName(int rc){
26: char *zName;
27: switch( rc ){
28: case SQLITE_OK: zName = "SQLITE_OK"; break;
29: case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
30: case SQLITE_PERM: zName = "SQLITE_PERM"; break;
31: case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
32: case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
33: case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
34: case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
35: case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
36: case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
37: case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
38: case SQLITE_FULL: zName = "SQLITE_FULL"; break;
39: case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
40: case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
41: case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
42: case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
43: default: zName = "SQLITE_Unknown"; break;
44: }
45: return zName;
46: }
47:
48: /*
49: ** A bogus sqlite3 connection structure for use in the btree
50: ** tests.
51: */
52: static sqlite3 sDb;
53: static int nRefSqlite3 = 0;
54:
55: /*
56: ** Usage: btree_open FILENAME NCACHE
57: **
58: ** Open a new database
59: */
60: static int btree_open(
61: void *NotUsed,
62: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
63: int argc, /* Number of arguments */
64: const char **argv /* Text of each argument */
65: ){
66: Btree *pBt;
67: int rc, nCache;
68: char zBuf[100];
69: int n;
70: char *zFilename;
71: if( argc!=3 ){
72: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
73: " FILENAME NCACHE FLAGS\"", 0);
74: return TCL_ERROR;
75: }
76: if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
77: nRefSqlite3++;
78: if( nRefSqlite3==1 ){
79: sDb.pVfs = sqlite3_vfs_find(0);
80: sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
81: sqlite3_mutex_enter(sDb.mutex);
82: }
83: n = strlen(argv[1]);
84: zFilename = sqlite3_malloc( n+2 );
85: if( zFilename==0 ) return TCL_ERROR;
86: memcpy(zFilename, argv[1], n+1);
87: zFilename[n+1] = 0;
88: rc = sqlite3BtreeOpen(sDb.pVfs, zFilename, &sDb, &pBt, 0,
89: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
90: sqlite3_free(zFilename);
91: if( rc!=SQLITE_OK ){
92: Tcl_AppendResult(interp, errorName(rc), 0);
93: return TCL_ERROR;
94: }
95: sqlite3BtreeSetCacheSize(pBt, nCache);
96: sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pBt);
97: Tcl_AppendResult(interp, zBuf, 0);
98: return TCL_OK;
99: }
100:
101: /*
102: ** Usage: btree_close ID
103: **
104: ** Close the given database.
105: */
106: static int btree_close(
107: void *NotUsed,
108: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
109: int argc, /* Number of arguments */
110: const char **argv /* Text of each argument */
111: ){
112: Btree *pBt;
113: int rc;
114: if( argc!=2 ){
115: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
116: " ID\"", 0);
117: return TCL_ERROR;
118: }
119: pBt = sqlite3TestTextToPtr(argv[1]);
120: rc = sqlite3BtreeClose(pBt);
121: if( rc!=SQLITE_OK ){
122: Tcl_AppendResult(interp, errorName(rc), 0);
123: return TCL_ERROR;
124: }
125: nRefSqlite3--;
126: if( nRefSqlite3==0 ){
127: sqlite3_mutex_leave(sDb.mutex);
128: sqlite3_mutex_free(sDb.mutex);
129: sDb.mutex = 0;
130: sDb.pVfs = 0;
131: }
132: return TCL_OK;
133: }
134:
135:
136: /*
137: ** Usage: btree_begin_transaction ID
138: **
139: ** Start a new transaction
140: */
141: static int btree_begin_transaction(
142: void *NotUsed,
143: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
144: int argc, /* Number of arguments */
145: const char **argv /* Text of each argument */
146: ){
147: Btree *pBt;
148: int rc;
149: if( argc!=2 ){
150: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
151: " ID\"", 0);
152: return TCL_ERROR;
153: }
154: pBt = sqlite3TestTextToPtr(argv[1]);
155: sqlite3BtreeEnter(pBt);
156: rc = sqlite3BtreeBeginTrans(pBt, 1);
157: sqlite3BtreeLeave(pBt);
158: if( rc!=SQLITE_OK ){
159: Tcl_AppendResult(interp, errorName(rc), 0);
160: return TCL_ERROR;
161: }
162: return TCL_OK;
163: }
164:
165: /*
166: ** Usage: btree_pager_stats ID
167: **
168: ** Returns pager statistics
169: */
170: static int btree_pager_stats(
171: void *NotUsed,
172: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
173: int argc, /* Number of arguments */
174: const char **argv /* Text of each argument */
175: ){
176: Btree *pBt;
177: int i;
178: int *a;
179:
180: if( argc!=2 ){
181: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
182: " ID\"", 0);
183: return TCL_ERROR;
184: }
185: pBt = sqlite3TestTextToPtr(argv[1]);
186:
187: /* Normally in this file, with a b-tree handle opened using the
188: ** [btree_open] command it is safe to call sqlite3BtreeEnter() directly.
189: ** But this function is sometimes called with a btree handle obtained
190: ** from an open SQLite connection (using [btree_from_db]). In this case
191: ** we need to obtain the mutex for the controlling SQLite handle before
192: ** it is safe to call sqlite3BtreeEnter().
193: */
194: sqlite3_mutex_enter(pBt->db->mutex);
195:
196: sqlite3BtreeEnter(pBt);
197: a = sqlite3PagerStats(sqlite3BtreePager(pBt));
198: for(i=0; i<11; i++){
199: static char *zName[] = {
200: "ref", "page", "max", "size", "state", "err",
201: "hit", "miss", "ovfl", "read", "write"
202: };
203: char zBuf[100];
204: Tcl_AppendElement(interp, zName[i]);
205: sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]);
206: Tcl_AppendElement(interp, zBuf);
207: }
208: sqlite3BtreeLeave(pBt);
209:
210: /* Release the mutex on the SQLite handle that controls this b-tree */
211: sqlite3_mutex_leave(pBt->db->mutex);
212: return TCL_OK;
213: }
214:
215: /*
216: ** Usage: btree_cursor ID TABLENUM WRITEABLE
217: **
218: ** Create a new cursor. Return the ID for the cursor.
219: */
220: static int btree_cursor(
221: void *NotUsed,
222: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
223: int argc, /* Number of arguments */
224: const char **argv /* Text of each argument */
225: ){
226: Btree *pBt;
227: int iTable;
228: BtCursor *pCur;
229: int rc = SQLITE_OK;
230: int wrFlag;
231: char zBuf[30];
232:
233: if( argc!=4 ){
234: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
235: " ID TABLENUM WRITEABLE\"", 0);
236: return TCL_ERROR;
237: }
238: pBt = sqlite3TestTextToPtr(argv[1]);
239: if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
240: if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
241: pCur = (BtCursor *)ckalloc(sqlite3BtreeCursorSize());
242: memset(pCur, 0, sqlite3BtreeCursorSize());
243: sqlite3BtreeEnter(pBt);
244: #ifndef SQLITE_OMIT_SHARED_CACHE
245: rc = sqlite3BtreeLockTable(pBt, iTable, wrFlag);
246: #endif
247: if( rc==SQLITE_OK ){
248: rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur);
249: }
250: sqlite3BtreeLeave(pBt);
251: if( rc ){
252: ckfree((char *)pCur);
253: Tcl_AppendResult(interp, errorName(rc), 0);
254: return TCL_ERROR;
255: }
256: sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur);
257: Tcl_AppendResult(interp, zBuf, 0);
258: return SQLITE_OK;
259: }
260:
261: /*
262: ** Usage: btree_close_cursor ID
263: **
264: ** Close a cursor opened using btree_cursor.
265: */
266: static int btree_close_cursor(
267: void *NotUsed,
268: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
269: int argc, /* Number of arguments */
270: const char **argv /* Text of each argument */
271: ){
272: BtCursor *pCur;
273: Btree *pBt;
274: int rc;
275:
276: if( argc!=2 ){
277: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
278: " ID\"", 0);
279: return TCL_ERROR;
280: }
281: pCur = sqlite3TestTextToPtr(argv[1]);
282: pBt = pCur->pBtree;
283: sqlite3BtreeEnter(pBt);
284: rc = sqlite3BtreeCloseCursor(pCur);
285: sqlite3BtreeLeave(pBt);
286: ckfree((char *)pCur);
287: if( rc ){
288: Tcl_AppendResult(interp, errorName(rc), 0);
289: return TCL_ERROR;
290: }
291: return SQLITE_OK;
292: }
293:
294: /*
295: ** Usage: btree_next ID
296: **
297: ** Move the cursor to the next entry in the table. Return 0 on success
298: ** or 1 if the cursor was already on the last entry in the table or if
299: ** the table is empty.
300: */
301: static int btree_next(
302: void *NotUsed,
303: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
304: int argc, /* Number of arguments */
305: const char **argv /* Text of each argument */
306: ){
307: BtCursor *pCur;
308: int rc;
309: int res = 0;
310: char zBuf[100];
311:
312: if( argc!=2 ){
313: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
314: " ID\"", 0);
315: return TCL_ERROR;
316: }
317: pCur = sqlite3TestTextToPtr(argv[1]);
318: sqlite3BtreeEnter(pCur->pBtree);
319: rc = sqlite3BtreeNext(pCur, &res);
320: sqlite3BtreeLeave(pCur->pBtree);
321: if( rc ){
322: Tcl_AppendResult(interp, errorName(rc), 0);
323: return TCL_ERROR;
324: }
325: sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
326: Tcl_AppendResult(interp, zBuf, 0);
327: return SQLITE_OK;
328: }
329:
330: /*
331: ** Usage: btree_first ID
332: **
333: ** Move the cursor to the first entry in the table. Return 0 if the
334: ** cursor was left point to something and 1 if the table is empty.
335: */
336: static int btree_first(
337: void *NotUsed,
338: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
339: int argc, /* Number of arguments */
340: const char **argv /* Text of each argument */
341: ){
342: BtCursor *pCur;
343: int rc;
344: int res = 0;
345: char zBuf[100];
346:
347: if( argc!=2 ){
348: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
349: " ID\"", 0);
350: return TCL_ERROR;
351: }
352: pCur = sqlite3TestTextToPtr(argv[1]);
353: sqlite3BtreeEnter(pCur->pBtree);
354: rc = sqlite3BtreeFirst(pCur, &res);
355: sqlite3BtreeLeave(pCur->pBtree);
356: if( rc ){
357: Tcl_AppendResult(interp, errorName(rc), 0);
358: return TCL_ERROR;
359: }
360: sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
361: Tcl_AppendResult(interp, zBuf, 0);
362: return SQLITE_OK;
363: }
364:
365: /*
366: ** Usage: btree_eof ID
367: **
368: ** Return TRUE if the given cursor is not pointing at a valid entry.
369: ** Return FALSE if the cursor does point to a valid entry.
370: */
371: static int btree_eof(
372: void *NotUsed,
373: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
374: int argc, /* Number of arguments */
375: const char **argv /* Text of each argument */
376: ){
377: BtCursor *pCur;
378: int rc;
379: char zBuf[50];
380:
381: if( argc!=2 ){
382: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
383: " ID\"", 0);
384: return TCL_ERROR;
385: }
386: pCur = sqlite3TestTextToPtr(argv[1]);
387: sqlite3BtreeEnter(pCur->pBtree);
388: rc = sqlite3BtreeEof(pCur);
389: sqlite3BtreeLeave(pCur->pBtree);
390: sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", rc);
391: Tcl_AppendResult(interp, zBuf, 0);
392: return SQLITE_OK;
393: }
394:
395: /*
396: ** Usage: btree_payload_size ID
397: **
398: ** Return the number of bytes of payload
399: */
400: static int btree_payload_size(
401: void *NotUsed,
402: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
403: int argc, /* Number of arguments */
404: const char **argv /* Text of each argument */
405: ){
406: BtCursor *pCur;
407: int n2;
408: u64 n1;
409: char zBuf[50];
410:
411: if( argc!=2 ){
412: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
413: " ID\"", 0);
414: return TCL_ERROR;
415: }
416: pCur = sqlite3TestTextToPtr(argv[1]);
417: sqlite3BtreeEnter(pCur->pBtree);
418:
419: /* The cursor may be in "require-seek" state. If this is the case, the
420: ** call to BtreeDataSize() will fix it. */
421: sqlite3BtreeDataSize(pCur, (u32*)&n2);
422: if( pCur->apPage[pCur->iPage]->intKey ){
423: n1 = 0;
424: }else{
425: sqlite3BtreeKeySize(pCur, (i64*)&n1);
426: }
427: sqlite3BtreeLeave(pCur->pBtree);
428: sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", (int)(n1+n2));
429: Tcl_AppendResult(interp, zBuf, 0);
430: return SQLITE_OK;
431: }
432:
433: /*
434: ** usage: varint_test START MULTIPLIER COUNT INCREMENT
435: **
436: ** This command tests the putVarint() and getVarint()
437: ** routines, both for accuracy and for speed.
438: **
439: ** An integer is written using putVarint() and read back with
440: ** getVarint() and varified to be unchanged. This repeats COUNT
441: ** times. The first integer is START*MULTIPLIER. Each iteration
442: ** increases the integer by INCREMENT.
443: **
444: ** This command returns nothing if it works. It returns an error message
445: ** if something goes wrong.
446: */
447: static int btree_varint_test(
448: void *NotUsed,
449: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
450: int argc, /* Number of arguments */
451: const char **argv /* Text of each argument */
452: ){
453: u32 start, mult, count, incr;
454: u64 in, out;
455: int n1, n2, i, j;
456: unsigned char zBuf[100];
457: if( argc!=5 ){
458: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
459: " START MULTIPLIER COUNT INCREMENT\"", 0);
460: return TCL_ERROR;
461: }
462: if( Tcl_GetInt(interp, argv[1], (int*)&start) ) return TCL_ERROR;
463: if( Tcl_GetInt(interp, argv[2], (int*)&mult) ) return TCL_ERROR;
464: if( Tcl_GetInt(interp, argv[3], (int*)&count) ) return TCL_ERROR;
465: if( Tcl_GetInt(interp, argv[4], (int*)&incr) ) return TCL_ERROR;
466: in = start;
467: in *= mult;
468: for(i=0; i<count; i++){
469: char zErr[200];
470: n1 = putVarint(zBuf, in);
471: if( n1>9 || n1<1 ){
472: sprintf(zErr, "putVarint returned %d - should be between 1 and 9", n1);
473: Tcl_AppendResult(interp, zErr, 0);
474: return TCL_ERROR;
475: }
476: n2 = getVarint(zBuf, &out);
477: if( n1!=n2 ){
478: sprintf(zErr, "putVarint returned %d and getVarint returned %d", n1, n2);
479: Tcl_AppendResult(interp, zErr, 0);
480: return TCL_ERROR;
481: }
482: if( in!=out ){
483: sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx", in, out);
484: Tcl_AppendResult(interp, zErr, 0);
485: return TCL_ERROR;
486: }
487: if( (in & 0xffffffff)==in ){
488: u32 out32;
489: n2 = getVarint32(zBuf, out32);
490: out = out32;
491: if( n1!=n2 ){
492: sprintf(zErr, "putVarint returned %d and GetVarint32 returned %d",
493: n1, n2);
494: Tcl_AppendResult(interp, zErr, 0);
495: return TCL_ERROR;
496: }
497: if( in!=out ){
498: sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx from GetVarint32",
499: in, out);
500: Tcl_AppendResult(interp, zErr, 0);
501: return TCL_ERROR;
502: }
503: }
504:
505: /* In order to get realistic timings, run getVarint 19 more times.
506: ** This is because getVarint is called about 20 times more often
507: ** than putVarint.
508: */
509: for(j=0; j<19; j++){
510: getVarint(zBuf, &out);
511: }
512: in += incr;
513: }
514: return TCL_OK;
515: }
516:
517: /*
518: ** usage: btree_from_db DB-HANDLE
519: **
520: ** This command returns the btree handle for the main database associated
521: ** with the database-handle passed as the argument. Example usage:
522: **
523: ** sqlite3 db test.db
524: ** set bt [btree_from_db db]
525: */
526: static int btree_from_db(
527: void *NotUsed,
528: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
529: int argc, /* Number of arguments */
530: const char **argv /* Text of each argument */
531: ){
532: char zBuf[100];
533: Tcl_CmdInfo info;
534: sqlite3 *db;
535: Btree *pBt;
536: int iDb = 0;
537:
538: if( argc!=2 && argc!=3 ){
539: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
540: " DB-HANDLE ?N?\"", 0);
541: return TCL_ERROR;
542: }
543:
544: if( 1!=Tcl_GetCommandInfo(interp, argv[1], &info) ){
545: Tcl_AppendResult(interp, "No such db-handle: \"", argv[1], "\"", 0);
546: return TCL_ERROR;
547: }
548: if( argc==3 ){
549: iDb = atoi(argv[2]);
550: }
551:
552: db = *((sqlite3 **)info.objClientData);
553: assert( db );
554:
555: pBt = db->aDb[iDb].pBt;
556: sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", pBt);
557: Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
558: return TCL_OK;
559: }
560:
561: /*
562: ** Usage: btree_ismemdb ID
563: **
564: ** Return true if the B-Tree is in-memory.
565: */
566: static int btree_ismemdb(
567: void *NotUsed,
568: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
569: int argc, /* Number of arguments */
570: const char **argv /* Text of each argument */
571: ){
572: Btree *pBt;
573: int res;
574:
575: if( argc!=2 ){
576: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
577: " ID\"", 0);
578: return TCL_ERROR;
579: }
580: pBt = sqlite3TestTextToPtr(argv[1]);
581: sqlite3_mutex_enter(pBt->db->mutex);
582: sqlite3BtreeEnter(pBt);
583: res = sqlite3PagerIsMemdb(sqlite3BtreePager(pBt));
584: sqlite3BtreeLeave(pBt);
585: sqlite3_mutex_leave(pBt->db->mutex);
586: Tcl_SetObjResult(interp, Tcl_NewBooleanObj(res));
587: return SQLITE_OK;
588: }
589:
590: /*
591: ** usage: btree_set_cache_size ID NCACHE
592: **
593: ** Set the size of the cache used by btree $ID.
594: */
595: static int btree_set_cache_size(
596: void *NotUsed,
597: Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
598: int argc, /* Number of arguments */
599: const char **argv /* Text of each argument */
600: ){
601: int nCache;
602: Btree *pBt;
603:
604: if( argc!=3 ){
605: Tcl_AppendResult(
606: interp, "wrong # args: should be \"", argv[0], " BT NCACHE\"", 0);
607: return TCL_ERROR;
608: }
609: pBt = sqlite3TestTextToPtr(argv[1]);
610: if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
611:
612: sqlite3_mutex_enter(pBt->db->mutex);
613: sqlite3BtreeEnter(pBt);
614: sqlite3BtreeSetCacheSize(pBt, nCache);
615: sqlite3BtreeLeave(pBt);
616: sqlite3_mutex_leave(pBt->db->mutex);
617: return TCL_OK;
618: }
619:
620:
621:
622: /*
623: ** Register commands with the TCL interpreter.
624: */
625: int Sqlitetest3_Init(Tcl_Interp *interp){
626: static struct {
627: char *zName;
628: Tcl_CmdProc *xProc;
629: } aCmd[] = {
630: { "btree_open", (Tcl_CmdProc*)btree_open },
631: { "btree_close", (Tcl_CmdProc*)btree_close },
632: { "btree_begin_transaction", (Tcl_CmdProc*)btree_begin_transaction },
633: { "btree_pager_stats", (Tcl_CmdProc*)btree_pager_stats },
634: { "btree_cursor", (Tcl_CmdProc*)btree_cursor },
635: { "btree_close_cursor", (Tcl_CmdProc*)btree_close_cursor },
636: { "btree_next", (Tcl_CmdProc*)btree_next },
637: { "btree_eof", (Tcl_CmdProc*)btree_eof },
638: { "btree_payload_size", (Tcl_CmdProc*)btree_payload_size },
639: { "btree_first", (Tcl_CmdProc*)btree_first },
640: { "btree_varint_test", (Tcl_CmdProc*)btree_varint_test },
641: { "btree_from_db", (Tcl_CmdProc*)btree_from_db },
642: { "btree_ismemdb", (Tcl_CmdProc*)btree_ismemdb },
643: { "btree_set_cache_size", (Tcl_CmdProc*)btree_set_cache_size }
644: };
645: int i;
646:
647: for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
648: Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
649: }
650:
651: return TCL_OK;
652: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>