mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-11-25 17:59:54 +08:00
Some work on indexes/write support. Bug fixes. Preliminary temp table/worktable work.
This commit is contained in:
16
ChangeLog
16
ChangeLog
@@ -1,3 +1,19 @@
|
|||||||
|
Wed Jan 9 15:22:11 EST 2004 Brian Bruns <camber@ais.org>
|
||||||
|
|
||||||
|
* include/mdbtools.h:
|
||||||
|
* src/libmdb/index.c:
|
||||||
|
* src/libmdb/write.c: modularize this a bit more to allow reuse
|
||||||
|
* src/libmdb/worktable.c: preliminary worktable/temp table support
|
||||||
|
* src/libmdb/table.c: fix reading of free page map and enable
|
||||||
|
* src/data/data.c: use mdb_crack_row() from write.c for cleaner row
|
||||||
|
handling. Fix delflag bug.
|
||||||
|
* src/util/updrow.c: fix sarg handling
|
||||||
|
* src/util/mdb-import.c: check for valid table
|
||||||
|
* src/sql/mdbsql.c:
|
||||||
|
* src/util/mdb-sql.c: Fix H and F flags. Change "list tables" and
|
||||||
|
"describe table" to write to worktable so client can pull results (almost)
|
||||||
|
like a normal query.
|
||||||
|
|
||||||
Wed Jan 22 14:54:11 EST 2003 Brian Bruns <camber@ais.org>
|
Wed Jan 22 14:54:11 EST 2003 Brian Bruns <camber@ais.org>
|
||||||
|
|
||||||
* src/util/mdb-sql.c: typo fix
|
* src/util/mdb-sql.c: typo fix
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ typedef struct {
|
|||||||
GList *sarg_stack;
|
GList *sarg_stack;
|
||||||
/* FIX ME */
|
/* FIX ME */
|
||||||
char *bound_values[256];
|
char *bound_values[256];
|
||||||
|
unsigned char *kludge_ttable_pg;
|
||||||
} MdbSQL;
|
} MdbSQL;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -444,5 +444,6 @@ extern int mdb_like_cmp(char *s, char *r);
|
|||||||
|
|
||||||
/* write.c */
|
/* write.c */
|
||||||
extern int mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields);
|
extern int mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields);
|
||||||
|
extern void mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size);
|
||||||
|
|
||||||
#endif /* _mdbtools_h_ */
|
#endif /* _mdbtools_h_ */
|
||||||
|
|||||||
@@ -221,23 +221,42 @@ int mdb_read_row(MdbTableDef *table, int row)
|
|||||||
lookupflag ? "[lookup]" : "",
|
lookupflag ? "[lookup]" : "",
|
||||||
delflag ? "[delflag]" : "");
|
delflag ? "[delflag]" : "");
|
||||||
#endif
|
#endif
|
||||||
num_fields = mdb_crack_row(table, row_start, row_end, &fields);
|
|
||||||
if (!mdb_test_sargs(table, &fields, num_fields)) return 0;
|
|
||||||
for (i=0; i < num_fields; i++) {
|
|
||||||
//col = g_ptr_array_index (table->columns, fields[i].colnum - 1);
|
|
||||||
//rc = _mdb_attempt_bind(mdb, col, fields[i].is_null,
|
|
||||||
//row_start + col_start, col->col_size);
|
|
||||||
}
|
|
||||||
//if (!table->noskip_del && (delflag || lookupflag)) {
|
|
||||||
if (!table->noskip_del && delflag) {
|
if (!table->noskip_del && delflag) {
|
||||||
row_end = row_start-1;
|
row_end = row_start-1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
num_fields = mdb_crack_row(table, row_start, row_end, &fields);
|
||||||
|
if (!mdb_test_sargs(table, &fields, num_fields)) return 0;
|
||||||
|
|
||||||
|
#if MDB_DEBUG
|
||||||
|
fprintf(stdout,"sarg test passed row %d \n", row);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MDB_DEBUG
|
#if MDB_DEBUG
|
||||||
buffer_dump(mdb->pg_buf, row_start, row_end);
|
buffer_dump(mdb->pg_buf, row_start, row_end);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* take advantage of mdb_crack_row() to clean up binding */
|
||||||
|
for (i = 0; i < num_fields; i++) {
|
||||||
|
col = g_ptr_array_index(table->columns,fields[i].colnum);
|
||||||
|
if (fields[i].is_fixed) {
|
||||||
|
rc = _mdb_attempt_bind(mdb, col,
|
||||||
|
fields[i].is_null,
|
||||||
|
fields[i].start,
|
||||||
|
col->col_size);
|
||||||
|
} else {
|
||||||
|
rc = _mdb_attempt_bind(mdb, col,
|
||||||
|
fields[i].is_null,
|
||||||
|
fields[i].start,
|
||||||
|
fields[i].siz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* find out all the important stuff about the row */
|
/* find out all the important stuff about the row */
|
||||||
if (IS_JET4(mdb)) {
|
if (IS_JET4(mdb)) {
|
||||||
num_cols = mdb_pg_get_int16(mdb, row_start);
|
num_cols = mdb_pg_get_int16(mdb, row_start);
|
||||||
@@ -386,6 +405,7 @@ int mdb_read_row(MdbTableDef *table, int row)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
static int _mdb_attempt_bind(MdbHandle *mdb,
|
static int _mdb_attempt_bind(MdbHandle *mdb,
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
#include "dmalloc.h"
|
#include "dmalloc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MdbIndexPage *mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
|
||||||
|
MdbIndexPage *mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg);
|
||||||
|
|
||||||
char idx_to_text[] = {
|
char idx_to_text[] = {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0-7 0x00-0x07 */
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0-7 0x00-0x07 */
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8-15 0x09-0x0f */
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8-15 0x09-0x0f */
|
||||||
@@ -334,20 +337,19 @@ void mdb_index_page_init(MdbIndexPage *ipg)
|
|||||||
* pages at the end of the chain have been peeled off before the call.
|
* pages at the end of the chain have been peeled off before the call.
|
||||||
*/
|
*/
|
||||||
MdbIndexPage *
|
MdbIndexPage *
|
||||||
mdb_find_next_leaf(MdbHandle *mdb, MdbIndexChain *chain)
|
mdb_find_next_leaf(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
|
||||||
{
|
{
|
||||||
MdbIndexPage *ipg, *newipg;
|
MdbIndexPage *ipg, *newipg;
|
||||||
guint32 pg;
|
guint32 pg;
|
||||||
guint passed = 0;
|
guint passed = 0;
|
||||||
|
|
||||||
ipg = &(chain->pages[chain->cur_depth - 1]);
|
ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are at the first page deep and it's not an index page then
|
* If we are at the first page deep and it's not an index page then
|
||||||
* we are simply done. (there is no page to find
|
* we are simply done. (there is no page to find
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mdb_read_pg(mdb, ipg->pg);
|
|
||||||
if (mdb->pg_buf[0]==MDB_PAGE_LEAF)
|
if (mdb->pg_buf[0]==MDB_PAGE_LEAF)
|
||||||
return ipg;
|
return ipg;
|
||||||
|
|
||||||
@@ -367,15 +369,8 @@ mdb_find_next_leaf(MdbHandle *mdb, MdbIndexChain *chain)
|
|||||||
* add to the chain and call this function
|
* add to the chain and call this function
|
||||||
* recursively.
|
* recursively.
|
||||||
*/
|
*/
|
||||||
chain->cur_depth++;
|
newipg = mdb_chain_add_page(mdb, chain, pg);
|
||||||
if (chain->cur_depth > MDB_MAX_INDEX_DEPTH) {
|
newipg = mdb_find_next_leaf(mdb, idx, chain);
|
||||||
fprintf(stderr,"Error! maximum index depth of %d exceeded. This is probably due to a programming bug, If you are confident that your indexes really are this deep, adjust MDB_MAX_INDEX_DEPTH in mdbtools.h and recompile.\n", MDB_MAX_INDEX_DEPTH);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
newipg = &(chain->pages[chain->cur_depth - 1]);
|
|
||||||
mdb_index_page_init(newipg);
|
|
||||||
newipg->pg = pg;
|
|
||||||
newipg = mdb_find_next_leaf(mdb, chain);
|
|
||||||
//printf("returning pg %lu\n",newipg->pg);
|
//printf("returning pg %lu\n",newipg->pg);
|
||||||
return newipg;
|
return newipg;
|
||||||
} while (!passed);
|
} while (!passed);
|
||||||
@@ -383,6 +378,46 @@ mdb_find_next_leaf(MdbHandle *mdb, MdbIndexChain *chain)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
MdbIndexPage *
|
||||||
|
mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg)
|
||||||
|
{
|
||||||
|
MdbIndexPage *ipg;
|
||||||
|
|
||||||
|
chain->cur_depth++;
|
||||||
|
if (chain->cur_depth > MDB_MAX_INDEX_DEPTH) {
|
||||||
|
fprintf(stderr,"Error! maximum index depth of %d exceeded. This is probably due to a programming bug, If you are confident that your indexes really are this deep, adjust MDB_MAX_INDEX_DEPTH in mdbtools.h and recompile.\n", MDB_MAX_INDEX_DEPTH);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
ipg = &(chain->pages[chain->cur_depth - 1]);
|
||||||
|
mdb_index_page_init(ipg);
|
||||||
|
ipg->pg = pg;
|
||||||
|
|
||||||
|
return ipg;
|
||||||
|
}
|
||||||
|
MdbIndexPage *
|
||||||
|
mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
|
||||||
|
{
|
||||||
|
MdbIndexPage *ipg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if it's new use the root index page (idx->first_pg)
|
||||||
|
*/
|
||||||
|
if (!chain->cur_depth) {
|
||||||
|
ipg = &(chain->pages[0]);
|
||||||
|
mdb_index_page_init(ipg);
|
||||||
|
chain->cur_depth = 1;
|
||||||
|
ipg->pg = idx->first_pg;
|
||||||
|
if (!(ipg = mdb_find_next_leaf(mdb, idx, chain)))
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
ipg = &(chain->pages[chain->cur_depth - 1]);
|
||||||
|
ipg->len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mdb_read_pg(mdb, ipg->pg);
|
||||||
|
|
||||||
|
return ipg;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* the main index function.
|
* the main index function.
|
||||||
* caller provides an index chain which is the current traversal of index
|
* caller provides an index chain which is the current traversal of index
|
||||||
@@ -401,22 +436,8 @@ mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32
|
|||||||
MdbIndexPage *ipg;
|
MdbIndexPage *ipg;
|
||||||
int passed = 0;
|
int passed = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
* if it's new use the root index page (idx->first_pg)
|
|
||||||
*/
|
|
||||||
if (!chain->cur_depth) {
|
|
||||||
ipg = &(chain->pages[0]);
|
|
||||||
mdb_index_page_init(ipg);
|
|
||||||
chain->cur_depth = 1;
|
|
||||||
ipg->pg = idx->first_pg;
|
|
||||||
if (!(ipg = mdb_find_next_leaf(mdb, chain)))
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
ipg = &(chain->pages[chain->cur_depth - 1]);
|
|
||||||
ipg->len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mdb_read_pg(mdb, ipg->pg);
|
ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* loop while the sargs don't match
|
* loop while the sargs don't match
|
||||||
@@ -436,7 +457,7 @@ mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32
|
|||||||
*/
|
*/
|
||||||
while (chain->cur_depth>1) {
|
while (chain->cur_depth>1) {
|
||||||
chain->cur_depth--;
|
chain->cur_depth--;
|
||||||
if (!(ipg = mdb_find_next_leaf(mdb, chain)))
|
if (!(ipg = mdb_find_next_leaf(mdb, idx, chain)))
|
||||||
return 0;
|
return 0;
|
||||||
mdb_index_find_next_on_page(mdb, ipg);
|
mdb_index_find_next_on_page(mdb, ipg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,8 +82,8 @@ int rownum, row_start, row_end;
|
|||||||
|
|
||||||
|
|
||||||
/* now grab the free space page map */
|
/* now grab the free space page map */
|
||||||
#if 0
|
#if 1
|
||||||
mdb_swap_pgbuf(mdb);
|
//mdb_swap_pgbuf(mdb);
|
||||||
rownum = mdb->pg_buf[fmt->tab_free_map_offset];
|
rownum = mdb->pg_buf[fmt->tab_free_map_offset];
|
||||||
mdb_read_alt_pg(mdb, mdb_pg_get_int24(mdb, fmt->tab_free_map_offset + 1));
|
mdb_read_alt_pg(mdb, mdb_pg_get_int24(mdb, fmt->tab_free_map_offset + 1));
|
||||||
mdb_swap_pgbuf(mdb);
|
mdb_swap_pgbuf(mdb);
|
||||||
@@ -92,6 +92,7 @@ int rownum, row_start, row_end;
|
|||||||
table->freemap_sz = row_end - row_start + 1;
|
table->freemap_sz = row_end - row_start + 1;
|
||||||
table->free_usage_map = malloc(table->freemap_sz);
|
table->free_usage_map = malloc(table->freemap_sz);
|
||||||
memcpy(table->free_usage_map, &mdb->pg_buf[row_start], table->freemap_sz);
|
memcpy(table->free_usage_map, &mdb->pg_buf[row_start], table->freemap_sz);
|
||||||
|
mdb_swap_pgbuf(mdb);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
table->first_data_pg = mdb_pg_get_int16(mdb, fmt->tab_first_dpg_offset);
|
table->first_data_pg = mdb_pg_get_int16(mdb, fmt->tab_first_dpg_offset);
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ int i;
|
|||||||
/* column is null is bit is clear (0) */
|
/* column is null is bit is clear (0) */
|
||||||
if (!fields[i].is_null) {
|
if (!fields[i].is_null) {
|
||||||
byte |= 1 << bit;
|
byte |= 1 << bit;
|
||||||
printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
|
//printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
|
||||||
}
|
}
|
||||||
bit++;
|
bit++;
|
||||||
if (bit==8) {
|
if (bit==8) {
|
||||||
@@ -302,9 +302,48 @@ mdb_update_indexes(MdbTableDef *table, int num_fields, MdbField *fields)
|
|||||||
#if MDB_DEBUG_WRITE
|
#if MDB_DEBUG_WRITE
|
||||||
fprintf(stderr,"Updating %s (%d).\n", idx->name, idx->index_type);
|
fprintf(stderr,"Updating %s (%d).\n", idx->name, idx->index_type);
|
||||||
#endif
|
#endif
|
||||||
|
if (idx->index_type==1) {
|
||||||
|
mdb_update_index(table, idx, num_fields, fields);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mdb_init_index_chain(MdbTableDef *table, MdbIndex *idx)
|
||||||
|
{
|
||||||
|
MdbCatalogEntry *entry = table->entry;
|
||||||
|
MdbHandle *mdb = entry->mdb;
|
||||||
|
|
||||||
|
table->scan_idx = idx;
|
||||||
|
table->chain = g_malloc0(sizeof(MdbIndexChain));
|
||||||
|
table->mdbidx = mdb_clone_handle(mdb);
|
||||||
|
mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
|
||||||
|
}
|
||||||
|
int
|
||||||
|
mdb_update_index(MdbTableDef *table, MdbIndex *idx, int num_fields, MdbField *fields)
|
||||||
|
{
|
||||||
|
int idx_xref[16];
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < idx->num_keys; i++) {
|
||||||
|
for (j = 0; j < num_fields; j++) {
|
||||||
|
// key_col_num is 1 based, can't remember why though
|
||||||
|
if (fields[j].colnum == idx->key_col_num[i]-1)
|
||||||
|
idx_xref[i] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < idx->num_keys; i++) {
|
||||||
|
fprintf(stdout, "key col %d (%d) is mapped to field %d (%d %d)\n",
|
||||||
|
i, idx->key_col_num[i], idx_xref[i], fields[idx_xref[i]].colnum,
|
||||||
|
fields[idx_xref[i]].siz);
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_fields; i++) {
|
||||||
|
fprintf(stdout, "%d (%d %d)\n",
|
||||||
|
i, fields[i].colnum,
|
||||||
|
fields[i].siz);
|
||||||
|
}
|
||||||
|
//mdb_find_leaf_pg();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
|
mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
|
||||||
{
|
{
|
||||||
@@ -330,11 +369,39 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mdb_add_row_to_pg(table, row_buffer, new_row_size);
|
||||||
|
|
||||||
|
#if MDB_DEBUG_WRITE
|
||||||
|
buffer_dump(mdb->pg_buf, 0, 39);
|
||||||
|
buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
|
||||||
|
fprintf(stdout, "writing page %d\n", pgnum);
|
||||||
|
#endif
|
||||||
|
if (!mdb_write_pg(mdb, pgnum)) {
|
||||||
|
fprintf(stderr, "write failed! exiting...\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdb_update_indexes(table, num_fields, fields);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Assumes caller has verfied space is available on page and adds the new
|
||||||
|
* row to the current pg_buf.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size)
|
||||||
|
{
|
||||||
|
unsigned char *new_pg;
|
||||||
|
int num_rows, i, pos, row_start, row_end, row_size;
|
||||||
|
MdbCatalogEntry *entry = table->entry;
|
||||||
|
MdbHandle *mdb = entry->mdb;
|
||||||
|
MdbFormatConstants *fmt = mdb->fmt;
|
||||||
|
|
||||||
new_pg = mdb_new_data_pg(entry);
|
new_pg = mdb_new_data_pg(entry);
|
||||||
|
|
||||||
num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
|
num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
|
||||||
pos = mdb->fmt->pg_size;
|
pos = mdb->fmt->pg_size;
|
||||||
|
|
||||||
|
/* copy existing rows */
|
||||||
for (i=0;i<num_rows;i++) {
|
for (i=0;i<num_rows;i++) {
|
||||||
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
|
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
|
||||||
row_end = mdb_find_end_of_row(mdb, i);
|
row_end = mdb_find_end_of_row(mdb, i);
|
||||||
@@ -347,19 +414,19 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
|
|||||||
/* add our new row */
|
/* add our new row */
|
||||||
pos -= new_row_size;
|
pos -= new_row_size;
|
||||||
memcpy(&new_pg[pos], row_buffer, new_row_size);
|
memcpy(&new_pg[pos], row_buffer, new_row_size);
|
||||||
|
/* add row to the row offset table */
|
||||||
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (num_rows*2), pos);
|
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (num_rows*2), pos);
|
||||||
|
|
||||||
|
/* update number rows on this page */
|
||||||
num_rows++;
|
num_rows++;
|
||||||
_mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
|
_mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
|
||||||
|
|
||||||
|
/* copy new page over old */
|
||||||
memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
|
memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
|
||||||
g_free(new_pg);
|
g_free(new_pg);
|
||||||
#if MDB_DEBUG_WRITE
|
|
||||||
buffer_dump(mdb->pg_buf, 0, 39);
|
|
||||||
buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mdb_update_indexes(table, num_fields, fields);
|
/* update the freespace */
|
||||||
|
_mdb_put_int16(mdb->pg_buf, 2, mdb_pg_get_freespace(mdb));
|
||||||
}
|
}
|
||||||
int
|
int
|
||||||
mdb_update_row(MdbTableDef *table)
|
mdb_update_row(MdbTableDef *table)
|
||||||
|
|||||||
175
src/sql/mdbsql.c
175
src/sql/mdbsql.c
@@ -418,6 +418,10 @@ MdbSQLSarg *sql_sarg;
|
|||||||
mdb_free_tabledef(sql->cur_table);
|
mdb_free_tabledef(sql->cur_table);
|
||||||
sql->cur_table = NULL;
|
sql->cur_table = NULL;
|
||||||
}
|
}
|
||||||
|
if (sql->kludge_ttable_pg) {
|
||||||
|
g_free(sql->kludge_ttable_pg);
|
||||||
|
sql->kludge_ttable_pg = NULL;
|
||||||
|
}
|
||||||
for (i=0;i<sql->num_columns;i++) {
|
for (i=0;i<sql->num_columns;i++) {
|
||||||
c = g_ptr_array_index(sql->columns,i);
|
c = g_ptr_array_index(sql->columns,i);
|
||||||
mdb_sql_free_column(c);
|
mdb_sql_free_column(c);
|
||||||
@@ -476,9 +480,18 @@ int vlen;
|
|||||||
}
|
}
|
||||||
void mdb_sql_listtables(MdbSQL *sql)
|
void mdb_sql_listtables(MdbSQL *sql)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
MdbCatalogEntry *entry;
|
MdbCatalogEntry *entry;
|
||||||
MdbHandle *mdb = sql->mdb;
|
MdbHandle *mdb = sql->mdb;
|
||||||
|
MdbField fields[4];
|
||||||
|
int num_fields = 0;
|
||||||
|
char tmpstr[256];
|
||||||
|
unsigned char row_buffer[4096];
|
||||||
|
unsigned char *new_pg;
|
||||||
|
int row_size;
|
||||||
|
MdbTableDef *ttable, *table = NULL;
|
||||||
|
MdbColumn *col, tcol;
|
||||||
|
MdbSQLColumn *sqlcol;
|
||||||
|
|
||||||
if (!mdb) {
|
if (!mdb) {
|
||||||
mdb_sql_error("You must connect to a database first");
|
mdb_sql_error("You must connect to a database first");
|
||||||
@@ -486,36 +499,63 @@ MdbHandle *mdb = sql->mdb;
|
|||||||
}
|
}
|
||||||
mdb_read_catalog (mdb, MDB_TABLE);
|
mdb_read_catalog (mdb, MDB_TABLE);
|
||||||
|
|
||||||
|
ttable = mdb_create_temp_table(mdb, "#listtables");
|
||||||
|
|
||||||
|
memset(&tcol,0,sizeof(MdbColumn));
|
||||||
|
strcpy(tcol.name, "Tables");
|
||||||
|
tcol.col_size = 30;
|
||||||
|
tcol.col_type = MDB_TEXT;
|
||||||
|
tcol.is_fixed = 0;
|
||||||
|
mdb_temp_table_add_col(ttable, &tcol);
|
||||||
|
mdb_sql_add_column(sql, "Tables");
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,0);
|
||||||
|
sqlcol->disp_size = mdb_col_disp_size(&tcol);
|
||||||
|
|
||||||
|
/* blank out the pg_buf */
|
||||||
|
new_pg = mdb_new_data_pg(ttable->entry);
|
||||||
|
memcpy(mdb->pg_buf, new_pg, mdb->fmt->pg_size);
|
||||||
|
g_free(new_pg);
|
||||||
|
|
||||||
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 */
|
/* loop over each entry in the catalog */
|
||||||
for (i=0; i < mdb->num_catalog; i++) {
|
for (i=0; i < mdb->num_catalog; i++) {
|
||||||
entry = g_ptr_array_index (mdb->catalog, i);
|
entry = g_ptr_array_index (mdb->catalog, i);
|
||||||
/* if it's a table */
|
/* if it's a table */
|
||||||
if (entry->object_type == MDB_TABLE) {
|
if (entry->object_type == MDB_TABLE) {
|
||||||
if (strncmp (entry->object_name, "MSys", 4)) {
|
if (strncmp (entry->object_name, "MSys", 4)) {
|
||||||
print_value (entry->object_name,30,1);
|
col = g_ptr_array_index(table->columns,0);
|
||||||
fprintf(stdout,"\n");
|
fields[0].value = entry->object_name;
|
||||||
|
fields[0].siz = strlen(entry->object_name);
|
||||||
|
fields[0].is_fixed = 0;
|
||||||
|
fields[0].is_null = 0;
|
||||||
|
fields[0].start = 0;
|
||||||
|
fields[0].colnum = 0;
|
||||||
|
|
||||||
|
row_size = mdb_pack_row(ttable, row_buffer, 1, &fields);
|
||||||
|
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
||||||
|
ttable->num_rows++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print_break (30,1);
|
sql->kludge_ttable_pg = g_memdup(mdb->pg_buf, mdb->fmt->pg_size);
|
||||||
fprintf(stdout,"\n");
|
sql->cur_table = ttable;
|
||||||
|
|
||||||
}
|
}
|
||||||
void mdb_sql_describe_table(MdbSQL *sql)
|
void mdb_sql_describe_table(MdbSQL *sql)
|
||||||
{
|
{
|
||||||
MdbTableDef *table = NULL;
|
MdbTableDef *ttable, *table = NULL;
|
||||||
MdbSQLTable *sql_tab;
|
MdbSQLTable *sql_tab;
|
||||||
MdbCatalogEntry *entry;
|
MdbCatalogEntry *entry;
|
||||||
MdbHandle *mdb = sql->mdb;
|
MdbHandle *mdb = sql->mdb;
|
||||||
MdbColumn *col;
|
MdbColumn *col, tcol;
|
||||||
int i;
|
MdbSQLColumn *sqlcol;
|
||||||
char colsize[11];
|
int i;
|
||||||
|
char colsize[11];
|
||||||
|
MdbField fields[4];
|
||||||
|
int num_fields = 0;
|
||||||
|
char tmpstr[256];
|
||||||
|
unsigned char row_buffer[4096];
|
||||||
|
unsigned char *new_pg;
|
||||||
|
int row_size;
|
||||||
|
|
||||||
if (!mdb) {
|
if (!mdb) {
|
||||||
mdb_sql_error("You must connect to a database first");
|
mdb_sql_error("You must connect to a database first");
|
||||||
@@ -543,35 +583,78 @@ char colsize[11];
|
|||||||
|
|
||||||
mdb_read_columns(table);
|
mdb_read_columns(table);
|
||||||
|
|
||||||
print_break (30,1);
|
ttable = mdb_create_temp_table(mdb, "#describe");
|
||||||
print_break (20,0);
|
|
||||||
print_break (10,0);
|
memset(&tcol,0,sizeof(MdbColumn));
|
||||||
fprintf(stdout,"\n");
|
strcpy(tcol.name, "Column Name");
|
||||||
print_value ("Column Name",30,1);
|
tcol.col_size = 30;
|
||||||
print_value ("Type",20,0);
|
tcol.col_type = MDB_TEXT;
|
||||||
print_value ("Size",10,0);
|
tcol.is_fixed = 0;
|
||||||
fprintf(stdout,"\n");
|
mdb_temp_table_add_col(ttable, &tcol);
|
||||||
print_break (30,1);
|
mdb_sql_add_column(sql, "Column Name");
|
||||||
print_break (20,0);
|
sqlcol = g_ptr_array_index(sql->columns,0);
|
||||||
print_break (10,0);
|
sqlcol->disp_size = mdb_col_disp_size(&tcol);
|
||||||
fprintf(stdout,"\n");
|
|
||||||
|
memset(&tcol,0,sizeof(MdbColumn));
|
||||||
|
strcpy(tcol.name, "Type");
|
||||||
|
tcol.col_size = 20;
|
||||||
|
tcol.col_type = MDB_TEXT;
|
||||||
|
tcol.is_fixed = 0;
|
||||||
|
mdb_temp_table_add_col(ttable, &tcol);
|
||||||
|
mdb_sql_add_column(sql, "Type");
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,1);
|
||||||
|
sqlcol->disp_size = mdb_col_disp_size(&tcol);
|
||||||
|
|
||||||
|
memset(&tcol,0,sizeof(MdbColumn));
|
||||||
|
strcpy(tcol.name, "Size");
|
||||||
|
tcol.col_size = 10;
|
||||||
|
tcol.col_type = MDB_TEXT;
|
||||||
|
tcol.is_fixed = 0;
|
||||||
|
mdb_temp_table_add_col(ttable, &tcol);
|
||||||
|
mdb_sql_add_column(sql, "Size");
|
||||||
|
sqlcol = g_ptr_array_index(sql->columns,2);
|
||||||
|
sqlcol->disp_size = mdb_col_disp_size(&tcol);
|
||||||
|
|
||||||
|
/* blank out the pg_buf */
|
||||||
|
new_pg = mdb_new_data_pg(ttable->entry);
|
||||||
|
memcpy(mdb->pg_buf, new_pg, mdb->fmt->pg_size);
|
||||||
|
g_free(new_pg);
|
||||||
|
|
||||||
for (i=0;i<table->num_cols;i++) {
|
for (i=0;i<table->num_cols;i++) {
|
||||||
|
|
||||||
col = g_ptr_array_index(table->columns,i);
|
col = g_ptr_array_index(table->columns,i);
|
||||||
|
fields[0].value = col->name;
|
||||||
print_value (col->name,30,1);
|
fields[0].siz = strlen(col->name);
|
||||||
print_value (mdb_get_coltype_string(mdb->default_backend, col->col_type),20,0);
|
fields[0].is_fixed = 0;
|
||||||
|
fields[0].is_null = 0;
|
||||||
|
fields[0].start = 0;
|
||||||
|
fields[0].colnum = 0;
|
||||||
|
|
||||||
|
strcpy(tmpstr, mdb_get_coltype_string(mdb->default_backend, col->col_type));
|
||||||
|
fields[1].value = tmpstr;
|
||||||
|
fields[1].siz = strlen(tmpstr);
|
||||||
|
fields[1].is_fixed = 0;
|
||||||
|
fields[1].is_null = 0;
|
||||||
|
fields[1].start = 0;
|
||||||
|
fields[1].colnum = 1;
|
||||||
|
|
||||||
sprintf(colsize,"%d",col->col_size);
|
sprintf(colsize,"%d",col->col_size);
|
||||||
print_value (colsize,10,0);
|
fields[2].value = colsize;
|
||||||
fprintf(stdout,"\n");
|
fields[2].siz = strlen(colsize);
|
||||||
|
fields[2].is_fixed = 0;
|
||||||
|
fields[2].is_null = 0;
|
||||||
|
fields[2].start = 0;
|
||||||
|
fields[2].colnum = 2;
|
||||||
|
|
||||||
|
row_size = mdb_pack_row(ttable, row_buffer, 3, &fields);
|
||||||
|
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
||||||
|
ttable->num_rows++;
|
||||||
}
|
}
|
||||||
print_break (30,1);
|
|
||||||
print_break (20,0);
|
|
||||||
print_break (10,0);
|
|
||||||
fprintf(stdout,"\n");
|
|
||||||
|
|
||||||
/* the column and table names are no good now */
|
/* the column and table names are no good now */
|
||||||
mdb_sql_reset(sql);
|
//mdb_sql_reset(sql);
|
||||||
|
sql->kludge_ttable_pg = g_memdup(mdb->pg_buf, mdb->fmt->pg_size);
|
||||||
|
sql->cur_table = ttable;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdb_sql_find_sargcol(MdbSargNode *node, gpointer data)
|
int mdb_sql_find_sargcol(MdbSargNode *node, gpointer data)
|
||||||
|
|||||||
@@ -95,18 +95,30 @@ MdbColumn *col;
|
|||||||
}
|
}
|
||||||
void read_to_row(MdbTableDef *table, char *sargname)
|
void read_to_row(MdbTableDef *table, char *sargname)
|
||||||
{
|
{
|
||||||
MdbSarg sarg;
|
static MdbSargNode sarg;
|
||||||
char *sargcol, *sargop, *sargval;
|
char *sargcol, *sargop, *sargval;
|
||||||
|
int i;
|
||||||
|
MdbColumn *col;
|
||||||
|
|
||||||
|
|
||||||
if (sargname) {
|
if (sargname) {
|
||||||
sargcol = strtok(sargname," ");
|
sargcol = strtok(sargname," ");
|
||||||
|
for (i=0;i<table->num_cols;i++) {
|
||||||
|
col=g_ptr_array_index(table->columns,i);
|
||||||
|
if (!strcasecmp(col->name, (char *)sargcol)) {
|
||||||
|
sarg.col = col;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sargop = strtok(NULL," ");
|
sargop = strtok(NULL," ");
|
||||||
sargval = strtok(NULL," ");
|
sargval = strtok(NULL," ");
|
||||||
printf("col %s op %s val %s\n",sargcol,sargop,sargval);
|
printf("col %s op %s val %s\n",sargcol,sargop,sargval);
|
||||||
sarg.op = MDB_EQUAL; /* only support = for now, sorry */
|
sarg.op = MDB_EQUAL; /* only support = for now, sorry */
|
||||||
sarg.value.i = atoi(sargval);
|
sarg.value.i = atoi(sargval);
|
||||||
mdb_add_sarg_by_name(table, sargcol, &sarg);
|
table->sarg_tree = &sarg;
|
||||||
|
|
||||||
|
// mdb_add_sarg_by_name(table, sargcol, &sarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
mdb_rewind_table(table);
|
mdb_rewind_table(table);
|
||||||
|
|||||||
Reference in New Issue
Block a user