• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/db-4.7.25.NC/examples_c/csv/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2005,2008 Oracle.  All rights reserved.
5 *
6 * $Id: query.c,v 1.17 2008/01/08 20:58:23 bostic Exp $
7 */
8
9#include "csv.h"
10#include "csv_local.h"
11#include "csv_extern.h"
12
13static int query_by_field(char *);
14static int query_fieldlist(char *);
15static int query_help(char *);
16static int query_usage(void);
17
18typedef struct _cmdtab {
19	char	*cmd;			/* Command name */
20	int	(*f)(char *);		/* Underlying function. */
21	char	*help;			/* Help message. */
22} CMDTAB;
23
24static CMDTAB cmdtab[] = {
25	{ "?",
26		query_help,
27		"?\t\tDisplay help screen" },
28	{ "exit",
29		NULL,
30		"exit\t\tExit program" },
31	{ "fields",
32		query_fieldlist,
33		"fields\t\tDisplay list of field names" },
34	{ "help",
35		query_help,
36		"help\t\tDisplay help screen" },
37	{ "quit",
38		NULL,
39		"quit\t\tExit program" },
40	{ NULL,
41		query_by_field,
42    "field[op]value\tDisplay fields by value (=, !=, <, <=, >, >=, ~, !~)" },
43	{ NULL,		NULL,		NULL }
44};
45
46/*
47 * query_interactive --
48 *	Allow the user to interactively query the database.
49 */
50int
51query_interactive()
52{
53	int done;
54	char *p, input[256];
55
56	for (;;) {
57		printf("Query: ");
58		(void)fflush(stdout);
59		if (fgets(input, sizeof(input), stdin) == NULL) {
60			printf("\n");
61			if (ferror(stdin)) {
62				dbenv->err(dbenv, errno,
63				    "error occurred reading from stdin");
64				return (1);
65			}
66			break;
67		}
68		if ((p = strchr(input, '\n')) == NULL) {
69			dbenv->errx(dbenv, "input buffer too small");
70			return (1);
71		}
72		*p = '\0';
73		if (query(input, &done) != 0)
74			return (1);
75		if (done != 0)
76			break;
77	}
78	return (0);
79}
80
81/*
82 * query --
83 *	Process a query.
84 */
85int
86query(char *cmd, int *donep)
87{
88	CMDTAB *p;
89
90	if (donep != NULL)
91		*donep = 0;
92
93	for (p = cmdtab; p->cmd != NULL; ++p)
94		if (p->cmd != NULL &&
95		    strncasecmp(cmd, p->cmd, strlen(p->cmd)) == 0)
96			break;
97
98	if (p->cmd == NULL)
99		return (query_by_field(cmd));
100
101	if (p->f == NULL) {
102		if (donep != NULL)
103			*donep = 1;
104		return (0);
105	}
106
107	return (p->f(cmd));
108}
109
110/*
111 * query_by_field --
112 *	Query the primary database by field.
113 */
114static int
115query_by_field(char *input)
116{
117	OPERATOR operator;
118	size_t len;
119	char *field, *op, *value;
120
121	/*
122	 * We expect to see "field [op] value" -- figure it out.
123	 *
124	 * Skip leading whitespace.
125	 */
126	while (isspace(*input))
127		++input;
128
129	/*
130	 * Find an operator, and it better not start the string.
131	 */
132	if ((len = strcspn(field = input, "<>!=~")) == 0)
133		return (query_usage());
134	op = field + len;
135
136	/* Figure out the operator, and find the start of the value. */
137	switch (op[0]) {
138	case '~':
139		operator = WC;
140		value = op + 1;
141		break;
142	case '!':
143		if (op[1] == '=') {
144			operator = NEQ;
145			value = op + 2;
146			break;
147		}
148		if (op[1] == '~') {
149			operator = NWC;
150			value = op + 2;
151			break;
152		}
153		return (query_usage());
154	case '<':
155		if (op[1] == '=') {
156			operator = LTEQ;
157			value = op + 2;
158		} else {
159			operator = LT;
160			value = op + 1;
161		}
162		break;
163	case '=':
164		operator = EQ;
165		if (op[1] == '=')
166			value = op + 2;
167		else
168			value = op + 1;
169		break;
170	case '>':
171		if (op[1] == '=') {
172			operator = GTEQ;
173			value = op + 2;
174		} else {
175			operator = GT;
176			value = op + 1;
177		}
178		break;
179	default:
180		return (query_usage());
181	}
182
183	/* Terminate the field name, and there better be a field name. */
184	while (--op > input && isspace(*op))
185		;
186	if (op == input)
187		return (query_usage());
188	op[1] = '\0';
189
190	/* Make sure there is a value field. */
191	while (isspace(*value))
192		++value;
193	if (*value == '\0')
194		return (query_usage());
195
196	return (DbRecord_search_field_name(field, value, operator));
197}
198
199/*
200 * query_fieldlist --
201 *	Display list of field names.
202 */
203static int
204query_fieldlist(char *input)
205{
206	DbField *f;
207
208	input = input;				/* Quiet compiler. */
209
210	for (f = fieldlist; f->name != NULL; ++f)
211		printf("field %3d: %s\n", f->fieldno, f->name);
212	return (0);
213}
214
215/*
216 * query_help --
217 *	Query command list.
218 */
219static int
220query_help(char *input)
221{
222	CMDTAB *p;
223
224	input = input;				/* Quiet compiler. */
225
226	printf("Query commands:\n");
227	for (p = cmdtab; p->help != NULL; ++p)
228		printf("\t%s\n", p->help);
229	return (0);
230}
231
232/*
233 * query_usage --
234 *	Query usage message.
235 */
236static int
237query_usage(void)
238{
239	fprintf(stderr, "%s: query syntax error\n", progname);
240	return (query_help(NULL));
241}
242