00001
00002
00003
00004
00005
00006
00007
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;
00021 int (*f)(char *);
00022 char *help;
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
00049
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
00084
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
00113
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
00124
00125
00126
00127 while (isspace(*input))
00128 ++input;
00129
00130
00131
00132
00133 if ((len = strcspn(field = input, "<>!=~")) == 0)
00134 return (query_usage());
00135 op = field + len;
00136
00137
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
00185 while (--op > input && isspace(*op))
00186 ;
00187 if (op == input)
00188 return (query_usage());
00189 op[1] = '\0';
00190
00191
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
00202
00203
00204 static int
00205 query_fieldlist(char *input)
00206 {
00207 DbField *f;
00208
00209 input = input;
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
00218
00219
00220 static int
00221 query_help(char *input)
00222 {
00223 CMDTAB *p;
00224
00225 input = input;
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
00235
00236
00237 static int
00238 query_usage(void)
00239 {
00240 fprintf(stderr, "%s: query syntax error\n", progname);
00241 return (query_help(NULL));
00242 }