main.c revision 92889
11573Srgrimes/*-
21573Srgrimes * Copyright (c) 1990, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * This code is derived from software contributed to Berkeley by
61573Srgrimes * Mike Olson.
71573Srgrimes *
81573Srgrimes * Redistribution and use in source and binary forms, with or without
91573Srgrimes * modification, are permitted provided that the following conditions
101573Srgrimes * are met:
111573Srgrimes * 1. Redistributions of source code must retain the above copyright
121573Srgrimes *    notice, this list of conditions and the following disclaimer.
131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141573Srgrimes *    notice, this list of conditions and the following disclaimer in the
151573Srgrimes *    documentation and/or other materials provided with the distribution.
161573Srgrimes * 3. All advertising materials mentioning features or use of this software
171573Srgrimes *    must display the following acknowledgement:
181573Srgrimes *	This product includes software developed by the University of
191573Srgrimes *	California, Berkeley and its contributors.
201573Srgrimes * 4. Neither the name of the University nor the names of its contributors
211573Srgrimes *    may be used to endorse or promote products derived from this software
221573Srgrimes *    without specific prior written permission.
231573Srgrimes *
241573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341573Srgrimes * SUCH DAMAGE.
351573Srgrimes */
361573Srgrimes
371573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
381573Srgrimesstatic char sccsid[] = "@(#)main.c	8.1 (Berkeley) 6/4/93";
391573Srgrimes#endif /* LIBC_SCCS and not lint */
4092889Sobrien#include <sys/cdefs.h>
4192889Sobrien__FBSDID("$FreeBSD: head/lib/libc/db/test/btree.tests/main.c 92889 2002-03-21 18:49:23Z obrien $");
421573Srgrimes
431573Srgrimes#include <sys/param.h>
441573Srgrimes#include <fcntl.h>
451573Srgrimes#include <db.h>
461573Srgrimes#include <errno.h>
471573Srgrimes#include <stdio.h>
481573Srgrimes#include <ctype.h>
491573Srgrimes#include <stdlib.h>
501573Srgrimes#include <string.h>
511573Srgrimes#include "btree.h"
521573Srgrimes
531573Srgrimestypedef struct cmd_table {
541573Srgrimes	char *cmd;
551573Srgrimes	int nargs;
561573Srgrimes	int rconv;
571573Srgrimes	void (*func) __P((DB *, char **));
581573Srgrimes	char *usage, *descrip;
591573Srgrimes} cmd_table;
601573Srgrimes
611573Srgrimesint stopstop;
621573SrgrimesDB *globaldb;
631573Srgrimes
641573Srgrimesvoid append	__P((DB *, char **));
651573Srgrimesvoid bstat	__P((DB *, char **));
661573Srgrimesvoid cursor	__P((DB *, char **));
671573Srgrimesvoid delcur	__P((DB *, char **));
681573Srgrimesvoid delete	__P((DB *, char **));
691573Srgrimesvoid dump	__P((DB *, char **));
701573Srgrimesvoid first	__P((DB *, char **));
711573Srgrimesvoid get	__P((DB *, char **));
721573Srgrimesvoid help	__P((DB *, char **));
731573Srgrimesvoid iafter	__P((DB *, char **));
741573Srgrimesvoid ibefore	__P((DB *, char **));
751573Srgrimesvoid icursor	__P((DB *, char **));
761573Srgrimesvoid insert	__P((DB *, char **));
771573Srgrimesvoid keydata	__P((DBT *, DBT *));
781573Srgrimesvoid last	__P((DB *, char **));
791573Srgrimesvoid list	__P((DB *, char **));
801573Srgrimesvoid load	__P((DB *, char **));
811573Srgrimesvoid mstat	__P((DB *, char **));
821573Srgrimesvoid next	__P((DB *, char **));
831573Srgrimesint  parse	__P((char *, char **, int));
841573Srgrimesvoid previous	__P((DB *, char **));
851573Srgrimesvoid show	__P((DB *, char **));
861573Srgrimesvoid usage	__P((void));
871573Srgrimesvoid user	__P((DB *));
881573Srgrimes
891573Srgrimescmd_table commands[] = {
901573Srgrimes	"?",	0, 0, help, "help", NULL,
911573Srgrimes	"a",	2, 1, append, "append key def", "append key with data def",
921573Srgrimes	"b",	0, 0, bstat, "bstat", "stat btree",
931573Srgrimes	"c",	1, 1, cursor,  "cursor word", "move cursor to word",
941573Srgrimes	"delc",	0, 0, delcur, "delcur", "delete key the cursor references",
951573Srgrimes	"dele",	1, 1, delete, "delete word", "delete word",
961573Srgrimes	"d",	0, 0, dump, "dump", "dump database",
971573Srgrimes	"f",	0, 0, first, "first", "move cursor to first record",
981573Srgrimes	"g",	1, 1, get, "get key", "locate key",
991573Srgrimes	"h",	0, 0, help, "help", "print command summary",
1001573Srgrimes	"ia",	2, 1, iafter, "iafter key data", "insert data after key",
1011573Srgrimes	"ib",	2, 1, ibefore, "ibefore key data", "insert data before key",
1021573Srgrimes	"ic",	2, 1, icursor, "icursor key data", "replace cursor",
1031573Srgrimes	"in",	2, 1, insert, "insert key def", "insert key with data def",
1041573Srgrimes	"la",	0, 0, last, "last", "move cursor to last record",
1051573Srgrimes	"li",	1, 1, list, "list file", "list to a file",
1061573Srgrimes	"loa",	1, 0, load, "load file", NULL,
1071573Srgrimes	"loc",	1, 1, get, "get key", NULL,
1081573Srgrimes	"m",	0, 0, mstat, "mstat", "stat memory pool",
1091573Srgrimes	"n",	0, 0, next, "next", "move cursor forward one record",
1101573Srgrimes	"p",	0, 0, previous, "previous", "move cursor back one record",
1111573Srgrimes	"q",	0, 0, NULL, "quit", "quit",
1121573Srgrimes	"sh",	1, 0, show, "show page", "dump a page",
1131573Srgrimes	{ NULL },
1141573Srgrimes};
1151573Srgrimes
1161573Srgrimesint recno;					/* use record numbers */
1171573Srgrimeschar *dict = "words";				/* default dictionary */
1181573Srgrimeschar *progname;
1191573Srgrimes
1201573Srgrimesint
1211573Srgrimesmain(argc, argv)
1221573Srgrimes	int argc;
1231573Srgrimes	char **argv;
1241573Srgrimes{
1251573Srgrimes	int c;
1261573Srgrimes	DB *db;
1271573Srgrimes	BTREEINFO b;
1281573Srgrimes
1291573Srgrimes	progname = *argv;
1301573Srgrimes
1311573Srgrimes	b.flags = 0;
1321573Srgrimes	b.cachesize = 0;
1331573Srgrimes	b.maxkeypage = 0;
1341573Srgrimes	b.minkeypage = 0;
1351573Srgrimes	b.psize = 0;
1361573Srgrimes	b.compare = NULL;
1371573Srgrimes	b.prefix = NULL;
1381573Srgrimes	b.lorder = 0;
1391573Srgrimes
1401573Srgrimes	while ((c = getopt(argc, argv, "bc:di:lp:ru")) != EOF) {
1411573Srgrimes		switch (c) {
1421573Srgrimes		case 'b':
1431573Srgrimes			b.lorder = BIG_ENDIAN;
1441573Srgrimes			break;
1451573Srgrimes		case 'c':
1461573Srgrimes			b.cachesize = atoi(optarg);
1471573Srgrimes			break;
1481573Srgrimes		case 'd':
1491573Srgrimes			b.flags |= R_DUP;
1501573Srgrimes			break;
1511573Srgrimes		case 'i':
1521573Srgrimes			dict = optarg;
1531573Srgrimes			break;
1541573Srgrimes		case 'l':
1551573Srgrimes			b.lorder = LITTLE_ENDIAN;
1561573Srgrimes			break;
1571573Srgrimes		case 'p':
1581573Srgrimes			b.psize = atoi(optarg);
1591573Srgrimes			break;
1601573Srgrimes		case 'r':
1611573Srgrimes			recno = 1;
1621573Srgrimes			break;
1631573Srgrimes		case 'u':
1641573Srgrimes			b.flags = 0;
1651573Srgrimes			break;
1661573Srgrimes		default:
1671573Srgrimes			usage();
1681573Srgrimes		}
1691573Srgrimes	}
1701573Srgrimes	argc -= optind;
1711573Srgrimes	argv += optind;
1721573Srgrimes
1731573Srgrimes	if (recno)
1741573Srgrimes		db = dbopen(*argv == NULL ? NULL : *argv, O_RDWR,
1751573Srgrimes		    0, DB_RECNO, NULL);
1761573Srgrimes	else
1771573Srgrimes		db = dbopen(*argv == NULL ? NULL : *argv, O_CREAT|O_RDWR,
1781573Srgrimes		    0600, DB_BTREE, &b);
1791573Srgrimes
1801573Srgrimes	if (db == NULL) {
1811573Srgrimes		(void)fprintf(stderr, "dbopen: %s\n", strerror(errno));
1821573Srgrimes		exit(1);
1831573Srgrimes	}
1841573Srgrimes	globaldb = db;
1851573Srgrimes	user(db);
1861573Srgrimes	exit(0);
1871573Srgrimes	/* NOTREACHED */
1881573Srgrimes}
1891573Srgrimes
1901573Srgrimesvoid
1911573Srgrimesuser(db)
1921573Srgrimes	DB *db;
1931573Srgrimes{
1941573Srgrimes	FILE *ifp;
1951573Srgrimes	int argc, i, last;
1961573Srgrimes	char *lbuf, *argv[4], buf[512];
1971573Srgrimes
1981573Srgrimes	if ((ifp = fopen("/dev/tty", "r")) == NULL) {
1991573Srgrimes		(void)fprintf(stderr,
2001573Srgrimes		    "/dev/tty: %s\n", strerror(errno));
2011573Srgrimes		exit(1);
2021573Srgrimes	}
2031573Srgrimes	for (last = 0;;) {
2041573Srgrimes		(void)printf("> ");
2051573Srgrimes		(void)fflush(stdout);
2061573Srgrimes		if ((lbuf = fgets(&buf[0], 512, ifp)) == NULL)
2071573Srgrimes			break;
2081573Srgrimes		if (lbuf[0] == '\n') {
2091573Srgrimes			i = last;
2101573Srgrimes			goto uselast;
2111573Srgrimes		}
2121573Srgrimes		lbuf[strlen(lbuf) - 1] = '\0';
2131573Srgrimes
2141573Srgrimes		if (lbuf[0] == 'q')
2151573Srgrimes			break;
2161573Srgrimes
2171573Srgrimes		argc = parse(lbuf, &argv[0], 3);
2181573Srgrimes		if (argc == 0)
2191573Srgrimes			continue;
2201573Srgrimes
2211573Srgrimes		for (i = 0; commands[i].cmd != NULL; i++)
2221573Srgrimes			if (strncmp(commands[i].cmd, argv[0],
2231573Srgrimes			    strlen(commands[i].cmd)) == 0)
2241573Srgrimes				break;
2251573Srgrimes
2261573Srgrimes		if (commands[i].cmd == NULL) {
2271573Srgrimes			(void)fprintf(stderr,
2281573Srgrimes			    "%s: command unknown ('help' for help)\n", lbuf);
2291573Srgrimes			continue;
2301573Srgrimes		}
2311573Srgrimes
2321573Srgrimes		if (commands[i].nargs != argc - 1) {
2331573Srgrimes			(void)fprintf(stderr, "usage: %s\n", commands[i].usage);
2341573Srgrimes			continue;
2351573Srgrimes		}
2361573Srgrimes
2371573Srgrimes		if (recno && commands[i].rconv) {
2381573Srgrimes			static recno_t nlong;
2391573Srgrimes			nlong = atoi(argv[1]);
2401573Srgrimes			argv[1] = (char *)&nlong;
2411573Srgrimes		}
2421573Srgrimesuselast:	last = i;
2431573Srgrimes		(*commands[i].func)(db, argv);
2441573Srgrimes	}
2451573Srgrimes	if ((db->sync)(db) == RET_ERROR)
2461573Srgrimes		perror("dbsync");
2471573Srgrimes	else if ((db->close)(db) == RET_ERROR)
2481573Srgrimes		perror("dbclose");
2491573Srgrimes}
2501573Srgrimes
2511573Srgrimesint
2521573Srgrimesparse(lbuf, argv, maxargc)
2531573Srgrimes	char *lbuf, **argv;
2541573Srgrimes	int maxargc;
2551573Srgrimes{
2561573Srgrimes	int argc = 0;
2571573Srgrimes	char *c;
2581573Srgrimes
2591573Srgrimes	c = lbuf;
2601573Srgrimes	while (isspace(*c))
2611573Srgrimes		c++;
2621573Srgrimes	while (*c != '\0' && argc < maxargc) {
2631573Srgrimes		*argv++ = c;
2641573Srgrimes		argc++;
2651573Srgrimes		while (!isspace(*c) && *c != '\0') {
2661573Srgrimes			c++;
2671573Srgrimes		}
2681573Srgrimes		while (isspace(*c))
2691573Srgrimes			*c++ = '\0';
2701573Srgrimes	}
2711573Srgrimes	return (argc);
2721573Srgrimes}
2731573Srgrimes
2741573Srgrimesvoid
2751573Srgrimesappend(db, argv)
2761573Srgrimes	DB *db;
2771573Srgrimes	char **argv;
2781573Srgrimes{
2791573Srgrimes	DBT key, data;
2801573Srgrimes	int status;
2811573Srgrimes
2821573Srgrimes	if (!recno) {
2831573Srgrimes		(void)fprintf(stderr,
2841573Srgrimes		    "append only available for recno db's.\n");
2851573Srgrimes		return;
2861573Srgrimes	}
2871573Srgrimes	key.data = argv[1];
2881573Srgrimes	key.size = sizeof(recno_t);
2891573Srgrimes	data.data = argv[2];
2901573Srgrimes	data.size = strlen(data.data);
2911573Srgrimes	status = (db->put)(db, &key, &data, R_APPEND);
2921573Srgrimes	switch (status) {
2931573Srgrimes	case RET_ERROR:
2941573Srgrimes		perror("append/put");
2951573Srgrimes		break;
2961573Srgrimes	case RET_SPECIAL:
2971573Srgrimes		(void)printf("%s (duplicate key)\n", argv[1]);
2981573Srgrimes		break;
2991573Srgrimes	case RET_SUCCESS:
3001573Srgrimes		break;
3011573Srgrimes	}
3021573Srgrimes}
3031573Srgrimes
3041573Srgrimesvoid
3051573Srgrimescursor(db, argv)
3061573Srgrimes	DB *db;
3071573Srgrimes	char **argv;
3081573Srgrimes{
3091573Srgrimes	DBT data, key;
3101573Srgrimes	int status;
3111573Srgrimes
3121573Srgrimes	key.data = argv[1];
3131573Srgrimes	if (recno)
3141573Srgrimes		key.size = sizeof(recno_t);
3151573Srgrimes	else
3161573Srgrimes		key.size = strlen(argv[1]) + 1;
3171573Srgrimes	status = (*db->seq)(db, &key, &data, R_CURSOR);
3181573Srgrimes	switch (status) {
3191573Srgrimes	case RET_ERROR:
3201573Srgrimes		perror("cursor/seq");
3211573Srgrimes		break;
3221573Srgrimes	case RET_SPECIAL:
3231573Srgrimes		(void)printf("key not found\n");
3241573Srgrimes		break;
3251573Srgrimes	case RET_SUCCESS:
3261573Srgrimes		keydata(&key, &data);
3271573Srgrimes		break;
3281573Srgrimes	}
3291573Srgrimes}
3301573Srgrimes
3311573Srgrimesvoid
3321573Srgrimesdelcur(db, argv)
3331573Srgrimes	DB *db;
3341573Srgrimes	char **argv;
3351573Srgrimes{
3361573Srgrimes	int status;
3371573Srgrimes
3381573Srgrimes	status = (*db->del)(db, NULL, R_CURSOR);
3391573Srgrimes
3401573Srgrimes	if (status == RET_ERROR)
3411573Srgrimes		perror("delcur/del");
3421573Srgrimes}
3431573Srgrimes
3441573Srgrimesvoid
3451573Srgrimesdelete(db, argv)
3461573Srgrimes	DB *db;
3471573Srgrimes	char **argv;
3481573Srgrimes{
3491573Srgrimes	DBT key;
3501573Srgrimes	int status;
3511573Srgrimes
3521573Srgrimes	key.data = argv[1];
3531573Srgrimes	if (recno)
3541573Srgrimes		key.size = sizeof(recno_t);
3551573Srgrimes	else
3561573Srgrimes		key.size = strlen(argv[1]) + 1;
3571573Srgrimes
3581573Srgrimes	status = (*db->del)(db, &key, 0);
3591573Srgrimes	switch (status) {
3601573Srgrimes	case RET_ERROR:
3611573Srgrimes		perror("delete/del");
3621573Srgrimes		break;
3631573Srgrimes	case RET_SPECIAL:
3641573Srgrimes		(void)printf("key not found\n");
3651573Srgrimes		break;
3661573Srgrimes	case RET_SUCCESS:
3671573Srgrimes		break;
3681573Srgrimes	}
3691573Srgrimes}
3701573Srgrimes
3711573Srgrimesvoid
3721573Srgrimesdump(db, argv)
3731573Srgrimes	DB *db;
3741573Srgrimes	char **argv;
3751573Srgrimes{
3761573Srgrimes	__bt_dump(db);
3771573Srgrimes}
3781573Srgrimes
3791573Srgrimesvoid
3801573Srgrimesfirst(db, argv)
3811573Srgrimes	DB *db;
3821573Srgrimes	char **argv;
3831573Srgrimes{
3841573Srgrimes	DBT data, key;
3851573Srgrimes	int status;
3861573Srgrimes
3871573Srgrimes	status = (*db->seq)(db, &key, &data, R_FIRST);
3881573Srgrimes
3891573Srgrimes	switch (status) {
3901573Srgrimes	case RET_ERROR:
3911573Srgrimes		perror("first/seq");
3921573Srgrimes		break;
3931573Srgrimes	case RET_SPECIAL:
3941573Srgrimes		(void)printf("no more keys\n");
3951573Srgrimes		break;
3961573Srgrimes	case RET_SUCCESS:
3971573Srgrimes		keydata(&key, &data);
3981573Srgrimes		break;
3991573Srgrimes	}
4001573Srgrimes}
4011573Srgrimes
4021573Srgrimesvoid
4031573Srgrimesget(db, argv)
4041573Srgrimes	DB *db;
4051573Srgrimes	char **argv;
4061573Srgrimes{
4071573Srgrimes	DBT data, key;
4081573Srgrimes	int status;
4091573Srgrimes
4101573Srgrimes	key.data = argv[1];
4111573Srgrimes	if (recno)
4121573Srgrimes		key.size = sizeof(recno_t);
4131573Srgrimes	else
4141573Srgrimes		key.size = strlen(argv[1]) + 1;
4151573Srgrimes
4161573Srgrimes	status = (*db->get)(db, &key, &data, 0);
4171573Srgrimes
4181573Srgrimes	switch (status) {
4191573Srgrimes	case RET_ERROR:
4201573Srgrimes		perror("get/get");
4211573Srgrimes		break;
4221573Srgrimes	case RET_SPECIAL:
4231573Srgrimes		(void)printf("key not found\n");
4241573Srgrimes		break;
4251573Srgrimes	case RET_SUCCESS:
4261573Srgrimes		keydata(&key, &data);
4271573Srgrimes		break;
4281573Srgrimes	}
4291573Srgrimes}
4301573Srgrimes
4311573Srgrimesvoid
4321573Srgrimeshelp(db, argv)
4331573Srgrimes	DB *db;
4341573Srgrimes	char **argv;
4351573Srgrimes{
4361573Srgrimes	int i;
4371573Srgrimes
4381573Srgrimes	for (i = 0; commands[i].cmd; i++)
4391573Srgrimes		if (commands[i].descrip)
4401573Srgrimes			(void)printf("%s: %s\n",
4411573Srgrimes			    commands[i].usage, commands[i].descrip);
4421573Srgrimes}
4431573Srgrimes
4441573Srgrimesvoid
4451573Srgrimesiafter(db, argv)
4461573Srgrimes	DB *db;
4471573Srgrimes	char **argv;
4481573Srgrimes{
4491573Srgrimes	DBT key, data;
4501573Srgrimes	int status;
4511573Srgrimes
4521573Srgrimes	if (!recno) {
4531573Srgrimes		(void)fprintf(stderr,
4541573Srgrimes		    "iafter only available for recno db's.\n");
4551573Srgrimes		return;
4561573Srgrimes	}
4571573Srgrimes	key.data = argv[1];
4581573Srgrimes	key.size = sizeof(recno_t);
4591573Srgrimes	data.data = argv[2];
4601573Srgrimes	data.size = strlen(data.data);
4611573Srgrimes	status = (db->put)(db, &key, &data, R_IAFTER);
4621573Srgrimes	switch (status) {
4631573Srgrimes	case RET_ERROR:
4641573Srgrimes		perror("iafter/put");
4651573Srgrimes		break;
4661573Srgrimes	case RET_SPECIAL:
4671573Srgrimes		(void)printf("%s (duplicate key)\n", argv[1]);
4681573Srgrimes		break;
4691573Srgrimes	case RET_SUCCESS:
4701573Srgrimes		break;
4711573Srgrimes	}
4721573Srgrimes}
4731573Srgrimes
4741573Srgrimesvoid
4751573Srgrimesibefore(db, argv)
4761573Srgrimes	DB *db;
4771573Srgrimes	char **argv;
4781573Srgrimes{
4791573Srgrimes	DBT key, data;
4801573Srgrimes	int status;
4811573Srgrimes
4821573Srgrimes	if (!recno) {
4831573Srgrimes		(void)fprintf(stderr,
4841573Srgrimes		    "ibefore only available for recno db's.\n");
4851573Srgrimes		return;
4861573Srgrimes	}
4871573Srgrimes	key.data = argv[1];
4881573Srgrimes	key.size = sizeof(recno_t);
4891573Srgrimes	data.data = argv[2];
4901573Srgrimes	data.size = strlen(data.data);
4911573Srgrimes	status = (db->put)(db, &key, &data, R_IBEFORE);
4921573Srgrimes	switch (status) {
4931573Srgrimes	case RET_ERROR:
4941573Srgrimes		perror("ibefore/put");
4951573Srgrimes		break;
4961573Srgrimes	case RET_SPECIAL:
4971573Srgrimes		(void)printf("%s (duplicate key)\n", argv[1]);
4981573Srgrimes		break;
4991573Srgrimes	case RET_SUCCESS:
5001573Srgrimes		break;
5011573Srgrimes	}
5021573Srgrimes}
5031573Srgrimes
5041573Srgrimesvoid
5051573Srgrimesicursor(db, argv)
5061573Srgrimes	DB *db;
5071573Srgrimes	char **argv;
5081573Srgrimes{
5091573Srgrimes	int status;
5101573Srgrimes	DBT data, key;
5111573Srgrimes
5121573Srgrimes	key.data = argv[1];
5131573Srgrimes	if (recno)
5141573Srgrimes		key.size = sizeof(recno_t);
5151573Srgrimes	else
5161573Srgrimes		key.size = strlen(argv[1]) + 1;
5171573Srgrimes	data.data = argv[2];
5181573Srgrimes	data.size = strlen(argv[2]) + 1;
5191573Srgrimes
5201573Srgrimes	status = (*db->put)(db, &key, &data, R_CURSOR);
5211573Srgrimes	switch (status) {
5221573Srgrimes	case RET_ERROR:
5231573Srgrimes		perror("icursor/put");
5241573Srgrimes		break;
5251573Srgrimes	case RET_SPECIAL:
5261573Srgrimes		(void)printf("%s (duplicate key)\n", argv[1]);
5271573Srgrimes		break;
5281573Srgrimes	case RET_SUCCESS:
5291573Srgrimes		break;
5301573Srgrimes	}
5311573Srgrimes}
5321573Srgrimes
5331573Srgrimesvoid
5341573Srgrimesinsert(db, argv)
5351573Srgrimes	DB *db;
5361573Srgrimes	char **argv;
5371573Srgrimes{
5381573Srgrimes	int status;
5391573Srgrimes	DBT data, key;
5401573Srgrimes
5411573Srgrimes	key.data = argv[1];
5421573Srgrimes	if (recno)
5431573Srgrimes		key.size = sizeof(recno_t);
5441573Srgrimes	else
5451573Srgrimes		key.size = strlen(argv[1]) + 1;
5461573Srgrimes	data.data = argv[2];
5471573Srgrimes	data.size = strlen(argv[2]) + 1;
5481573Srgrimes
5491573Srgrimes	status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
5501573Srgrimes	switch (status) {
5511573Srgrimes	case RET_ERROR:
5521573Srgrimes		perror("insert/put");
5531573Srgrimes		break;
5541573Srgrimes	case RET_SPECIAL:
5551573Srgrimes		(void)printf("%s (duplicate key)\n", argv[1]);
5561573Srgrimes		break;
5571573Srgrimes	case RET_SUCCESS:
5581573Srgrimes		break;
5591573Srgrimes	}
5601573Srgrimes}
5611573Srgrimes
5621573Srgrimesvoid
5631573Srgrimeslast(db, argv)
5641573Srgrimes	DB *db;
5651573Srgrimes	char **argv;
5661573Srgrimes{
5671573Srgrimes	DBT data, key;
5681573Srgrimes	int status;
5691573Srgrimes
5701573Srgrimes	status = (*db->seq)(db, &key, &data, R_LAST);
5711573Srgrimes
5721573Srgrimes	switch (status) {
5731573Srgrimes	case RET_ERROR:
5741573Srgrimes		perror("last/seq");
5751573Srgrimes		break;
5761573Srgrimes	case RET_SPECIAL:
5771573Srgrimes		(void)printf("no more keys\n");
5781573Srgrimes		break;
5791573Srgrimes	case RET_SUCCESS:
5801573Srgrimes		keydata(&key, &data);
5811573Srgrimes		break;
5821573Srgrimes	}
5831573Srgrimes}
5841573Srgrimes
5851573Srgrimesvoid
5861573Srgrimeslist(db, argv)
5871573Srgrimes	DB *db;
5881573Srgrimes	char **argv;
5891573Srgrimes{
5901573Srgrimes	DBT data, key;
5911573Srgrimes	FILE *fp;
5921573Srgrimes	int status;
5931573Srgrimes
5941573Srgrimes	if ((fp = fopen(argv[1], "w")) == NULL) {
5951573Srgrimes		(void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
5961573Srgrimes		return;
5971573Srgrimes	}
5981573Srgrimes	status = (*db->seq)(db, &key, &data, R_FIRST);
5991573Srgrimes	while (status == RET_SUCCESS) {
6001573Srgrimes		(void)fprintf(fp, "%s\n", key.data);
6011573Srgrimes		status = (*db->seq)(db, &key, &data, R_NEXT);
6021573Srgrimes	}
6031573Srgrimes	if (status == RET_ERROR)
6041573Srgrimes		perror("list/seq");
6051573Srgrimes}
6061573Srgrimes
6071573SrgrimesDB *BUGdb;
6081573Srgrimesvoid
6091573Srgrimesload(db, argv)
6101573Srgrimes	DB *db;
6111573Srgrimes	char **argv;
6121573Srgrimes{
61392889Sobrien	char *p, *t;
6141573Srgrimes	FILE *fp;
6151573Srgrimes	DBT data, key;
6161573Srgrimes	recno_t cnt;
6171573Srgrimes	size_t len;
6181573Srgrimes	int status;
6191573Srgrimes	char *lp, buf[16 * 1024];
6201573Srgrimes
6211573Srgrimes	BUGdb = db;
6221573Srgrimes	if ((fp = fopen(argv[1], "r")) == NULL) {
6231573Srgrimes		(void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
6241573Srgrimes		return;
6251573Srgrimes	}
6261573Srgrimes	(void)printf("loading %s...\n", argv[1]);
6271573Srgrimes
6281573Srgrimes	for (cnt = 1; (lp = fgetline(fp, &len)) != NULL; ++cnt) {
6291573Srgrimes		if (recno) {
6301573Srgrimes			key.data = &cnt;
6311573Srgrimes			key.size = sizeof(recno_t);
6321573Srgrimes			data.data = lp;
6331573Srgrimes			data.size = len + 1;
6348870Srgrimes		} else {
6351573Srgrimes			key.data = lp;
6361573Srgrimes			key.size = len + 1;
6371573Srgrimes			for (p = lp + len - 1, t = buf; p >= lp; *t++ = *p--);
6381573Srgrimes			*t = '\0';
6391573Srgrimes			data.data = buf;
6401573Srgrimes			data.size = len + 1;
6411573Srgrimes		}
6421573Srgrimes
6431573Srgrimes		status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
6441573Srgrimes		switch (status) {
6451573Srgrimes		case RET_ERROR:
6461573Srgrimes			perror("load/put");
6471573Srgrimes			exit(1);
6481573Srgrimes		case RET_SPECIAL:
6491573Srgrimes			if (recno)
6501573Srgrimes				(void)fprintf(stderr,
6511573Srgrimes				    "duplicate: %ld {%s}\n", cnt, data.data);
6521573Srgrimes			else
6531573Srgrimes				(void)fprintf(stderr,
6541573Srgrimes				    "duplicate: %ld {%s}\n", cnt, key.data);
6551573Srgrimes			exit(1);
6561573Srgrimes		case RET_SUCCESS:
6571573Srgrimes			break;
6581573Srgrimes		}
6591573Srgrimes	}
6601573Srgrimes	(void)fclose(fp);
6611573Srgrimes}
6621573Srgrimes
6631573Srgrimesvoid
6641573Srgrimesnext(db, argv)
6651573Srgrimes	DB *db;
6661573Srgrimes	char **argv;
6671573Srgrimes{
6681573Srgrimes	DBT data, key;
6691573Srgrimes	int status;
6701573Srgrimes
6711573Srgrimes	status = (*db->seq)(db, &key, &data, R_NEXT);
6721573Srgrimes
6731573Srgrimes	switch (status) {
6741573Srgrimes	case RET_ERROR:
6751573Srgrimes		perror("next/seq");
6761573Srgrimes		break;
6771573Srgrimes	case RET_SPECIAL:
6781573Srgrimes		(void)printf("no more keys\n");
6791573Srgrimes		break;
6801573Srgrimes	case RET_SUCCESS:
6811573Srgrimes		keydata(&key, &data);
6821573Srgrimes		break;
6831573Srgrimes	}
6841573Srgrimes}
6851573Srgrimes
6861573Srgrimesvoid
6871573Srgrimesprevious(db, argv)
6881573Srgrimes	DB *db;
6891573Srgrimes	char **argv;
6901573Srgrimes{
6911573Srgrimes	DBT data, key;
6921573Srgrimes	int status;
6931573Srgrimes
6941573Srgrimes	status = (*db->seq)(db, &key, &data, R_PREV);
6951573Srgrimes
6961573Srgrimes	switch (status) {
6971573Srgrimes	case RET_ERROR:
6981573Srgrimes		perror("previous/seq");
6991573Srgrimes		break;
7001573Srgrimes	case RET_SPECIAL:
7011573Srgrimes		(void)printf("no more keys\n");
7021573Srgrimes		break;
7031573Srgrimes	case RET_SUCCESS:
7041573Srgrimes		keydata(&key, &data);
7051573Srgrimes		break;
7061573Srgrimes	}
7071573Srgrimes}
7081573Srgrimes
7091573Srgrimesvoid
7101573Srgrimesshow(db, argv)
7111573Srgrimes	DB *db;
7121573Srgrimes	char **argv;
7131573Srgrimes{
7141573Srgrimes	BTREE *t;
7151573Srgrimes	PAGE *h;
7161573Srgrimes	pgno_t pg;
7171573Srgrimes
7181573Srgrimes	pg = atoi(argv[1]);
7191573Srgrimes	t = db->internal;
7201573Srgrimes	if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) {
7211573Srgrimes		(void)printf("getpage of %ld failed\n", pg);
7221573Srgrimes		return;
7231573Srgrimes	}
7241573Srgrimes	if (pg == 0)
7251573Srgrimes		__bt_dmpage(h);
7261573Srgrimes	else
7271573Srgrimes		__bt_dpage(h);
7281573Srgrimes	mpool_put(t->bt_mp, h, 0);
7291573Srgrimes}
7301573Srgrimes
7311573Srgrimesvoid
7321573Srgrimesbstat(db, argv)
7331573Srgrimes	DB *db;
7341573Srgrimes	char **argv;
7351573Srgrimes{
7361573Srgrimes	(void)printf("BTREE\n");
7371573Srgrimes	__bt_stat(db);
7381573Srgrimes}
7391573Srgrimes
7401573Srgrimesvoid
7411573Srgrimesmstat(db, argv)
7421573Srgrimes	DB *db;
7431573Srgrimes	char **argv;
7441573Srgrimes{
7451573Srgrimes	(void)printf("MPOOL\n");
7461573Srgrimes	mpool_stat(((BTREE *)db->internal)->bt_mp);
7471573Srgrimes}
7481573Srgrimes
7491573Srgrimesvoid
7501573Srgrimeskeydata(key, data)
7511573Srgrimes	DBT *key, *data;
7521573Srgrimes{
7531573Srgrimes	if (!recno && key->size > 0)
7541573Srgrimes		(void)printf("%s/", key->data);
7551573Srgrimes	if (data->size > 0)
7561573Srgrimes		(void)printf("%s", data->data);
7571573Srgrimes	(void)printf("\n");
7581573Srgrimes}
7591573Srgrimes
7601573Srgrimesvoid
7611573Srgrimesusage()
7621573Srgrimes{
7631573Srgrimes	(void)fprintf(stderr,
7641573Srgrimes	    "usage: %s [-bdlu] [-c cache] [-i file] [-p page] [file]\n",
7651573Srgrimes	    progname);
7661573Srgrimes	exit (1);
7671573Srgrimes}
768