mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-19 02:27:55 +08:00
patch from Jeff Smith for mdb_pack_row4() and null mask fix
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
Thu Mar 4 23:24:27 EST 2004 Brian Bruns <brian@bruns.com>
|
||||||
|
* include/mdbtools.h: add prototype for mdb_index_find_next()
|
||||||
|
* src/libmdb/write.c: add mdb_pack_row4() (Jeff Smith). Fix null mask order (Jeff, me)
|
||||||
|
* src/sql/mdbsql.c: convert list tables/describe table to ucs2 for jet4 db's
|
||||||
|
|
||||||
Thu Mar 4 15:30:21 EST 2004 Brian Bruns <brian@bruns.com>
|
Thu Mar 4 15:30:21 EST 2004 Brian Bruns <brian@bruns.com>
|
||||||
* src/odbc/Makefile.am: add newer files to driver
|
* src/odbc/Makefile.am: add newer files to driver
|
||||||
* src/libmdb/options.c: add debug_row option
|
* src/libmdb/options.c: add debug_row option
|
||||||
|
@@ -469,6 +469,7 @@ extern int mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg);
|
|||||||
extern int mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row);
|
extern int mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row);
|
||||||
extern void mdb_index_hash_text(guchar *text, guchar *hash);
|
extern void mdb_index_hash_text(guchar *text, guchar *hash);
|
||||||
extern void mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table);
|
extern void mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table);
|
||||||
|
extern int mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row);
|
||||||
|
|
||||||
/* stats.c */
|
/* stats.c */
|
||||||
extern void mdb_stats_on(MdbHandle *mdb);
|
extern void mdb_stats_on(MdbHandle *mdb);
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int mdb_copy_index_pg(MdbTableDef *table, MdbIndexPage *ipg);
|
||||||
|
|
||||||
void
|
void
|
||||||
_mdb_put_int16(unsigned char *buf, guint32 offset, guint32 value)
|
_mdb_put_int16(unsigned char *buf, guint32 offset, guint32 value)
|
||||||
{
|
{
|
||||||
@@ -84,14 +86,14 @@ MdbIndex *idx;
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int
|
static int
|
||||||
mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
||||||
{
|
{
|
||||||
MdbCatalogEntry *entry = table->entry;
|
MdbCatalogEntry *entry = table->entry;
|
||||||
MdbHandle *mdb = entry->mdb;
|
MdbHandle *mdb = entry->mdb;
|
||||||
MdbColumn *col;
|
MdbColumn *col;
|
||||||
int i, j;
|
int i;
|
||||||
int var_cols = 0, fixed_cols = 0, num_cols, totcols = 0;
|
int var_cols = 0, fixed_cols = 0, num_cols;
|
||||||
int var_cols_found, fixed_cols_found, var_entry_pos;
|
int var_cols_found, fixed_cols_found, var_entry_pos;
|
||||||
int col_start, next_col;
|
int col_start, next_col;
|
||||||
unsigned char *nullmask;
|
unsigned char *nullmask;
|
||||||
@@ -126,17 +128,17 @@ mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
|||||||
col = g_ptr_array_index (table->columns, i);
|
col = g_ptr_array_index (table->columns, i);
|
||||||
if (mdb_is_fixed_col(col)) {
|
if (mdb_is_fixed_col(col)) {
|
||||||
fixed_cols++;
|
fixed_cols++;
|
||||||
fields[totcols].colnum = i;
|
fields[i].colnum = i;
|
||||||
fields[totcols].siz = col->col_size;
|
fields[i].siz = col->col_size;
|
||||||
fields[totcols++].is_fixed = 1;
|
fields[i].is_fixed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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);
|
||||||
if (!mdb_is_fixed_col(col)) {
|
if (!mdb_is_fixed_col(col)) {
|
||||||
var_cols++;
|
var_cols++;
|
||||||
fields[totcols].colnum = i;
|
fields[i].colnum = i;
|
||||||
fields[totcols++].is_fixed = 0;
|
fields[i].is_fixed = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,13 +151,12 @@ mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
|||||||
fixed_cols_found = 0;
|
fixed_cols_found = 0;
|
||||||
var_cols_found = 0;
|
var_cols_found = 0;
|
||||||
|
|
||||||
totcols = 0;
|
for (i=0;i<table->num_cols;i++) {
|
||||||
for (j=0;j<table->num_cols;j++) {
|
col = g_ptr_array_index(table->columns,i);
|
||||||
col = g_ptr_array_index(table->columns,j);
|
|
||||||
if (mdb_is_fixed_col(col) && fixed_cols_found <= fixed_cols) {
|
if (mdb_is_fixed_col(col) && fixed_cols_found <= fixed_cols) {
|
||||||
real_offset += col->col_size;
|
real_offset += col->col_size;
|
||||||
fields[totcols].start = row_start + col->fixed_offset + 2;
|
fields[i].start = row_start + col->fixed_offset + 2;
|
||||||
fields[totcols++].value = &mdb->pg_buf[row_start + col->fixed_offset + 2];
|
fields[i].value = &mdb->pg_buf[row_start + col->fixed_offset + 2];
|
||||||
fixed_cols_found++;
|
fixed_cols_found++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,8 +176,8 @@ mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
|||||||
|
|
||||||
col_start = mdb_pg_get_int16(mdb, row_end - 3 - bitmask_sz);
|
col_start = mdb_pg_get_int16(mdb, row_end - 3 - bitmask_sz);
|
||||||
|
|
||||||
for (j=0;j<table->num_cols;j++) {
|
for (i=0;i<table->num_cols;i++) {
|
||||||
col = g_ptr_array_index(table->columns,j);
|
col = g_ptr_array_index(table->columns,i);
|
||||||
if (!mdb_is_fixed_col(col) && ++var_cols_found <= var_cols) {
|
if (!mdb_is_fixed_col(col) && ++var_cols_found <= var_cols) {
|
||||||
if (var_cols_found==var_cols) {
|
if (var_cols_found==var_cols) {
|
||||||
len=eod - col_start;
|
len=eod - col_start;
|
||||||
@@ -191,10 +192,9 @@ mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
|||||||
next_col = mdb_pg_get_int16(mdb, var_entry_pos);
|
next_col = mdb_pg_get_int16(mdb, var_entry_pos);
|
||||||
len = next_col - col_start;
|
len = next_col - col_start;
|
||||||
} /* if found==var_cols */
|
} /* if found==var_cols */
|
||||||
while (len<0) len+=256;
|
fields[i].start = row_start + col_start;
|
||||||
fields[totcols].start = row_start + col_start;
|
fields[i].value = &mdb->pg_buf[row_start +col_start];
|
||||||
fields[totcols].value = &mdb->pg_buf[row_start +col_start];
|
fields[i].siz = len;
|
||||||
fields[totcols++].siz = len;
|
|
||||||
col_start += len;
|
col_start += len;
|
||||||
} /* if !fixed */
|
} /* if !fixed */
|
||||||
} /* for */
|
} /* for */
|
||||||
@@ -205,32 +205,52 @@ mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
|||||||
static int
|
static int
|
||||||
mdb_crack_row3(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
mdb_crack_row3(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
||||||
{
|
{
|
||||||
MdbCatalogEntry *entry = table->entry;
|
MdbCatalogEntry *entry = table->entry;
|
||||||
MdbHandle *mdb = entry->mdb;
|
MdbHandle *mdb = entry->mdb;
|
||||||
MdbColumn *col;
|
MdbColumn *col;
|
||||||
int i, j;
|
int i;
|
||||||
int var_cols = 0, fixed_cols = 0, num_cols, totcols = 0;
|
int var_cols = 0, fixed_cols = 0, num_cols;
|
||||||
int var_cols_found, fixed_cols_found, var_entry_pos;
|
int var_cols_found, fixed_cols_found, var_entry_pos;
|
||||||
int col_start;
|
int col_start;
|
||||||
unsigned char *nullmask;
|
unsigned char *nullmask;
|
||||||
int bitmask_sz;
|
int bitmask_sz;
|
||||||
int byte_num, bit_num;
|
int byte_num, bit_num;
|
||||||
int num_of_jumps = 0, jumps_used = 0;
|
int num_of_jumps = 0, jumps_used = 0;
|
||||||
int eod, len; /* end of data */
|
int eod, len; /* end of data */
|
||||||
|
int row_pos;
|
||||||
|
|
||||||
|
if (mdb_get_option(MDB_DEBUG_ROW)) {
|
||||||
|
buffer_dump(mdb->pg_buf, row_start, row_end+1);
|
||||||
|
}
|
||||||
|
|
||||||
num_cols = mdb->pg_buf[row_start];
|
num_cols = mdb->pg_buf[row_start];
|
||||||
|
|
||||||
if (num_cols != table->num_cols) {
|
if (num_cols != table->num_cols) {
|
||||||
fprintf(stderr,"WARNING: number of table columns does not match number of row columns, strange results may occur\n");
|
fprintf(stderr,"WARNING: number of table columns does not match number of row columns, strange results may occur\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* compute nulls first to help with fixed colnum's */
|
||||||
|
bitmask_sz = (num_cols - 1) / 8 + 1;
|
||||||
|
nullmask = &mdb->pg_buf[row_end - bitmask_sz + 1];
|
||||||
|
|
||||||
|
for (i=0;i<table->num_cols;i++) {
|
||||||
|
col = g_ptr_array_index (table->columns, i);
|
||||||
|
row_pos = col->row_col_num;
|
||||||
|
byte_num = row_pos / 8;
|
||||||
|
bit_num = row_pos % 8;
|
||||||
|
/* logic on nulls is reverse, 1 is not null, 0 is null */
|
||||||
|
fields[i].is_null = nullmask[byte_num] & 1 << bit_num ? 0 : 1;
|
||||||
|
//printf("col %d is %s\n", i, fields[i].is_null ? "null" : "not null");
|
||||||
|
}
|
||||||
|
|
||||||
/* how many fixed cols? */
|
/* how many fixed cols? */
|
||||||
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);
|
||||||
if (mdb_is_fixed_col(col)) {
|
if (mdb_is_fixed_col(col)) {
|
||||||
fixed_cols++;
|
fixed_cols++;
|
||||||
fields[totcols].colnum = i;
|
fields[i].colnum = i;
|
||||||
fields[totcols].siz = col->col_size;
|
fields[i].siz = col->col_size;
|
||||||
fields[totcols++].is_fixed = 1;
|
fields[i].is_fixed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* how many var cols? */
|
/* how many var cols? */
|
||||||
@@ -238,22 +258,11 @@ int eod, len; /* end of data */
|
|||||||
col = g_ptr_array_index (table->columns, i);
|
col = g_ptr_array_index (table->columns, i);
|
||||||
if (!mdb_is_fixed_col(col)) {
|
if (!mdb_is_fixed_col(col)) {
|
||||||
var_cols++;
|
var_cols++;
|
||||||
fields[totcols].colnum = i;
|
fields[i].colnum = i;
|
||||||
fields[totcols++].is_fixed = 0;
|
fields[i].is_fixed = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmask_sz = (num_cols - 1) / 8 + 1;
|
|
||||||
nullmask = &mdb->pg_buf[row_end - bitmask_sz + 1];
|
|
||||||
|
|
||||||
for (i=0;i<num_cols;i++) {
|
|
||||||
byte_num = i / 8;
|
|
||||||
bit_num = i % 8;
|
|
||||||
/* logic on nulls is reverse, 1 is not null, 0 is null */
|
|
||||||
fields[i].is_null = nullmask[byte_num] & 1 << bit_num ? 0 : 1;
|
|
||||||
//printf("col %d is %s\n", i, fields[i].is_null ? "null" : "not null");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the end of data pointer */
|
/* find the end of data pointer */
|
||||||
eod = mdb->pg_buf[row_end-1-var_cols-bitmask_sz];
|
eod = mdb->pg_buf[row_end-1-var_cols-bitmask_sz];
|
||||||
|
|
||||||
@@ -264,13 +273,12 @@ int eod, len; /* end of data */
|
|||||||
fixed_cols_found = 0;
|
fixed_cols_found = 0;
|
||||||
var_cols_found = 0;
|
var_cols_found = 0;
|
||||||
|
|
||||||
totcols = 0;
|
|
||||||
/* loop through fixed columns and add values to fields[] */
|
/* loop through fixed columns and add values to fields[] */
|
||||||
for (j=0;j<table->num_cols;j++) {
|
for (i=0;i<table->num_cols;i++) {
|
||||||
col = g_ptr_array_index(table->columns,j);
|
col = g_ptr_array_index(table->columns,i);
|
||||||
if (mdb_is_fixed_col(col) && ++fixed_cols_found <= fixed_cols) {
|
if (mdb_is_fixed_col(col) && ++fixed_cols_found <= fixed_cols) {
|
||||||
fields[totcols].start = row_start + col_start;
|
fields[i].start = row_start + col_start;
|
||||||
fields[totcols++].value = &mdb->pg_buf[row_start + col_start];
|
fields[i].value = &mdb->pg_buf[row_start + col_start];
|
||||||
if (col->col_type != MDB_BOOL)
|
if (col->col_type != MDB_BOOL)
|
||||||
col_start += col->col_size;
|
col_start += col->col_size;
|
||||||
}
|
}
|
||||||
@@ -298,8 +306,8 @@ int eod, len; /* end of data */
|
|||||||
/* col_start is now the offset to the first variable length field */
|
/* col_start is now the offset to the first variable length field */
|
||||||
col_start = mdb->pg_buf[col_ptr];
|
col_start = mdb->pg_buf[col_ptr];
|
||||||
|
|
||||||
for (j=0;j<table->num_cols;j++) {
|
for (i=0;i<table->num_cols;i++) {
|
||||||
col = g_ptr_array_index(table->columns,j);
|
col = g_ptr_array_index(table->columns,i);
|
||||||
/* if it's a var_col and we aren't looking at a column
|
/* if it's a var_col and we aren't looking at a column
|
||||||
* added after this row was created */
|
* added after this row was created */
|
||||||
if (!mdb_is_fixed_col(col) && ++var_cols_found <= var_cols) {
|
if (!mdb_is_fixed_col(col) && ++var_cols_found <= var_cols) {
|
||||||
@@ -327,9 +335,9 @@ int eod, len; /* end of data */
|
|||||||
len=mdb->pg_buf[var_entry_pos] - mdb->pg_buf[var_entry_pos+1];
|
len=mdb->pg_buf[var_entry_pos] - mdb->pg_buf[var_entry_pos+1];
|
||||||
} /* if found==var_cols */
|
} /* if found==var_cols */
|
||||||
while (len<0) len+=256;
|
while (len<0) len+=256;
|
||||||
fields[totcols].start = row_start + col_start;
|
fields[i].start = row_start + col_start;
|
||||||
fields[totcols].value = &mdb->pg_buf[row_start +col_start];
|
fields[i].value = &mdb->pg_buf[row_start +col_start];
|
||||||
fields[totcols++].siz = len;
|
fields[i].siz = len;
|
||||||
col_start += len;
|
col_start += len;
|
||||||
} /* if !fixed */
|
} /* if !fixed */
|
||||||
} /* for */
|
} /* for */
|
||||||
@@ -349,17 +357,45 @@ MdbHandle *mdb = entry->mdb;
|
|||||||
return mdb_crack_row3(table, row_start, row_end, fields);
|
return mdb_crack_row3(table, row_start, row_end, fields);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mdb_pack_null_mask(unsigned char *buffer, int num_fields, MdbField *fields)
|
||||||
|
{
|
||||||
|
int pos = 0, bit = 0, byte = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* 'Not null' bitmap */
|
||||||
|
for (i=0; i<num_fields; i++) {
|
||||||
|
/* column is null if bit is clear (0) */
|
||||||
|
if (!fields[i].is_null) {
|
||||||
|
byte |= 1 << bit;
|
||||||
|
//printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
|
||||||
|
}
|
||||||
|
bit++;
|
||||||
|
if (bit==8) {
|
||||||
|
buffer[pos++] = byte;
|
||||||
|
bit = byte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* if we've written any bits to the current byte, flush it */
|
||||||
|
if (bit)
|
||||||
|
buffer[pos++] = byte;
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
/* fields must be ordered with fixed columns first, then vars, subsorted by
|
/* fields must be ordered with fixed columns first, then vars, subsorted by
|
||||||
* column number */
|
* column number */
|
||||||
int
|
static int
|
||||||
mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, int num_fields, MdbField *fields)
|
mdb_pack_row4(MdbTableDef *table, unsigned char *row_buffer, int num_fields, MdbField *fields)
|
||||||
{
|
{
|
||||||
int pos = 0;
|
unsigned int pos = 0;
|
||||||
int var_cols = 0;
|
unsigned int var_cols = 0;
|
||||||
unsigned char bit, byte;
|
unsigned int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
row_buffer[pos++] = num_fields;
|
row_buffer[pos++] = num_fields & 0xff;
|
||||||
|
row_buffer[pos++] = (num_fields >> 8) & 0xff;
|
||||||
|
|
||||||
|
/* Fixed length columns */
|
||||||
for (i=0;i<num_fields;i++) {
|
for (i=0;i<num_fields;i++) {
|
||||||
if (fields[i].is_fixed) {
|
if (fields[i].is_fixed) {
|
||||||
fields[i].offset = pos;
|
fields[i].offset = pos;
|
||||||
@@ -367,6 +403,7 @@ int i;
|
|||||||
pos += fields[i].siz;
|
pos += fields[i].siz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Variable length columns */
|
||||||
for (i=0;i<num_fields;i++) {
|
for (i=0;i<num_fields;i++) {
|
||||||
if (!fields[i].is_fixed) {
|
if (!fields[i].is_fixed) {
|
||||||
var_cols++;
|
var_cols++;
|
||||||
@@ -375,40 +412,75 @@ int i;
|
|||||||
pos += fields[i].siz;
|
pos += fields[i].siz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* EOD */
|
||||||
|
row_buffer[pos] = pos & 0xff;
|
||||||
|
row_buffer[pos+1] = (pos >> 8) & 0xff;
|
||||||
|
pos += 2;
|
||||||
|
|
||||||
|
/* Offsets of the variable-length columns */
|
||||||
|
for (i=num_fields; i>num_fields-var_cols; i--) {
|
||||||
|
row_buffer[pos++] = fields[i-1].offset & 0xff;
|
||||||
|
row_buffer[pos++] = (fields[i-1].offset >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
/* Number of variable-length columns */
|
||||||
|
row_buffer[pos++] = var_cols & 0xff;
|
||||||
|
row_buffer[pos++] = (var_cols >> 8) & 0xff;
|
||||||
|
|
||||||
|
pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mdb_pack_row3(MdbTableDef *table, unsigned char *row_buffer, int num_fields, MdbField *fields)
|
||||||
|
{
|
||||||
|
unsigned int pos = 0;
|
||||||
|
unsigned int var_cols = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
row_buffer[pos++] = num_fields;
|
||||||
|
|
||||||
|
/* Fixed length columns */
|
||||||
|
for (i=0;i<num_fields;i++) {
|
||||||
|
if (fields[i].is_fixed) {
|
||||||
|
fields[i].offset = pos;
|
||||||
|
memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
|
||||||
|
pos += fields[i].siz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Variable length columns */
|
||||||
|
for (i=0;i<num_fields;i++) {
|
||||||
|
if (!fields[i].is_fixed) {
|
||||||
|
var_cols++;
|
||||||
|
fields[i].offset = pos;
|
||||||
|
memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
|
||||||
|
pos += fields[i].siz;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* EOD */
|
/* EOD */
|
||||||
row_buffer[pos] = pos;
|
row_buffer[pos] = pos;
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
for (i=num_fields-1;i>=num_fields - var_cols;i--) {
|
for (i=num_fields-1;i>=(int)(num_fields - var_cols);i--) {
|
||||||
row_buffer[pos++] = fields[i].offset % 256;
|
row_buffer[pos++] = fields[i].offset % 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
row_buffer[pos++] = var_cols;
|
row_buffer[pos++] = var_cols;
|
||||||
|
|
||||||
byte = 0;
|
pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
|
||||||
bit = 0;
|
|
||||||
for (i=0;i<num_fields;i++) {
|
|
||||||
/* column is null if bit is clear (0) */
|
|
||||||
if (!fields[i].is_null) {
|
|
||||||
byte |= 1 << bit;
|
|
||||||
//printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
|
|
||||||
}
|
|
||||||
bit++;
|
|
||||||
if (bit==8) {
|
|
||||||
row_buffer[pos++] = byte;
|
|
||||||
bit=0;
|
|
||||||
byte = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/* if we've written any bits to the current byte, flush it*/
|
|
||||||
if (bit)
|
|
||||||
row_buffer[pos++] = byte;
|
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
int
|
int
|
||||||
|
mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, int num_fields, MdbField *fields)
|
||||||
|
{
|
||||||
|
if (IS_JET4(table->entry->mdb)) {
|
||||||
|
return mdb_pack_row4(table, row_buffer, num_fields, fields);
|
||||||
|
} else {
|
||||||
|
return mdb_pack_row3(table, row_buffer, num_fields, fields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int
|
||||||
mdb_pg_get_freespace(MdbHandle *mdb)
|
mdb_pg_get_freespace(MdbHandle *mdb)
|
||||||
{
|
{
|
||||||
MdbFormatConstants *fmt = mdb->fmt;
|
MdbFormatConstants *fmt = mdb->fmt;
|
||||||
@@ -526,7 +598,6 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
|
|||||||
MdbFormatConstants *fmt = mdb->fmt;
|
MdbFormatConstants *fmt = mdb->fmt;
|
||||||
guint32 pgnum;
|
guint32 pgnum;
|
||||||
guint16 rownum;
|
guint16 rownum;
|
||||||
unsigned char *new_pg;
|
|
||||||
|
|
||||||
if (!mdb->f->writable) {
|
if (!mdb->f->writable) {
|
||||||
fprintf(stderr, "File is not open for writing\n");
|
fprintf(stderr, "File is not open for writing\n");
|
||||||
@@ -732,7 +803,7 @@ int i, pos;
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int
|
static int
|
||||||
mdb_copy_index_pg(MdbTableDef *table, MdbIndexPage *ipg)
|
mdb_copy_index_pg(MdbTableDef *table, MdbIndexPage *ipg)
|
||||||
{
|
{
|
||||||
MdbCatalogEntry *entry = table->entry;
|
MdbCatalogEntry *entry = table->entry;
|
||||||
|
@@ -527,6 +527,27 @@ int vlen;
|
|||||||
}
|
}
|
||||||
fprintf(stdout,"|");
|
fprintf(stdout,"|");
|
||||||
}
|
}
|
||||||
|
static gchar *
|
||||||
|
convert_to_ucs2(MdbHandle *mdb, gchar *text)
|
||||||
|
{
|
||||||
|
gchar *tmpstr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tmpstr = (gchar *) g_malloc((strlen(text)+1)*2);
|
||||||
|
if (IS_JET4(mdb)) {
|
||||||
|
/* sloppily convert to UCS2-LE */
|
||||||
|
for (i=0;i<strlen(text);i++) {
|
||||||
|
tmpstr[i*2]=text[i];
|
||||||
|
tmpstr[i*2+1]=0;
|
||||||
|
}
|
||||||
|
tmpstr[i*2]=0;
|
||||||
|
tmpstr[i*2+1]=0;
|
||||||
|
} else {
|
||||||
|
strcpy(tmpstr, text);
|
||||||
|
}
|
||||||
|
/* caller is responsible for freeing returned value */
|
||||||
|
return tmpstr;
|
||||||
|
}
|
||||||
void mdb_sql_listtables(MdbSQL *sql)
|
void mdb_sql_listtables(MdbSQL *sql)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -536,9 +557,11 @@ void mdb_sql_listtables(MdbSQL *sql)
|
|||||||
unsigned char row_buffer[4096];
|
unsigned char row_buffer[4096];
|
||||||
unsigned char *new_pg;
|
unsigned char *new_pg;
|
||||||
int row_size;
|
int row_size;
|
||||||
MdbTableDef *ttable, *table = NULL;
|
MdbTableDef *ttable;
|
||||||
MdbColumn *col, tcol;
|
MdbColumn tcol;
|
||||||
MdbSQLColumn *sqlcol;
|
MdbSQLColumn *sqlcol;
|
||||||
|
gchar *tmpstr;
|
||||||
|
int tmpsiz;
|
||||||
|
|
||||||
if (!mdb) {
|
if (!mdb) {
|
||||||
mdb_sql_error("You must connect to a database first");
|
mdb_sql_error("You must connect to a database first");
|
||||||
@@ -570,8 +593,10 @@ void mdb_sql_listtables(MdbSQL *sql)
|
|||||||
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)) {
|
||||||
//col = g_ptr_array_index(table->columns,0);
|
//col = g_ptr_array_index(table->columns,0);
|
||||||
fields[0].value = entry->object_name;
|
tmpstr = convert_to_ucs2(mdb, entry->object_name);
|
||||||
fields[0].siz = strlen(entry->object_name);
|
tmpsiz = IS_JET4(mdb) ? strlen(entry->object_name)*2 : strlen(entry->object_name);
|
||||||
|
fields[0].value = tmpstr;
|
||||||
|
fields[0].siz = tmpsiz;
|
||||||
fields[0].is_fixed = 0;
|
fields[0].is_fixed = 0;
|
||||||
fields[0].is_null = 0;
|
fields[0].is_null = 0;
|
||||||
fields[0].start = 0;
|
fields[0].start = 0;
|
||||||
@@ -580,6 +605,7 @@ void mdb_sql_listtables(MdbSQL *sql)
|
|||||||
row_size = mdb_pack_row(ttable, row_buffer, 1, fields);
|
row_size = mdb_pack_row(ttable, row_buffer, 1, fields);
|
||||||
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
||||||
ttable->num_rows++;
|
ttable->num_rows++;
|
||||||
|
g_free(tmpstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -596,12 +622,13 @@ void mdb_sql_describe_table(MdbSQL *sql)
|
|||||||
MdbColumn *col, tcol;
|
MdbColumn *col, tcol;
|
||||||
MdbSQLColumn *sqlcol;
|
MdbSQLColumn *sqlcol;
|
||||||
int i;
|
int i;
|
||||||
char colsize[11];
|
|
||||||
MdbField fields[4];
|
MdbField fields[4];
|
||||||
char tmpstr[256];
|
char tmpstr[256];
|
||||||
unsigned char row_buffer[4096];
|
unsigned char row_buffer[4096];
|
||||||
unsigned char *new_pg;
|
unsigned char *new_pg;
|
||||||
int row_size;
|
int row_size;
|
||||||
|
gchar *col_name, *col_type, *col_size;
|
||||||
|
int tmpsiz;
|
||||||
|
|
||||||
if (!mdb) {
|
if (!mdb) {
|
||||||
mdb_sql_error("You must connect to a database first");
|
mdb_sql_error("You must connect to a database first");
|
||||||
@@ -669,24 +696,30 @@ void mdb_sql_describe_table(MdbSQL *sql)
|
|||||||
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;
|
col_name = convert_to_ucs2(mdb, col->name);
|
||||||
fields[0].siz = strlen(col->name);
|
tmpsiz = IS_JET4(mdb) ? strlen(col->name)*2 : strlen(col->name);
|
||||||
|
fields[0].value = col_name;
|
||||||
|
fields[0].siz = tmpsiz;
|
||||||
fields[0].is_fixed = 0;
|
fields[0].is_fixed = 0;
|
||||||
fields[0].is_null = 0;
|
fields[0].is_null = 0;
|
||||||
fields[0].start = 0;
|
fields[0].start = 0;
|
||||||
fields[0].colnum = 0;
|
fields[0].colnum = 0;
|
||||||
|
|
||||||
strcpy(tmpstr, mdb_get_coltype_string(mdb->default_backend, col->col_type));
|
strcpy(tmpstr, mdb_get_coltype_string(mdb->default_backend, col->col_type));
|
||||||
fields[1].value = tmpstr;
|
col_type = convert_to_ucs2(mdb, tmpstr);
|
||||||
fields[1].siz = strlen(tmpstr);
|
tmpsiz = IS_JET4(mdb) ? strlen(tmpstr)*2 : strlen(tmpstr);
|
||||||
|
fields[1].value = col_type;
|
||||||
|
fields[1].siz = tmpsiz;
|
||||||
fields[1].is_fixed = 0;
|
fields[1].is_fixed = 0;
|
||||||
fields[1].is_null = 0;
|
fields[1].is_null = 0;
|
||||||
fields[1].start = 0;
|
fields[1].start = 0;
|
||||||
fields[1].colnum = 1;
|
fields[1].colnum = 1;
|
||||||
|
|
||||||
sprintf(colsize,"%d",col->col_size);
|
sprintf(tmpstr,"%d",col->col_size);
|
||||||
fields[2].value = colsize;
|
col_size = convert_to_ucs2(mdb, tmpstr);
|
||||||
fields[2].siz = strlen(colsize);
|
tmpsiz = IS_JET4(mdb) ? strlen(tmpstr)*2 : strlen(tmpstr);
|
||||||
|
fields[2].value = col_size;
|
||||||
|
fields[2].siz = tmpsiz;
|
||||||
fields[2].is_fixed = 0;
|
fields[2].is_fixed = 0;
|
||||||
fields[2].is_null = 0;
|
fields[2].is_null = 0;
|
||||||
fields[2].start = 0;
|
fields[2].start = 0;
|
||||||
@@ -694,6 +727,9 @@ void mdb_sql_describe_table(MdbSQL *sql)
|
|||||||
|
|
||||||
row_size = mdb_pack_row(ttable, row_buffer, 3, fields);
|
row_size = mdb_pack_row(ttable, row_buffer, 3, fields);
|
||||||
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
||||||
|
g_free(col_name);
|
||||||
|
g_free(col_type);
|
||||||
|
g_free(col_size);
|
||||||
ttable->num_rows++;
|
ttable->num_rows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user