xref: /csrg-svn/lib/libc/db/test/btree.tests/main.c (revision 47886)
1*47886Sbostic /*-
2*47886Sbostic  * Copyright (c) 1990 The Regents of the University of California.
3*47886Sbostic  * All rights reserved.
4*47886Sbostic  *
5*47886Sbostic  * This code is derived from software contributed to Berkeley by
6*47886Sbostic  * Mike Olson.
7*47886Sbostic  *
8*47886Sbostic  * %sccs.include.redist.c%
9*47886Sbostic  */
10*47886Sbostic 
11*47886Sbostic #if defined(LIBC_SCCS) && !defined(lint)
12*47886Sbostic static char sccsid[] = "@(#)main.c	5.1 (Berkeley) 04/12/91";
13*47886Sbostic #endif /* LIBC_SCCS and not lint */
14*47886Sbostic 
15*47886Sbostic /*
16*47886Sbostic  *  test1.c -- simple btree test program.
17*47886Sbostic  */
18*47886Sbostic 
19*47886Sbostic #include <stdio.h>
20*47886Sbostic #include <ctype.h>
21*47886Sbostic #include <sys/param.h>
22*47886Sbostic #include <sys/types.h>
23*47886Sbostic #include <sys/file.h>
24*47886Sbostic #include <db.h>
25*47886Sbostic #include <btree.h>
26*47886Sbostic 
27*47886Sbostic #define	DICTIONARY	"/usr/share/dict/words"
28*47886Sbostic 
29*47886Sbostic typedef struct cmd_table {
30*47886Sbostic 	char *cmd;
31*47886Sbostic 	int nargs;
32*47886Sbostic 	int (*func)();
33*47886Sbostic 	char *descrip;
34*47886Sbostic } cmd_table;
35*47886Sbostic 
36*47886Sbostic extern int cursor(), delcur(), delete(), first(), help(), insert();
37*47886Sbostic extern int last(), lookup(), next(), previous();
38*47886Sbostic 
39*47886Sbostic cmd_table Commands[] = {
40*47886Sbostic 	"cursor", 2, cursor,
41*47886Sbostic 		"cursor <word>:  point the scan cursor at <word>",
42*47886Sbostic 	"delcur", 1, delcur,
43*47886Sbostic 		"delcur:  delete the word under the scan cursor",
44*47886Sbostic 	"delete", 2, delete,
45*47886Sbostic 		"delete <word>:  delete <word> from the dictionary",
46*47886Sbostic 	"first", 1, first,
47*47886Sbostic 		"first: point the scan cursor at the first dictionary entry",
48*47886Sbostic 	"help", 1, help,
49*47886Sbostic 		"help:  print this command summary",
50*47886Sbostic 	"insert", 3, insert,
51*47886Sbostic 		"insert <word> <def>:  insert <word> into the dictionary with definition <def>",
52*47886Sbostic 	"last", 1, last,
53*47886Sbostic 		"last:  point the scan cursor at the last dictionary entry",
54*47886Sbostic 	"lookup", 2, lookup,
55*47886Sbostic 		"lookup <word>:  look up <word> in the dictionary",
56*47886Sbostic 	"next", 1, next,
57*47886Sbostic 		"next:  move the scan cursor forward one word",
58*47886Sbostic 	"previous", 1, previous,
59*47886Sbostic 		"previous:  move the scan cursor back one word",
60*47886Sbostic 	(char *) NULL, 0, NULL, (char *) NULL,
61*47886Sbostic };
62*47886Sbostic 
63*47886Sbostic char *Usage = "[-p pagesize] [-c cachesize] [-u] [-l|b|n] [dbname]";
64*47886Sbostic 
65*47886Sbostic main(argc, argv)
66*47886Sbostic 	int argc;
67*47886Sbostic 	char **argv;
68*47886Sbostic {
69*47886Sbostic 	char *dbname;
70*47886Sbostic 	int c;
71*47886Sbostic 	char *progname;
72*47886Sbostic 	extern int strcmp();
73*47886Sbostic 	extern char *optarg;
74*47886Sbostic 	extern int optind;
75*47886Sbostic 	DB *t;
76*47886Sbostic 	BTREEINFO b;
77*47886Sbostic 
78*47886Sbostic 	progname = *argv;
79*47886Sbostic 
80*47886Sbostic 	b.psize = 0;
81*47886Sbostic 	b.cachesize = 0;
82*47886Sbostic 	b.lorder = 0;
83*47886Sbostic 	b.flags = R_DUP;
84*47886Sbostic 	b.compare = strcmp;
85*47886Sbostic 
86*47886Sbostic 	while ((c = getopt(argc, argv, "p:c:ulb")) != EOF) {
87*47886Sbostic 		switch (c) {
88*47886Sbostic 		  case 'p':
89*47886Sbostic 			b.psize = atoi(optarg);
90*47886Sbostic 			break;
91*47886Sbostic 
92*47886Sbostic 		  case 'c':
93*47886Sbostic 			b.cachesize = atoi(optarg);
94*47886Sbostic 			break;
95*47886Sbostic 
96*47886Sbostic 		  case 'u':
97*47886Sbostic 			b.flags = 0;
98*47886Sbostic 			break;
99*47886Sbostic 
100*47886Sbostic 		  case 'l':
101*47886Sbostic 			b.lorder = LITTLE_ENDIAN;
102*47886Sbostic 			break;
103*47886Sbostic 
104*47886Sbostic 		  case 'b':
105*47886Sbostic 			b.lorder = BIG_ENDIAN;
106*47886Sbostic 			break;
107*47886Sbostic 
108*47886Sbostic 		  default:
109*47886Sbostic 			fprintf(stderr, "%s: usage: %s\n", progname, Usage);
110*47886Sbostic 			exit (1);
111*47886Sbostic 		}
112*47886Sbostic 	}
113*47886Sbostic 
114*47886Sbostic 	if (argv[optind] != (char *) NULL)
115*47886Sbostic 		dbname = argv[optind];
116*47886Sbostic 
117*47886Sbostic 	if ((t = btree_open(dbname, O_CREAT|O_RDWR, 0600, &b)) == (DB *) NULL) {
118*47886Sbostic 		perror(progname);
119*47886Sbostic 		exit (1);
120*47886Sbostic 	}
121*47886Sbostic 
122*47886Sbostic 	load(t);
123*47886Sbostic 
124*47886Sbostic 	user(t);
125*47886Sbostic }
126*47886Sbostic 
127*47886Sbostic load(t)
128*47886Sbostic 	DB *t;
129*47886Sbostic {
130*47886Sbostic 	char *lbuf;
131*47886Sbostic 	int i, l;
132*47886Sbostic 	int status;
133*47886Sbostic 	FILE *fp;
134*47886Sbostic 	DBT key;
135*47886Sbostic 	DBT data;
136*47886Sbostic 	char word[64];
137*47886Sbostic 	char drow[64];
138*47886Sbostic 
139*47886Sbostic 	printf("loading %s...\n", DICTIONARY);
140*47886Sbostic 	fflush(stdout);
141*47886Sbostic 	if ((fp = fopen(DICTIONARY, "r")) == (FILE *) NULL) {
142*47886Sbostic 		perror("/usr/dict/words");
143*47886Sbostic 		(void) (*(t->close))(t->internal);
144*47886Sbostic 		exit (1);
145*47886Sbostic 	}
146*47886Sbostic 
147*47886Sbostic 	key.data = &word[0];
148*47886Sbostic 	data.data = &drow[0];
149*47886Sbostic 	while ((lbuf = fgets(word, 64, fp)) != (char *) NULL) {
150*47886Sbostic 		l = strlen(lbuf) - 1;
151*47886Sbostic 		lbuf[l] = '\0';
152*47886Sbostic 		for (i = 0; i < l; i++)
153*47886Sbostic 			drow[l - (i + 1)] = word[i];
154*47886Sbostic 		drow[l] = '\0';
155*47886Sbostic 
156*47886Sbostic 		key.size = data.size = l + 1;
157*47886Sbostic 
158*47886Sbostic 		status = (*(t->put))(t->internal, &key, &data, R_NOOVERWRITE);
159*47886Sbostic 
160*47886Sbostic 		switch (status) {
161*47886Sbostic 		  case RET_SUCCESS:
162*47886Sbostic 			break;
163*47886Sbostic 
164*47886Sbostic 		  case RET_ERROR:
165*47886Sbostic 			perror("put");
166*47886Sbostic 			break;
167*47886Sbostic 
168*47886Sbostic 		  case RET_SPECIAL:
169*47886Sbostic 			fprintf(stderr, "%s is a duplicate key!\n", lbuf);
170*47886Sbostic 			fflush(stderr);
171*47886Sbostic 			break;
172*47886Sbostic 		}
173*47886Sbostic 	}
174*47886Sbostic 
175*47886Sbostic 	(void) fclose(fp);
176*47886Sbostic 	printf("done\n");
177*47886Sbostic 	fflush(stdout);
178*47886Sbostic }
179*47886Sbostic 
180*47886Sbostic user(t)
181*47886Sbostic 	DB *t;
182*47886Sbostic {
183*47886Sbostic 	char *lbuf;
184*47886Sbostic 	int argc;
185*47886Sbostic 	int i;
186*47886Sbostic 	char *argv[4];
187*47886Sbostic 	char buf[512];
188*47886Sbostic 
189*47886Sbostic 	for (;;) {
190*47886Sbostic 		printf("> ");
191*47886Sbostic 		fflush(stdout);
192*47886Sbostic 		if ((lbuf = fgets(&buf[0], 512, stdin)) == (char *) NULL)
193*47886Sbostic 			break;
194*47886Sbostic 		lbuf[strlen(lbuf) - 1] = '\0';
195*47886Sbostic 
196*47886Sbostic 		if (strcmp(lbuf, "quit") == 0)
197*47886Sbostic 			break;
198*47886Sbostic 
199*47886Sbostic 		argc = parse(lbuf, &argv[0], 3);
200*47886Sbostic 		if (argc == 0)
201*47886Sbostic 			continue;
202*47886Sbostic 
203*47886Sbostic 		for (i = 0; Commands[i].cmd != (char *) NULL; i++) {
204*47886Sbostic 			if (strcmp(Commands[i].cmd, argv[0]) == 0)
205*47886Sbostic 				break;
206*47886Sbostic 		}
207*47886Sbostic 
208*47886Sbostic 		if (Commands[i].cmd == (char *) NULL) {
209*47886Sbostic 			fprintf(stderr,
210*47886Sbostic 				"%s: command unknown ('help' for help)\n",
211*47886Sbostic 				lbuf);
212*47886Sbostic 			fflush(stderr);
213*47886Sbostic 			continue;
214*47886Sbostic 		}
215*47886Sbostic 
216*47886Sbostic 		if (Commands[i].nargs != argc) {
217*47886Sbostic 			fprintf(stderr, "arg count\n");
218*47886Sbostic 			fflush(stderr);
219*47886Sbostic 			continue;
220*47886Sbostic 		}
221*47886Sbostic 
222*47886Sbostic 		switch (argc) {
223*47886Sbostic 		  case 1:
224*47886Sbostic 			(*(Commands[i].func))(t);
225*47886Sbostic 			break;
226*47886Sbostic 		  case 2:
227*47886Sbostic 			(*(Commands[i].func))(t, argv[1]);
228*47886Sbostic 			break;
229*47886Sbostic 		  case 3:
230*47886Sbostic 			(*(Commands[i].func))(t, argv[1], argv[2]);
231*47886Sbostic 			break;
232*47886Sbostic 		  case 4:
233*47886Sbostic 			(*(Commands[i].func))(t, argv[1], argv[2], argv[3]);
234*47886Sbostic 			break;
235*47886Sbostic 		}
236*47886Sbostic 	}
237*47886Sbostic 	(void) (*(t->close))(t->internal);
238*47886Sbostic 	exit (0);
239*47886Sbostic }
240*47886Sbostic 
241*47886Sbostic int
242*47886Sbostic parse(lbuf, argv, maxargc)
243*47886Sbostic 	char *lbuf;
244*47886Sbostic 	char **argv;
245*47886Sbostic 	int maxargc;
246*47886Sbostic {
247*47886Sbostic 	int argc = 0;
248*47886Sbostic 	char *c;
249*47886Sbostic 
250*47886Sbostic 	c = lbuf;
251*47886Sbostic 	while (isspace(*c))
252*47886Sbostic 		c++;
253*47886Sbostic 	while (*c != '\0' && argc < maxargc) {
254*47886Sbostic 		*argv++ = c;
255*47886Sbostic 		argc++;
256*47886Sbostic 		while (!isspace(*c) && *c != '\0') {
257*47886Sbostic 			c++;
258*47886Sbostic 		}
259*47886Sbostic 		while (isspace(*c))
260*47886Sbostic 			*c++ = '\0';
261*47886Sbostic 	}
262*47886Sbostic 	return (argc);
263*47886Sbostic }
264*47886Sbostic 
265*47886Sbostic int
266*47886Sbostic cursor(t, arg)
267*47886Sbostic 	DB *t;
268*47886Sbostic 	char *arg;
269*47886Sbostic {
270*47886Sbostic 	int status;
271*47886Sbostic 	DBT key;
272*47886Sbostic 	DBT data;
273*47886Sbostic 
274*47886Sbostic 	key.data = arg;
275*47886Sbostic 	key.size = strlen(arg + 1);
276*47886Sbostic 	status = (*(t->seq))(t->internal, &key, &data, R_CURSOR);
277*47886Sbostic 	if (status == RET_SUCCESS)
278*47886Sbostic 		show(&key, &data);
279*47886Sbostic 	else
280*47886Sbostic 		perror("cursor");
281*47886Sbostic }
282*47886Sbostic 
283*47886Sbostic int
284*47886Sbostic delcur(t)
285*47886Sbostic 	DB *t;
286*47886Sbostic {
287*47886Sbostic 	int status;
288*47886Sbostic 
289*47886Sbostic 	status = (*(t->delete))(t->internal, (DBT *) NULL, R_CURSOR);
290*47886Sbostic 
291*47886Sbostic 	if (status == RET_ERROR)
292*47886Sbostic 		perror("delcur");
293*47886Sbostic }
294*47886Sbostic 
295*47886Sbostic int
296*47886Sbostic delete(t, arg)
297*47886Sbostic 	DB *t;
298*47886Sbostic 	char *arg;
299*47886Sbostic {
300*47886Sbostic 	int status;
301*47886Sbostic 	DBT key;
302*47886Sbostic 
303*47886Sbostic 	key.data = arg;
304*47886Sbostic 	key.size = strlen(arg) + 1;
305*47886Sbostic 
306*47886Sbostic 	status = (*(t->delete))(t->internal, &key, 0);
307*47886Sbostic 	switch (status) {
308*47886Sbostic 	  case RET_SUCCESS:
309*47886Sbostic 		break;
310*47886Sbostic 
311*47886Sbostic 	  case RET_ERROR:
312*47886Sbostic 		perror("delete");
313*47886Sbostic 		break;
314*47886Sbostic 
315*47886Sbostic 	  case RET_SPECIAL:
316*47886Sbostic 		fprintf(stderr, "%s not found\n", arg);
317*47886Sbostic 		fflush(stderr);
318*47886Sbostic 		break;
319*47886Sbostic 	}
320*47886Sbostic }
321*47886Sbostic 
322*47886Sbostic int
323*47886Sbostic first(t)
324*47886Sbostic 	DB *t;
325*47886Sbostic {
326*47886Sbostic 	int status;
327*47886Sbostic 	DBT key;
328*47886Sbostic 	DBT data;
329*47886Sbostic 
330*47886Sbostic 	status = (*(t->seq))(t->internal, &key, &data, R_FIRST);
331*47886Sbostic 
332*47886Sbostic 	switch (status) {
333*47886Sbostic 	  case RET_ERROR:
334*47886Sbostic 		perror("first");
335*47886Sbostic 		break;
336*47886Sbostic 
337*47886Sbostic 	  case RET_SPECIAL:
338*47886Sbostic 		printf("no more keys");
339*47886Sbostic 		break;
340*47886Sbostic 
341*47886Sbostic 	  case RET_SUCCESS:
342*47886Sbostic 		show(&key, &data);
343*47886Sbostic 		break;
344*47886Sbostic 	}
345*47886Sbostic }
346*47886Sbostic int
347*47886Sbostic help(t)
348*47886Sbostic 	DB *t;
349*47886Sbostic {
350*47886Sbostic 	int i;
351*47886Sbostic 
352*47886Sbostic #ifdef lint
353*47886Sbostic 	t = t;
354*47886Sbostic #endif /* lint */
355*47886Sbostic 	for (i = 0; Commands[i].cmd != (char *) NULL; i++)
356*47886Sbostic 		printf("%s\n", Commands[i].descrip);
357*47886Sbostic 	printf("type 'quit' to quit\n");
358*47886Sbostic }
359*47886Sbostic 
360*47886Sbostic int
361*47886Sbostic insert(t, arg, def)
362*47886Sbostic 	DB *t;
363*47886Sbostic 	char *arg;
364*47886Sbostic 	char *def;
365*47886Sbostic {
366*47886Sbostic 	int status;
367*47886Sbostic 	DBT key;
368*47886Sbostic 	DBT data;
369*47886Sbostic 
370*47886Sbostic 	key.data = arg;
371*47886Sbostic 	key.size = strlen(arg) + 1;
372*47886Sbostic 	data.data = def;
373*47886Sbostic 	data.size = strlen(def) + 1;
374*47886Sbostic 
375*47886Sbostic 	status = (*(t->put))(t->internal, &key, &data, R_NOOVERWRITE);
376*47886Sbostic 	switch (status) {
377*47886Sbostic 	  case RET_SUCCESS:
378*47886Sbostic 		break;
379*47886Sbostic 
380*47886Sbostic 	  case RET_ERROR:
381*47886Sbostic 		perror("put");
382*47886Sbostic 		break;
383*47886Sbostic 
384*47886Sbostic 	  case RET_SPECIAL:
385*47886Sbostic 		fprintf(stderr, "%s is a duplicate key!\n", arg);
386*47886Sbostic 		fflush(stderr);
387*47886Sbostic 		break;
388*47886Sbostic 	}
389*47886Sbostic }
390*47886Sbostic 
391*47886Sbostic int
392*47886Sbostic last(t)
393*47886Sbostic 	DB *t;
394*47886Sbostic {
395*47886Sbostic 	int status;
396*47886Sbostic 	DBT key;
397*47886Sbostic 	DBT data;
398*47886Sbostic 
399*47886Sbostic 	status = (*(t->seq))(t->internal, &key, &data, R_LAST);
400*47886Sbostic 
401*47886Sbostic 	switch (status) {
402*47886Sbostic 	  case RET_ERROR:
403*47886Sbostic 		perror("last");
404*47886Sbostic 		break;
405*47886Sbostic 
406*47886Sbostic 	  case RET_SPECIAL:
407*47886Sbostic 		printf("no more keys");
408*47886Sbostic 		break;
409*47886Sbostic 
410*47886Sbostic 	  case RET_SUCCESS:
411*47886Sbostic 		show(&key, &data);
412*47886Sbostic 		break;
413*47886Sbostic 	}
414*47886Sbostic }
415*47886Sbostic 
416*47886Sbostic int
417*47886Sbostic lookup(t, arg)
418*47886Sbostic 	DB *t;
419*47886Sbostic 	char *arg;
420*47886Sbostic {
421*47886Sbostic 	int status;
422*47886Sbostic 	DBT key;
423*47886Sbostic 	DBT data;
424*47886Sbostic 
425*47886Sbostic 	key.data = arg;
426*47886Sbostic 	key.size = strlen(arg) + 1;
427*47886Sbostic 
428*47886Sbostic 	status = (*(t->get))(t->internal, &key, &data, 0);
429*47886Sbostic 
430*47886Sbostic 	switch (status) {
431*47886Sbostic 	  case RET_SPECIAL:
432*47886Sbostic 		printf("not found\n");
433*47886Sbostic 		break;
434*47886Sbostic 	  case RET_SUCCESS:
435*47886Sbostic 		show(&key, &data);
436*47886Sbostic 		break;
437*47886Sbostic 	  case RET_ERROR:
438*47886Sbostic 		perror("get");
439*47886Sbostic 		break;
440*47886Sbostic 	}
441*47886Sbostic }
442*47886Sbostic 
443*47886Sbostic int
444*47886Sbostic next(t)
445*47886Sbostic 	DB *t;
446*47886Sbostic {
447*47886Sbostic 	int status;
448*47886Sbostic 	DBT key;
449*47886Sbostic 	DBT data;
450*47886Sbostic 
451*47886Sbostic 	status = (*(t->seq))(t->internal, &key, &data, R_NEXT);
452*47886Sbostic 
453*47886Sbostic 	switch (status) {
454*47886Sbostic 	  case RET_ERROR:
455*47886Sbostic 		perror("next");
456*47886Sbostic 		break;
457*47886Sbostic 
458*47886Sbostic 	  case RET_SPECIAL:
459*47886Sbostic 		printf("no more keys");
460*47886Sbostic 		break;
461*47886Sbostic 
462*47886Sbostic 	  case RET_SUCCESS:
463*47886Sbostic 		show(&key, &data);
464*47886Sbostic 		break;
465*47886Sbostic 	}
466*47886Sbostic }
467*47886Sbostic 
468*47886Sbostic int
469*47886Sbostic previous(t)
470*47886Sbostic 	DB *t;
471*47886Sbostic {
472*47886Sbostic 	int status;
473*47886Sbostic 	DBT key;
474*47886Sbostic 	DBT data;
475*47886Sbostic 
476*47886Sbostic 	status = (*(t->seq))(t->internal, &key, &data, R_PREV);
477*47886Sbostic 
478*47886Sbostic 	switch (status) {
479*47886Sbostic 	  case RET_ERROR:
480*47886Sbostic 		perror("previous");
481*47886Sbostic 		break;
482*47886Sbostic 
483*47886Sbostic 	  case RET_SPECIAL:
484*47886Sbostic 		printf("no more keys");
485*47886Sbostic 		break;
486*47886Sbostic 
487*47886Sbostic 	  case RET_SUCCESS:
488*47886Sbostic 		show(&key, &data);
489*47886Sbostic 		break;
490*47886Sbostic 	}
491*47886Sbostic }
492*47886Sbostic 
493*47886Sbostic show(key, data)
494*47886Sbostic 	DBT *key;
495*47886Sbostic 	DBT *data;
496*47886Sbostic {
497*47886Sbostic 	if (key->size > 0)
498*47886Sbostic 		printf("%s", key->data);
499*47886Sbostic 	if (data->size > 0)
500*47886Sbostic 		printf("/%s", data->data);
501*47886Sbostic 	printf("\n");
502*47886Sbostic }
503