mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-04-05 20:31:00 +08:00
First attempt at sql engine
This commit is contained in:
parent
5ceaff28ce
commit
58cb55ef0a
@ -159,6 +159,7 @@ typedef struct {
|
|||||||
int num_sargs;
|
int num_sargs;
|
||||||
GPtrArray *sargs;
|
GPtrArray *sargs;
|
||||||
unsigned char is_fixed;
|
unsigned char is_fixed;
|
||||||
|
int query_order;
|
||||||
} MdbColumn;
|
} MdbColumn;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
@ -106,6 +106,7 @@ int next_pg, next_pg_off;
|
|||||||
#if 0
|
#if 0
|
||||||
next_pg = MDB_CATALOG_PG;
|
next_pg = MDB_CATALOG_PG;
|
||||||
mdb_free_catalog(mdb);
|
mdb_free_catalog(mdb);
|
||||||
|
mdb->num_catalog = 0;
|
||||||
|
|
||||||
while (next_pg) {
|
while (next_pg) {
|
||||||
mdb_read_pg(mdb, next_pg);
|
mdb_read_pg(mdb, next_pg);
|
||||||
@ -126,6 +127,9 @@ int next_pg, next_pg_off;
|
|||||||
}
|
}
|
||||||
return (mdb->catalog);
|
return (mdb->catalog);
|
||||||
#endif
|
#endif
|
||||||
|
mdb_free_catalog(mdb);
|
||||||
|
mdb->num_catalog = 0;
|
||||||
|
|
||||||
mdb->catalog = g_array_new(FALSE,FALSE,sizeof(MdbCatalogEntry));
|
mdb->catalog = g_array_new(FALSE,FALSE,sizeof(MdbCatalogEntry));
|
||||||
next_pg=0;
|
next_pg=0;
|
||||||
while (mdb_read_pg(mdb,next_pg)) {
|
while (mdb_read_pg(mdb,next_pg)) {
|
||||||
|
@ -411,3 +411,39 @@ time_t t;
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
int mdb_col_disp_size(MdbColumn *col)
|
||||||
|
{
|
||||||
|
switch (col->col_type) {
|
||||||
|
case MDB_BOOL:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case MDB_BYTE:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case MDB_INT:
|
||||||
|
return 5;
|
||||||
|
break;
|
||||||
|
case MDB_LONGINT:
|
||||||
|
return 7;
|
||||||
|
break;
|
||||||
|
case MDB_FLOAT:
|
||||||
|
return 10;
|
||||||
|
break;
|
||||||
|
case MDB_DOUBLE:
|
||||||
|
return 10;
|
||||||
|
break;
|
||||||
|
case MDB_TEXT:
|
||||||
|
return col->col_size;
|
||||||
|
break;
|
||||||
|
case MDB_SDATETIME:
|
||||||
|
return 20;
|
||||||
|
break;
|
||||||
|
case MDB_MEMO:
|
||||||
|
return 255;
|
||||||
|
break;
|
||||||
|
case MDB_MONEY:
|
||||||
|
return 12;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -33,7 +33,7 @@ int j,pos;
|
|||||||
mdb->fd = open(filename,O_RDONLY);
|
mdb->fd = open(filename,O_RDONLY);
|
||||||
|
|
||||||
if (mdb->fd==-1) {
|
if (mdb->fd==-1) {
|
||||||
fprintf(stderr,"Couldn't open file %s\n",filename);
|
/* fprintf(stderr,"Couldn't open file %s\n",filename); */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!mdb_read_pg(mdb, 0)) {
|
if (!mdb_read_pg(mdb, 0)) {
|
||||||
|
30
src/sql/Makefile
Normal file
30
src/sql/Makefile
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
SHELL = /bin/sh
|
||||||
|
LEX = flex -i
|
||||||
|
YACC = yacc -d
|
||||||
|
CC = gcc
|
||||||
|
CPPFLAGS =
|
||||||
|
CFLAGS = $(CPPFLAG) -g -O2 -DHW_LITTLE_ENDIAN
|
||||||
|
LDFLAGS =
|
||||||
|
LIBS = -L ../libmdb -lmdb -ll `glib-config --libs` -lreadline -lncurses
|
||||||
|
|
||||||
|
INC = -I ../include `glib-config --cflags` -I/usr/include/readline
|
||||||
|
OBJS = y.tab.o lex.yy.o mdbsql.o main.o
|
||||||
|
|
||||||
|
all: sql
|
||||||
|
|
||||||
|
libmdb: $(OBJS)
|
||||||
|
rm -f libmdb.a
|
||||||
|
ar cq libmdb.a $(OBJS)
|
||||||
|
clean:
|
||||||
|
rm -f core *.o *.a y.tab.* lex.yy.c sql
|
||||||
|
|
||||||
|
lex.yy.c: sql.l
|
||||||
|
$(LEX) $<
|
||||||
|
y.tab.c: sql.y
|
||||||
|
$(YACC) $<
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) -g -c $< $(INC)
|
||||||
|
|
||||||
|
sql: $(OBJS)
|
||||||
|
$(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
|
||||||
|
|
76
src/sql/main.c
Normal file
76
src/sql/main.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <readline.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "mdbsql.h"
|
||||||
|
|
||||||
|
extern MdbSQL *g_sql;
|
||||||
|
|
||||||
|
char *g_input_ptr;
|
||||||
|
|
||||||
|
int mdb_sql_yyinput(char *buf, int need)
|
||||||
|
{
|
||||||
|
int cplen, have;
|
||||||
|
|
||||||
|
have = strlen(g_input_ptr);
|
||||||
|
cplen = need > have ? have : need;
|
||||||
|
|
||||||
|
if (cplen>0) {
|
||||||
|
memcpy(buf, g_input_ptr, cplen);
|
||||||
|
g_input_ptr += cplen;
|
||||||
|
}
|
||||||
|
return cplen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse(char *buf)
|
||||||
|
{
|
||||||
|
g_input_ptr = buf;
|
||||||
|
if (yyparse()) {
|
||||||
|
fprintf(stderr, "Couldn't parse SQL\n");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
char prompt[20];
|
||||||
|
int line = 1;
|
||||||
|
char *mybuf;
|
||||||
|
int bufsz = 4096;
|
||||||
|
int done = 0;
|
||||||
|
|
||||||
|
/* initialize the SQL engine */
|
||||||
|
g_sql = mdb_sql_init();
|
||||||
|
|
||||||
|
/* give the buffer an initial size */
|
||||||
|
bufsz = 4096;
|
||||||
|
mybuf = (char *) malloc(bufsz);
|
||||||
|
mybuf[0]='\0';
|
||||||
|
|
||||||
|
sprintf(prompt,"1 => ");
|
||||||
|
s=readline(prompt);
|
||||||
|
while (!done) {
|
||||||
|
if (!strcmp(s,"go")) {
|
||||||
|
line = 0;
|
||||||
|
parse(mybuf);
|
||||||
|
mybuf[0]='\0';
|
||||||
|
} else if (!strcmp(s,"reset")) {
|
||||||
|
line = 0;
|
||||||
|
mybuf[0]='\0';
|
||||||
|
} else {
|
||||||
|
add_history(s);
|
||||||
|
strcat(mybuf,s);
|
||||||
|
/* preserve line numbering for the parser */
|
||||||
|
strcat(mybuf,"\n");
|
||||||
|
}
|
||||||
|
sprintf(prompt,"%d => ",++line);
|
||||||
|
free(s);
|
||||||
|
s=readline(prompt);
|
||||||
|
if (!strcmp(s,"exit") || !strcmp(s,"quit") || !strcmp(s,"bye")) {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mdb_sql_exit(g_sql);
|
||||||
|
}
|
357
src/sql/mdbsql.c
Normal file
357
src/sql/mdbsql.c
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
#include "mdbsql.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
mdb_sql_error(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf (stderr,fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fprintf(stderr,"\n");
|
||||||
|
}
|
||||||
|
MdbSQL *mdb_sql_init()
|
||||||
|
{
|
||||||
|
MdbSQL *sql;
|
||||||
|
|
||||||
|
mdb_init();
|
||||||
|
sql = (MdbSQL *) g_malloc0(sizeof(MdbSQL));
|
||||||
|
sql->columns = g_ptr_array_new();
|
||||||
|
sql->tables = g_ptr_array_new();
|
||||||
|
sql->sargs = g_ptr_array_new();
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
MdbSQLSarg *mdb_sql_alloc_sarg()
|
||||||
|
{
|
||||||
|
MdbSQLSarg *sql_sarg;
|
||||||
|
sql_sarg = (MdbSQLSarg *) malloc(sizeof(MdbSQLSarg));
|
||||||
|
memset(sql_sarg,0,sizeof(MdbSQLSarg));
|
||||||
|
sql_sarg->sarg = (MdbSarg *) malloc(sizeof(MdbSarg));
|
||||||
|
memset(sql_sarg->sarg,0,sizeof(MdbSarg));
|
||||||
|
return sql_sarg;
|
||||||
|
}
|
||||||
|
MdbSQLColumn *mdb_sql_alloc_column()
|
||||||
|
{
|
||||||
|
MdbSQLColumn *c;
|
||||||
|
|
||||||
|
c = (MdbSQLColumn *) malloc(sizeof(MdbSQLColumn));
|
||||||
|
memset(c,0,sizeof(MdbSQLColumn));
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
MdbSQLTable *mdb_sql_alloc_table()
|
||||||
|
{
|
||||||
|
MdbSQLTable *t;
|
||||||
|
|
||||||
|
t = (MdbSQLTable *) malloc(sizeof(MdbSQLTable));
|
||||||
|
memset(t,0,sizeof(MdbSQLTable));
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
MdbHandle *mdb_sql_open(MdbSQL *sql, char *db_name)
|
||||||
|
{
|
||||||
|
int fail = 0;
|
||||||
|
if (!(sql->mdb = mdb_open(db_name))) {
|
||||||
|
if (!strstr(db_name, ".mdb")) {
|
||||||
|
char *tmpstr = (char *) malloc(strlen(db_name)+5);
|
||||||
|
strcpy(tmpstr,db_name);
|
||||||
|
strcat(tmpstr,".mdb");
|
||||||
|
if (!(sql->mdb = mdb_open(tmpstr))) {
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
free(tmpstr);
|
||||||
|
} else {
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fail) {
|
||||||
|
mdb_sql_error("Unable to locate database %s", db_name);
|
||||||
|
}
|
||||||
|
return sql->mdb;
|
||||||
|
|
||||||
|
}
|
||||||
|
int mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
|
||||||
|
{
|
||||||
|
MdbSQLSarg *sql_sarg;
|
||||||
|
|
||||||
|
sql_sarg = mdb_sql_alloc_sarg();
|
||||||
|
sql_sarg->col_name = g_strdup(col_name);
|
||||||
|
sql_sarg->sarg->op = op;
|
||||||
|
sql_sarg->sarg->value.i = atoi(constant);
|
||||||
|
g_ptr_array_add(sql->sargs, sql_sarg);
|
||||||
|
sql->num_sargs++;
|
||||||
|
}
|
||||||
|
int mdb_sql_all_columns(MdbSQL *sql)
|
||||||
|
{
|
||||||
|
sql->all_columns=1;
|
||||||
|
}
|
||||||
|
int mdb_sql_add_column(MdbSQL *sql, char *column_name)
|
||||||
|
{
|
||||||
|
MdbSQLColumn *c, *cp;
|
||||||
|
|
||||||
|
c = mdb_sql_alloc_column();
|
||||||
|
c->name = g_strdup(column_name);
|
||||||
|
g_ptr_array_add(sql->columns, c);
|
||||||
|
sql->num_columns++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int mdb_sql_add_table(MdbSQL *sql, char *table_name)
|
||||||
|
{
|
||||||
|
MdbSQLTable *t;
|
||||||
|
|
||||||
|
t = mdb_sql_alloc_table();
|
||||||
|
t->name = g_strdup(table_name);
|
||||||
|
t->alias = NULL;
|
||||||
|
g_ptr_array_add(sql->tables, t);
|
||||||
|
sql->num_tables++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void mdb_sql_dump(MdbSQL *sql)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
MdbSQLColumn *c;
|
||||||
|
MdbSQLTable *t;
|
||||||
|
|
||||||
|
for (i=0;i<sql->num_columns;i++) {
|
||||||
|
c = g_ptr_array_index(sql->columns,i);
|
||||||
|
printf("column = %s\n",c->name);
|
||||||
|
}
|
||||||
|
for (i=0;i<sql->num_tables;i++) {
|
||||||
|
t = g_ptr_array_index(sql->tables,i);
|
||||||
|
printf("table = %s\n",t->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void mdb_sql_exit(MdbSQL *sql)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
MdbSQLColumn *c;
|
||||||
|
MdbSQLTable *t;
|
||||||
|
MdbSQLSarg *sql_sarg;
|
||||||
|
|
||||||
|
for (i=0;i<sql->num_columns;i++) {
|
||||||
|
c = g_ptr_array_index(sql->columns,i);
|
||||||
|
if (c->name) g_free(c->name);
|
||||||
|
}
|
||||||
|
for (i=0;i<sql->num_tables;i++) {
|
||||||
|
t = g_ptr_array_index(sql->tables,i);
|
||||||
|
if (t->name) g_free(t->name);
|
||||||
|
}
|
||||||
|
for (i=0;i<sql->num_sargs;i++) {
|
||||||
|
sql_sarg = g_ptr_array_index(sql->sargs,i);
|
||||||
|
if (sql_sarg->col_name) g_free(sql_sarg->col_name);
|
||||||
|
if (sql_sarg->sarg) g_free(sql_sarg->sarg);
|
||||||
|
}
|
||||||
|
g_ptr_array_free(sql->columns,TRUE);
|
||||||
|
g_ptr_array_free(sql->tables,TRUE);
|
||||||
|
g_ptr_array_free(sql->sargs,TRUE);
|
||||||
|
}
|
||||||
|
void mdb_sql_reset(MdbSQL *sql)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
MdbSQLColumn *c;
|
||||||
|
MdbSQLTable *t;
|
||||||
|
MdbSQLSarg *sql_sarg;
|
||||||
|
|
||||||
|
for (i=0;i<sql->num_columns;i++) {
|
||||||
|
c = g_ptr_array_index(sql->columns,i);
|
||||||
|
if (c->name) g_free(c->name);
|
||||||
|
}
|
||||||
|
for (i=0;i<sql->num_tables;i++) {
|
||||||
|
t = g_ptr_array_index(sql->tables,i);
|
||||||
|
if (t->name) g_free(t->name);
|
||||||
|
}
|
||||||
|
for (i=0;i<sql->num_sargs;i++) {
|
||||||
|
sql_sarg = g_ptr_array_index(sql->sargs,i);
|
||||||
|
if (sql_sarg->col_name) g_free(sql_sarg->col_name);
|
||||||
|
if (sql_sarg->sarg) g_free(sql_sarg->sarg);
|
||||||
|
}
|
||||||
|
g_ptr_array_free(sql->columns,TRUE);
|
||||||
|
g_ptr_array_free(sql->tables,TRUE);
|
||||||
|
g_ptr_array_free(sql->sargs,TRUE);
|
||||||
|
|
||||||
|
sql->all_columns = 0;
|
||||||
|
sql->num_columns = 0;
|
||||||
|
sql->columns = g_ptr_array_new();
|
||||||
|
sql->num_tables = 0;
|
||||||
|
sql->tables = g_ptr_array_new();
|
||||||
|
sql->num_sargs = 0;
|
||||||
|
sql->sargs = g_ptr_array_new();
|
||||||
|
}
|
||||||
|
static void print_break(int sz, int first)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (first) {
|
||||||
|
fprintf(stdout,"+");
|
||||||
|
}
|
||||||
|
for (i=0;i<sz;i++) {
|
||||||
|
fprintf(stdout,"-");
|
||||||
|
}
|
||||||
|
fprintf(stdout,"+");
|
||||||
|
}
|
||||||
|
static void print_value(char *v, int sz, int first)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int vlen;
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
fprintf(stdout,"|");
|
||||||
|
}
|
||||||
|
vlen = strlen(v);
|
||||||
|
for (i=0;i<sz;i++) {
|
||||||
|
fprintf(stdout,"%c",i >= vlen ? ' ' : v[i]);
|
||||||
|
}
|
||||||
|
fprintf(stdout,"|");
|
||||||
|
}
|
||||||
|
void mdb_sql_listtables(MdbSQL *sql)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
MdbCatalogEntry entry;
|
||||||
|
MdbHandle *mdb = sql->mdb;
|
||||||
|
|
||||||
|
if (!mdb) {
|
||||||
|
mdb_sql_error("You must connect to a database first");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mdb_read_catalog (mdb, MDB_TABLE);
|
||||||
|
|
||||||
|
|
||||||
|
print_break (30,1);
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
print_value ("Tables",30,1);
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
print_break (30,1);
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
/* loop over each entry in the catalog */
|
||||||
|
for (i=0; i < mdb->num_catalog; i++) {
|
||||||
|
entry = g_array_index (mdb->catalog, MdbCatalogEntry, i);
|
||||||
|
/* if it's a table */
|
||||||
|
if (entry.object_type == MDB_TABLE) {
|
||||||
|
if (strncmp (entry.object_name, "MSys", 4)) {
|
||||||
|
print_value (entry.object_name,30,1);
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_break (30,1);
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
}
|
||||||
|
void mdb_sql_select(MdbSQL *sql)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
MdbCatalogEntry entry;
|
||||||
|
MdbHandle *mdb = sql->mdb;
|
||||||
|
MdbTableDef *table = NULL;
|
||||||
|
MdbSQLTable *sql_tab;
|
||||||
|
char *bound_values[256];
|
||||||
|
MdbColumn *col;
|
||||||
|
MdbSQLColumn *sqlcol;
|
||||||
|
MdbSQLSarg *sql_sarg;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
if (!mdb) {
|
||||||
|
mdb_sql_error("You must connect to a database first");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql_tab = g_ptr_array_index(sql->tables,0);
|
||||||
|
|
||||||
|
mdb_read_catalog(mdb, MDB_TABLE);
|
||||||
|
|
||||||
|
for (i=0;i<mdb->num_catalog;i++) {
|
||||||
|
entry = g_array_index(mdb->catalog,MdbCatalogEntry,i);
|
||||||
|
if (entry.object_type == MDB_TABLE &&
|
||||||
|
!strcmp(entry.object_name,sql_tab->name)) {
|
||||||
|
table = mdb_read_table(&entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!table) {
|
||||||
|
mdb_sql_error("%s is not a table in this database", sql_tab->name);
|
||||||
|
/* the column and table names are no good now */
|
||||||
|
mdb_sql_reset(sql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mdb_read_columns(table);
|
||||||
|
mdb_rewind_table(table);
|
||||||
|
|
||||||
|
if (sql->all_columns) {
|
||||||
|
for (i=0;i<table->num_cols;i++) {
|
||||||
|
col=g_ptr_array_index(table->columns,i);
|
||||||
|
sqlcol = mdb_sql_alloc_column();
|
||||||
|
sqlcol->name = g_strdup(col->name);
|
||||||
|
g_ptr_array_add(sql->columns, sqlcol);
|
||||||
|
sql->num_columns++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i=0;i<sql->num_columns;i++) {
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,i);
|
||||||
|
found=0;
|
||||||
|
for (j=0;j<table->num_cols;j++) {
|
||||||
|
col=g_ptr_array_index(table->columns,j);
|
||||||
|
if (!strcmp(sqlcol->name, col->name)) {
|
||||||
|
bound_values[i] = (char *) malloc(MDB_BIND_SIZE);
|
||||||
|
bound_values[i][0] = '\0';
|
||||||
|
/* bind the column to its listed (SQL) position */
|
||||||
|
mdb_bind_column(table, j+1, bound_values[i]);
|
||||||
|
sqlcol->disp_size = mdb_col_disp_size(col);
|
||||||
|
found=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
mdb_sql_error("Column %s not found",sqlcol->name);
|
||||||
|
mdb_sql_reset(sql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now add back the sargs */
|
||||||
|
for (i=0;i<sql->num_sargs;i++) {
|
||||||
|
sql_sarg=g_ptr_array_index(sql->sargs,i);
|
||||||
|
fprintf(stdout,"Sarg for %s\n",sql_sarg->col_name);
|
||||||
|
mdb_add_sarg_by_name(table,sql_sarg->col_name, sql_sarg->sarg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print header */
|
||||||
|
for (j=0;j<sql->num_columns;j++) {
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||||
|
print_break(sqlcol->disp_size, !j);
|
||||||
|
}
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
for (j=0;j<sql->num_columns;j++) {
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||||
|
print_value(sqlcol->name,sqlcol->disp_size,!j);
|
||||||
|
}
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
for (j=0;j<sql->num_columns;j++) {
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||||
|
print_break(sqlcol->disp_size, !j);
|
||||||
|
}
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
|
||||||
|
/* print each row */
|
||||||
|
while(mdb_fetch_row(table)) {
|
||||||
|
for (j=0;j<sql->num_columns;j++) {
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||||
|
print_value(bound_values[j],sqlcol->disp_size,!j);
|
||||||
|
}
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* footer */
|
||||||
|
for (j=0;j<sql->num_columns;j++) {
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||||
|
print_break(sqlcol->disp_size, !j);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout,"\n");
|
||||||
|
/* clean up */
|
||||||
|
for (j=0;j<sql->num_columns;j++) {
|
||||||
|
if (bound_values[j]) free(bound_values[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the column and table names are no good now */
|
||||||
|
mdb_sql_reset(sql);
|
||||||
|
}
|
||||||
|
|
48
src/sql/mdbsql.h
Normal file
48
src/sql/mdbsql.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <mdbtools.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MdbHandle *mdb;
|
||||||
|
int all_columns;
|
||||||
|
int num_columns;
|
||||||
|
GPtrArray *columns;
|
||||||
|
int num_tables;
|
||||||
|
GPtrArray *tables;
|
||||||
|
int num_sargs;
|
||||||
|
GPtrArray *sargs;
|
||||||
|
} MdbSQL;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
int disp_size;
|
||||||
|
} MdbSQLColumn;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
char *alias;
|
||||||
|
} MdbSQLTable;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *col_name;
|
||||||
|
MdbSarg *sarg;
|
||||||
|
} MdbSQLSarg;
|
||||||
|
|
||||||
|
#undef YY_INPUT
|
||||||
|
#define YY_INPUT(b, r, ms) (r = mdb_sql_yyinput(b, ms));
|
||||||
|
|
||||||
|
MdbSQL *mdb_sql_init();
|
||||||
|
MdbSQLSarg *mdb_sql_alloc_sarg();
|
||||||
|
MdbSQLColumn *mdb_sql_alloc_column();
|
||||||
|
MdbSQLTable *mdb_sql_alloc_table();
|
||||||
|
MdbHandle *mdb_sql_open(MdbSQL *sql, char *db_name);
|
||||||
|
int mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant);
|
||||||
|
int mdb_sql_all_columns(MdbSQL *sql);
|
||||||
|
int mdb_sql_add_column(MdbSQL *sql, char *column_name);
|
||||||
|
int mdb_sql_add_table(MdbSQL *sql, char *table_name);
|
||||||
|
void mdb_sql_dump(MdbSQL *sql);
|
||||||
|
void mdb_sql_exit(MdbSQL *sql);
|
||||||
|
void mdb_sql_reset(MdbSQL *sql);
|
||||||
|
void mdb_sql_listtables(MdbSQL *sql);
|
||||||
|
void mdb_sql_select(MdbSQL *sql);
|
46
src/sql/sql.l
Normal file
46
src/sql/sql.l
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
%{
|
||||||
|
#include "y.tab.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include "mdbsql.h"
|
||||||
|
|
||||||
|
extern MdbSQL *g_sql;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%%
|
||||||
|
select { return SELECT; }
|
||||||
|
from { return FROM; }
|
||||||
|
connect { return CONNECT; }
|
||||||
|
to { return TO; }
|
||||||
|
list { return LIST; }
|
||||||
|
where { return WHERE; }
|
||||||
|
and { return AND; }
|
||||||
|
tables { return TABLES; }
|
||||||
|
[ \t\r] ;
|
||||||
|
[A-z][A-z0-9]* { yylval.name = strdup(yytext); return NAME; }
|
||||||
|
'.*' { yylval.name = strdup(yytext); return STRING; }
|
||||||
|
([0-9]+|([0-9]*\.[0-9+)([eE][-+]?[0-9]+)?) {
|
||||||
|
yylval.name = strdup(yytext); return NUMBER;
|
||||||
|
}
|
||||||
|
(\/?[A-z0-9\.]+)+ { yylval.name = strdup(yytext); return PATH; }
|
||||||
|
. { return yytext[0]; }
|
||||||
|
%%
|
||||||
|
|
||||||
|
void yyerror(char *s)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Error at Line : %s near %s\n", s, yytext);
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_sql = mdb_sql_init();
|
||||||
|
yyin = stdin;
|
||||||
|
if (yyparse()) {
|
||||||
|
fprintf(stderr, "Couldn't parse SQL\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
mdb_sql_dump(g_sql);
|
||||||
|
mdb_sql_exit(g_sql);
|
||||||
|
}
|
||||||
|
#endif
|
81
src/sql/sql.y
Normal file
81
src/sql/sql.y
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
%{
|
||||||
|
#include "mdbsql.h"
|
||||||
|
|
||||||
|
MdbSQL *g_sql;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
char *name;
|
||||||
|
double dval;
|
||||||
|
int ival;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token NAME PATH NUMBER STRING
|
||||||
|
%token SELECT FROM WHERE CONNECT TO LIST TABLES WHERE AND
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
query:
|
||||||
|
SELECT column_list FROM table where_clause {
|
||||||
|
mdb_sql_select(g_sql);
|
||||||
|
}
|
||||||
|
| CONNECT TO database {
|
||||||
|
mdb_sql_open(g_sql, $3.name); free($3.name);
|
||||||
|
}
|
||||||
|
| LIST TABLES {
|
||||||
|
mdb_sql_listtables(g_sql);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
where_clause:
|
||||||
|
/* empty */
|
||||||
|
| WHERE sarg_list
|
||||||
|
;
|
||||||
|
|
||||||
|
sarg_list:
|
||||||
|
sarg
|
||||||
|
| sarg AND sarg_list
|
||||||
|
;
|
||||||
|
|
||||||
|
sarg:
|
||||||
|
NAME operator constant {
|
||||||
|
mdb_sql_add_sarg(g_sql, $1.name, $2.ival, $3.name);
|
||||||
|
free($1.name);
|
||||||
|
free($3.name);
|
||||||
|
}
|
||||||
|
| constant operator NAME {
|
||||||
|
mdb_sql_add_sarg(g_sql, $3.name, $2.ival, $1.name);
|
||||||
|
free($1.name);
|
||||||
|
free($3.name);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
operator:
|
||||||
|
'=' { $$.ival = MDB_EQUAL; }
|
||||||
|
| '>' { $$.ival = MDB_GT; }
|
||||||
|
| '<' { $$.ival = MDB_LT; }
|
||||||
|
;
|
||||||
|
constant:
|
||||||
|
NUMBER { $$.name = $1.name; }
|
||||||
|
| STRING { $$.name = $1.name; }
|
||||||
|
;
|
||||||
|
|
||||||
|
database:
|
||||||
|
PATH
|
||||||
|
| NAME
|
||||||
|
|
||||||
|
table:
|
||||||
|
NAME { mdb_sql_add_table(g_sql, $1.name); free($1.name); }
|
||||||
|
;
|
||||||
|
|
||||||
|
column_list:
|
||||||
|
'*' { mdb_sql_all_columns(g_sql); }
|
||||||
|
| column
|
||||||
|
| column ',' column_list
|
||||||
|
;
|
||||||
|
|
||||||
|
column:
|
||||||
|
NAME { mdb_sql_add_column(g_sql, $1.name); free($1.name); }
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
Loading…
Reference in New Issue
Block a user