Import BSDDB 4.7.25 (as of svn r89086)
This commit is contained in:
241
examples_c/csv/query.c
Normal file
241
examples_c/csv/query.c
Normal file
@@ -0,0 +1,241 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 2005,2008 Oracle. All rights reserved.
|
||||
*
|
||||
* $Id: query.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
|
||||
#include "csv.h"
|
||||
#include "csv_local.h"
|
||||
#include "csv_extern.h"
|
||||
|
||||
static int query_by_field(char *);
|
||||
static int query_fieldlist(char *);
|
||||
static int query_help(char *);
|
||||
static int query_usage(void);
|
||||
|
||||
typedef struct _cmdtab {
|
||||
char *cmd; /* Command name */
|
||||
int (*f)(char *); /* Underlying function. */
|
||||
char *help; /* Help message. */
|
||||
} CMDTAB;
|
||||
|
||||
static CMDTAB cmdtab[] = {
|
||||
{ "?",
|
||||
query_help,
|
||||
"?\t\tDisplay help screen" },
|
||||
{ "exit",
|
||||
NULL,
|
||||
"exit\t\tExit program" },
|
||||
{ "fields",
|
||||
query_fieldlist,
|
||||
"fields\t\tDisplay list of field names" },
|
||||
{ "help",
|
||||
query_help,
|
||||
"help\t\tDisplay help screen" },
|
||||
{ "quit",
|
||||
NULL,
|
||||
"quit\t\tExit program" },
|
||||
{ NULL,
|
||||
query_by_field,
|
||||
"field[op]value\tDisplay fields by value (=, !=, <, <=, >, >=, ~, !~)" },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* query_interactive --
|
||||
* Allow the user to interactively query the database.
|
||||
*/
|
||||
int
|
||||
query_interactive()
|
||||
{
|
||||
int done;
|
||||
char *p, input[256];
|
||||
|
||||
for (;;) {
|
||||
printf("Query: ");
|
||||
(void)fflush(stdout);
|
||||
if (fgets(input, sizeof(input), stdin) == NULL) {
|
||||
printf("\n");
|
||||
if (ferror(stdin)) {
|
||||
dbenv->err(dbenv, errno,
|
||||
"error occurred reading from stdin");
|
||||
return (1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ((p = strchr(input, '\n')) == NULL) {
|
||||
dbenv->errx(dbenv, "input buffer too small");
|
||||
return (1);
|
||||
}
|
||||
*p = '\0';
|
||||
if (query(input, &done) != 0)
|
||||
return (1);
|
||||
if (done != 0)
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* query --
|
||||
* Process a query.
|
||||
*/
|
||||
int
|
||||
query(char *cmd, int *donep)
|
||||
{
|
||||
CMDTAB *p;
|
||||
|
||||
if (donep != NULL)
|
||||
*donep = 0;
|
||||
|
||||
for (p = cmdtab; p->cmd != NULL; ++p)
|
||||
if (p->cmd != NULL &&
|
||||
strncasecmp(cmd, p->cmd, strlen(p->cmd)) == 0)
|
||||
break;
|
||||
|
||||
if (p->cmd == NULL)
|
||||
return (query_by_field(cmd));
|
||||
|
||||
if (p->f == NULL) {
|
||||
if (donep != NULL)
|
||||
*donep = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (p->f(cmd));
|
||||
}
|
||||
|
||||
/*
|
||||
* query_by_field --
|
||||
* Query the primary database by field.
|
||||
*/
|
||||
static int
|
||||
query_by_field(char *input)
|
||||
{
|
||||
OPERATOR operator;
|
||||
size_t len;
|
||||
char *field, *op, *value;
|
||||
|
||||
/*
|
||||
* We expect to see "field [op] value" -- figure it out.
|
||||
*
|
||||
* Skip leading whitespace.
|
||||
*/
|
||||
while (isspace(*input))
|
||||
++input;
|
||||
|
||||
/*
|
||||
* Find an operator, and it better not start the string.
|
||||
*/
|
||||
if ((len = strcspn(field = input, "<>!=~")) == 0)
|
||||
return (query_usage());
|
||||
op = field + len;
|
||||
|
||||
/* Figure out the operator, and find the start of the value. */
|
||||
switch (op[0]) {
|
||||
case '~':
|
||||
operator = WC;
|
||||
value = op + 1;
|
||||
break;
|
||||
case '!':
|
||||
if (op[1] == '=') {
|
||||
operator = NEQ;
|
||||
value = op + 2;
|
||||
break;
|
||||
}
|
||||
if (op[1] == '~') {
|
||||
operator = NWC;
|
||||
value = op + 2;
|
||||
break;
|
||||
}
|
||||
return (query_usage());
|
||||
case '<':
|
||||
if (op[1] == '=') {
|
||||
operator = LTEQ;
|
||||
value = op + 2;
|
||||
} else {
|
||||
operator = LT;
|
||||
value = op + 1;
|
||||
}
|
||||
break;
|
||||
case '=':
|
||||
operator = EQ;
|
||||
if (op[1] == '=')
|
||||
value = op + 2;
|
||||
else
|
||||
value = op + 1;
|
||||
break;
|
||||
case '>':
|
||||
if (op[1] == '=') {
|
||||
operator = GTEQ;
|
||||
value = op + 2;
|
||||
} else {
|
||||
operator = GT;
|
||||
value = op + 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (query_usage());
|
||||
}
|
||||
|
||||
/* Terminate the field name, and there better be a field name. */
|
||||
while (--op > input && isspace(*op))
|
||||
;
|
||||
if (op == input)
|
||||
return (query_usage());
|
||||
op[1] = '\0';
|
||||
|
||||
/* Make sure there is a value field. */
|
||||
while (isspace(*value))
|
||||
++value;
|
||||
if (*value == '\0')
|
||||
return (query_usage());
|
||||
|
||||
return (DbRecord_search_field_name(field, value, operator));
|
||||
}
|
||||
|
||||
/*
|
||||
* query_fieldlist --
|
||||
* Display list of field names.
|
||||
*/
|
||||
static int
|
||||
query_fieldlist(char *input)
|
||||
{
|
||||
DbField *f;
|
||||
|
||||
input = input; /* Quiet compiler. */
|
||||
|
||||
for (f = fieldlist; f->name != NULL; ++f)
|
||||
printf("field %3d: %s\n", f->fieldno, f->name);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* query_help --
|
||||
* Query command list.
|
||||
*/
|
||||
static int
|
||||
query_help(char *input)
|
||||
{
|
||||
CMDTAB *p;
|
||||
|
||||
input = input; /* Quiet compiler. */
|
||||
|
||||
printf("Query commands:\n");
|
||||
for (p = cmdtab; p->help != NULL; ++p)
|
||||
printf("\t%s\n", p->help);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* query_usage --
|
||||
* Query usage message.
|
||||
*/
|
||||
static int
|
||||
query_usage(void)
|
||||
{
|
||||
fprintf(stderr, "%s: query syntax error\n", progname);
|
||||
return (query_help(NULL));
|
||||
}
|
||||
Reference in New Issue
Block a user