mirror of
https://github.com/mdbtools/mdbtools.git
synced 2026-03-10 00:20:54 +08:00
Patches from Brent Johnson for double, off page memo, and big endian support
This commit is contained in:
@@ -13,7 +13,7 @@ mandir = $(exec_prefix)/man/man1
|
||||
|
||||
CC = gcc
|
||||
CPPFLAGS =
|
||||
CFLAGS = $(CPPFLAG) -g -O2
|
||||
CFLAGS = $(CPPFLAG) -g -O2 -DHW_LITTLE_ENDIAN
|
||||
LDFLAGS =
|
||||
LIBS =
|
||||
INSTALL= @INSTALL@
|
||||
@@ -31,7 +31,7 @@ clean:
|
||||
rm -f core *.o *.a
|
||||
|
||||
.c.o:
|
||||
$(CC) -g -c $< $(INC)
|
||||
$(CC) $(CFLAGS) -g -c $< $(INC)
|
||||
|
||||
install:
|
||||
@for lib in $(LIBLIST); do \
|
||||
@@ -44,3 +44,13 @@ uninstall:
|
||||
echo " copying $$lib to $(libdir)"; \
|
||||
rm -f $(libdir)/$$lib; \
|
||||
done
|
||||
|
||||
backend.o: backend.c ../include/mdbtools.h
|
||||
catalog.o: catalog.c ../include/mdbtools.h
|
||||
data.o: data.c ../include/mdbtools.h
|
||||
dump.o: dump.c ../include/mdbtools.h
|
||||
file.o: file.c ../include/mdbtools.h
|
||||
kkd.o: kkd.c ../include/mdbtools.h
|
||||
mem.o: mem.c ../include/mdbtools.h
|
||||
table.o: table.c ../include/mdbtools.h
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ clean:
|
||||
rm -f core *.o *.a
|
||||
|
||||
.c.o:
|
||||
$(CC) -g -c $< $(INC)
|
||||
$(CC) $(CFLAGS) -g -c $< $(INC)
|
||||
|
||||
install:
|
||||
@for lib in $(LIBLIST); do \
|
||||
@@ -44,3 +44,13 @@ uninstall:
|
||||
echo " copying $$lib to $(libdir)"; \
|
||||
rm -f $(libdir)/$$lib; \
|
||||
done
|
||||
|
||||
backend.o: backend.c ../include/mdbtools.h
|
||||
catalog.o: catalog.c ../include/mdbtools.h
|
||||
data.o: data.c ../include/mdbtools.h
|
||||
dump.o: dump.c ../include/mdbtools.h
|
||||
file.o: file.c ../include/mdbtools.h
|
||||
kkd.o: kkd.c ../include/mdbtools.h
|
||||
mem.o: mem.c ../include/mdbtools.h
|
||||
table.o: table.c ../include/mdbtools.h
|
||||
|
||||
|
||||
@@ -159,11 +159,11 @@ MdbBackend *backend;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
char *mdb_get_relationships(MdbHandle *mdb) {
|
||||
|
||||
static void do_first (MdbHandle *mdb)
|
||||
{
|
||||
int i, j, k;
|
||||
static char text[255];
|
||||
void do_first () {
|
||||
mdb_read_catalog (mdb, MDB_TABLE);
|
||||
|
||||
/* loop over each entry in the catalog */
|
||||
@@ -171,29 +171,32 @@ static char text[255];
|
||||
entry = g_array_index (mdb->catalog, MdbCatalogEntry, i);
|
||||
if ((entry.object_type == MDB_TABLE) &&
|
||||
(strncmp (entry.object_name, "MSysRelationships", 17) == 0))
|
||||
{
|
||||
table = mdb_read_table (&entry);
|
||||
if ( table->num_rows > 0 ) {
|
||||
mdb_read_columns(table);
|
||||
mdb_rewind_table(table);
|
||||
for (k=0;k<table->num_cols;k++) {
|
||||
bound_values[k] = (char *) malloc(256);
|
||||
bound_values[k][0] = '\0';
|
||||
mdb_bind_column(table,k+1,bound_values[k]);
|
||||
}
|
||||
relationships[0] = (char *) malloc(256); /* child column */
|
||||
{
|
||||
table = mdb_read_table (&entry);
|
||||
if ( table->num_rows > 0 ) {
|
||||
mdb_read_columns(table);
|
||||
mdb_rewind_table(table);
|
||||
for (k=0;k<table->num_cols;k++) {
|
||||
bound_values[k] = (char *) malloc(MDB_BIND_SIZE);
|
||||
bound_values[k][0] = '\0';
|
||||
mdb_bind_column(table,k+1,bound_values[k]);
|
||||
}
|
||||
relationships[0] = (char *) malloc(256); /* child column */
|
||||
relationships[1] = (char *) malloc(256); /* child table */
|
||||
relationships[2] = (char *) malloc(256); /* parent column */
|
||||
relationships[3] = (char *) malloc(256); /* parent table */
|
||||
} /* if num_rows > 0 */
|
||||
did_first = 1;
|
||||
return;
|
||||
} /* if MSysRelationships */
|
||||
} /* for */
|
||||
}
|
||||
|
||||
relationships[1] = (char *) malloc(256); /* child table */
|
||||
relationships[2] = (char *) malloc(256); /* parent column
|
||||
*/
|
||||
relationships[3] = (char *) malloc(256); /* parent table */
|
||||
char *mdb_get_relationships(MdbHandle *mdb) {
|
||||
|
||||
int k;
|
||||
static char text[255];
|
||||
|
||||
}
|
||||
did_first = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* generate relationships by "reading" the MSysRelationships table
|
||||
* szColumn contains the column name of the child table
|
||||
@@ -203,7 +206,7 @@ static char text[255];
|
||||
*/
|
||||
sprintf(text,"%c",0);
|
||||
if ( did_first == 0)
|
||||
do_first();
|
||||
do_first(mdb);
|
||||
if (table->cur_row < table->num_rows) {
|
||||
if (mdb_fetch_row(table)) {
|
||||
relationships[0][0] = '\0';
|
||||
@@ -221,19 +224,17 @@ static char text[255];
|
||||
else if (strncmp(col->name,"szReferencedObject",18) == 0)
|
||||
strcpy(relationships[3],bound_values[k]);
|
||||
}
|
||||
if (strncmp(mdb->backend_name,"oracle",6) == 0)
|
||||
sprintf(text,"alter table %s add constraint %s_%s foreign key
|
||||
(%s) references %s(%s)",
|
||||
|
||||
relationships[1],relationships[3],relationships[1],
|
||||
|
||||
relationships[0],relationships[3],relationships[2]);
|
||||
else
|
||||
sprintf(text,"relationships are not supported for
|
||||
%s",mdb->backend_name);
|
||||
if (strncmp(mdb->backend_name,"oracle",6) == 0) {
|
||||
sprintf(text,"alter table %s add constraint %s_%s foreign key (%s) \
|
||||
references %s(%s)",
|
||||
relationships[1],relationships[3],relationships[1],
|
||||
relationships[0],relationships[3],relationships[2]);
|
||||
} else {
|
||||
sprintf(text,"relationships are not supported for %s",
|
||||
mdb->backend_name);
|
||||
} /* else */
|
||||
} /* got a row */
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (k=0;k<table->num_cols;k++) {
|
||||
free(bound_values[k]);
|
||||
}
|
||||
|
||||
@@ -255,10 +255,51 @@ int mdb_is_fixed_col(MdbColumn *col)
|
||||
{
|
||||
return col->is_fixed;
|
||||
}
|
||||
static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
|
||||
{
|
||||
short memo_len;
|
||||
static char text[MDB_BIND_SIZE];
|
||||
|
||||
if (size<MDB_MEMO_OVERHEAD) {
|
||||
return "";
|
||||
} else if (size == MDB_MEMO_OVERHEAD) {
|
||||
/* If the only thing here is the field information, the
|
||||
* data is linked. Go read it from another page.
|
||||
* Question: Do we need to read and evaluate the whole page?
|
||||
* Question: It seems to be the only record on the page. If
|
||||
* it weren't, how do we know which record it is?
|
||||
*
|
||||
* WARNING: Assuming the storage area is at least 2048 bytes!
|
||||
*/
|
||||
|
||||
/* The 16 bit integer at offset 0 is the length of the memo field.
|
||||
* The 16 bit integer at offset 5 is the page it is stored on.
|
||||
*/
|
||||
memo_len = mdb_get_int16(mdb, start);
|
||||
|
||||
if(mdb_read_alt_pg(mdb, mdb_get_int16(mdb, start+5)) != mdb->pg_size) {
|
||||
/* Failed to read */
|
||||
return "";
|
||||
}
|
||||
strncpy(text, &mdb->alt_pg_buf[mdb->pg_size - memo_len], memo_len);
|
||||
return text;
|
||||
} else {
|
||||
strncpy(text, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
|
||||
size - MDB_MEMO_OVERHEAD);
|
||||
text[size - MDB_MEMO_OVERHEAD]='\0';
|
||||
return text;
|
||||
}
|
||||
#if 0
|
||||
strncpy(text, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
|
||||
size - MDB_MEMO_OVERHEAD);
|
||||
text[size - MDB_MEMO_OVERHEAD]='\0';
|
||||
return text;
|
||||
#endif
|
||||
}
|
||||
char *mdb_col_to_string(MdbHandle *mdb, int start, int datatype, int size)
|
||||
{
|
||||
/* FIX ME -- not thread safe */
|
||||
static char text[256];
|
||||
static char text[MDB_BIND_SIZE];
|
||||
|
||||
switch (datatype) {
|
||||
case MDB_BOOL:
|
||||
@@ -273,6 +314,10 @@ static char text[256];
|
||||
sprintf(text,"%ld",mdb_get_int32(mdb, start));
|
||||
return text;
|
||||
break;
|
||||
case MDB_DOUBLE:
|
||||
sprintf(text,"%f",mdb_get_double(mdb, start));
|
||||
return text;
|
||||
break;
|
||||
case MDB_TEXT:
|
||||
if (size<0) {
|
||||
return "";
|
||||
@@ -282,13 +327,7 @@ static char text[256];
|
||||
return text;
|
||||
break;
|
||||
case MDB_MEMO:
|
||||
if (size<MDB_MEMO_OVERHEAD) {
|
||||
return "";
|
||||
}
|
||||
strncpy(text, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
|
||||
size - MDB_MEMO_OVERHEAD);
|
||||
text[size - MDB_MEMO_OVERHEAD]='\0';
|
||||
return text;
|
||||
return mdb_memo_to_string(mdb, start, size);
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "mdbtools.h"
|
||||
|
||||
static size_t _mdb_read_pg(MdbHandle *mdb, unsigned char *pg_buf, unsigned long pg);
|
||||
|
||||
MdbHandle *mdb_open(char *filename)
|
||||
{
|
||||
MdbHandle *mdb;
|
||||
@@ -68,6 +70,22 @@ int j,pos;
|
||||
*/
|
||||
size_t mdb_read_pg(MdbHandle *mdb, unsigned long pg)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = _mdb_read_pg(mdb, mdb->pg_buf, pg);
|
||||
/* kan - reset the cur_pos on a new page read */
|
||||
mdb->cur_pos = 0; /* kan */
|
||||
return len;
|
||||
}
|
||||
size_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = _mdb_read_pg(mdb, mdb->alt_pg_buf, pg);
|
||||
return len;
|
||||
}
|
||||
static size_t _mdb_read_pg(MdbHandle *mdb, unsigned char *pg_buf, unsigned long pg)
|
||||
{
|
||||
size_t len;
|
||||
struct stat status;
|
||||
off_t offset = pg * mdb->pg_size;
|
||||
@@ -78,7 +96,7 @@ off_t offset = pg * mdb->pg_size;
|
||||
return 0;
|
||||
}
|
||||
lseek(mdb->fd, offset, SEEK_SET);
|
||||
len = read(mdb->fd,mdb->pg_buf,mdb->pg_size);
|
||||
len = read(mdb->fd,pg_buf,mdb->pg_size);
|
||||
if (len==-1) {
|
||||
perror("read");
|
||||
return 0;
|
||||
@@ -86,9 +104,7 @@ off_t offset = pg * mdb->pg_size;
|
||||
else if (len<mdb->pg_size) {
|
||||
/* fprintf(stderr,"EOF reached.\n"); */
|
||||
return 0;
|
||||
}
|
||||
/* kan - reset the cur_pos on a new page read */
|
||||
mdb->cur_pos = 0; /* kan */
|
||||
}
|
||||
return len;
|
||||
}
|
||||
int mdb_get_int16(MdbHandle *mdb, int offset)
|
||||
@@ -119,6 +135,27 @@ unsigned char *c;
|
||||
mdb->cur_pos+=4;
|
||||
return l;
|
||||
}
|
||||
double mdb_get_double(MdbHandle *mdb, int offset)
|
||||
{
|
||||
double d, d2;
|
||||
unsigned char *c;
|
||||
int i;
|
||||
|
||||
if (offset <0 || offset+4 > mdb->pg_size) return -1;
|
||||
|
||||
memcpy(&d, &mdb->pg_buf[offset], 8);
|
||||
|
||||
#ifdef HW_BIG_ENDIAN
|
||||
d2 = d;
|
||||
for (i=0; i<sizeof(d); i++) {
|
||||
*(((unsigned char *)&d)+i) =
|
||||
*(((unsigned char *)&d2)+sizeof(d)-1-i);
|
||||
}
|
||||
#endif
|
||||
mdb->cur_pos+=8;
|
||||
return d;
|
||||
|
||||
}
|
||||
int mdb_set_pos(MdbHandle *mdb, int pos)
|
||||
{
|
||||
if (pos<0 || pos >= mdb->pg_size) return 0;
|
||||
|
||||
Reference in New Issue
Block a user