Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

query.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: query.c,v 1.12 2005/10/14 12:53:07 bostic Exp $
00008  */
00009 
00010 #include "csv.h"
00011 #include "csv_local.h"
00012 #include "csv_extern.h"
00013 
00014 static int query_by_field(char *);
00015 static int query_fieldlist(char *);
00016 static int query_help(char *);
00017 static int query_usage(void);
00018 
00019 typedef struct _cmdtab {
00020         char    *cmd;                   /* Command name */
00021         int     (*f)(char *);           /* Underlying function. */
00022         char    *help;                  /* Help message. */
00023 } CMDTAB;
00024 
00025 static CMDTAB cmdtab[] = {
00026         { "?",
00027                 query_help,
00028                 "?\t\tDisplay help screen" },
00029         { "exit",
00030                 NULL,
00031                 "exit\t\tExit program" },
00032         { "fields",
00033                 query_fieldlist,
00034                 "fields\t\tDisplay list of field names" },
00035         { "help",
00036                 query_help,
00037                 "help\t\tDisplay help screen" },
00038         { "quit",
00039                 NULL,
00040                 "quit\t\tExit program" },
00041         { NULL,
00042                 query_by_field,
00043     "field[op]value\tDisplay fields by value (=, !=, <, <=, >, >=, ~, !~)" },
00044         { NULL,         NULL,           NULL }
00045 };
00046 
00047 /*
00048  * query_interactive --
00049  *      Allow the user to interactively query the database.
00050  */
00051 int
00052 query_interactive()
00053 {
00054         int done;
00055         char *p, input[256];
00056 
00057         for (;;) {
00058                 printf("Query: ");
00059                 (void)fflush(stdout);
00060                 if (fgets(input, sizeof(input), stdin) == NULL) {
00061                         printf("\n");
00062                         if (ferror(stdin)) {
00063                                 dbenv->err(dbenv, errno,
00064                                     "error occurred reading from stdin");
00065                                 return (1);
00066                         }
00067                         break;
00068                 }
00069                 if ((p = strchr(input, '\n')) == NULL) {
00070                         dbenv->errx(dbenv, "input buffer too small");
00071                         return (1);
00072                 }
00073                 *p = '\0';
00074                 if (query(input, &done) != 0)
00075                         return (1);
00076                 if (done != 0)
00077                         break;
00078         }
00079         return (0);
00080 }
00081 
00082 /*
00083  * query --
00084  *      Process a query.
00085  */
00086 int
00087 query(char *cmd, int *donep)
00088 {
00089         CMDTAB *p;
00090 
00091         if (donep != NULL)
00092                 *donep = 0;
00093 
00094         for (p = cmdtab; p->cmd != NULL; ++p)
00095                 if (p->cmd != NULL &&
00096                     strncasecmp(cmd, p->cmd, strlen(p->cmd)) == 0)
00097                         break;
00098 
00099         if (p->cmd == NULL)
00100                 return (query_by_field(cmd));
00101 
00102         if (p->f == NULL) {
00103                 if (donep != NULL)
00104                         *donep = 1;
00105                 return (0);
00106         }
00107 
00108         return (p->f(cmd));
00109 }
00110 
00111 /*
00112  * query_by_field --
00113  *      Query the primary database by field.
00114  */
00115 static int
00116 query_by_field(char *input)
00117 {
00118         OPERATOR operator;
00119         size_t len;
00120         char *field, *op, *value;
00121 
00122         /*
00123          * We expect to see "field [op] value" -- figure it out.
00124          *
00125          * Skip leading whitespace.
00126          */
00127         while (isspace(*input))
00128                 ++input;
00129 
00130         /*
00131          * Find an operator, and it better not start the string.
00132          */
00133         if ((len = strcspn(field = input, "<>!=~")) == 0)
00134                 return (query_usage());
00135         op = field + len;
00136 
00137         /* Figure out the operator, and find the start of the value. */
00138         switch (op[0]) {
00139         case '~':
00140                 operator = WC;
00141                 value = op + 1;
00142                 break;
00143         case '!':
00144                 if (op[1] == '=') {
00145                         operator = NEQ;
00146                         value = op + 2;
00147                         break;
00148                 }
00149                 if (op[1] == '~') {
00150                         operator = NWC;
00151                         value = op + 2;
00152                         break;
00153                 }
00154                 return (query_usage());
00155         case '<':
00156                 if (op[1] == '=') {
00157                         operator = LTEQ;
00158                         value = op + 2;
00159                 } else {
00160                         operator = LT;
00161                         value = op + 1;
00162                 }
00163                 break;
00164         case '=':
00165                 operator = EQ;
00166                 if (op[1] == '=')
00167                         value = op + 2;
00168                 else
00169                         value = op + 1;
00170                 break;
00171         case '>':
00172                 if (op[1] == '=') {
00173                         operator = GTEQ;
00174                         value = op + 2;
00175                 } else {
00176                         operator = GT;
00177                         value = op + 1;
00178                 }
00179                 break;
00180         default:
00181                 return (query_usage());
00182         }
00183 
00184         /* Terminate the field name, and there better be a field name. */
00185         while (--op > input && isspace(*op))
00186                 ;
00187         if (op == input)
00188                 return (query_usage());
00189         op[1] = '\0';
00190 
00191         /* Make sure there is a value field. */
00192         while (isspace(*value))
00193                 ++value;
00194         if (*value == '\0')
00195                 return (query_usage());
00196 
00197         return (DbRecord_search_field_name(field, value, operator));
00198 }
00199 
00200 /*
00201  * query_fieldlist --
00202  *      Display list of field names.
00203  */
00204 static int
00205 query_fieldlist(char *input)
00206 {
00207         DbField *f;
00208 
00209         input = input;                          /* Quiet compiler. */
00210 
00211         for (f = fieldlist; f->name != NULL; ++f)
00212                 printf("field %3d: %s\n", f->fieldno, f->name);
00213         return (0);
00214 }
00215 
00216 /*
00217  * query_help --
00218  *      Query command list.
00219  */
00220 static int
00221 query_help(char *input)
00222 {
00223         CMDTAB *p;
00224 
00225         input = input;                          /* Quiet compiler. */
00226 
00227         printf("Query commands:\n");
00228         for (p = cmdtab; p->help != NULL; ++p)
00229                 printf("\t%s\n", p->help);
00230         return (0);
00231 }
00232 
00233 /*
00234  * query_usage --
00235  *      Query usage message.
00236  */
00237 static int
00238 query_usage(void)
00239 {
00240         fprintf(stderr, "%s: query syntax error\n", progname);
00241         return (query_help(NULL));
00242 }

Generated on Sun Dec 25 12:14:25 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2