mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-19 10:37:54 +08:00
Add mdb_find_row function
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
Sun Mar 6 22:09:09 CST 2005 Jeff Smith <whydoubt@yahoo.com>
|
Sun Mar 6 22:09:09 CST 2005 Jeff Smith <whydoubt@yahoo.com>
|
||||||
* src/libmdb/table.c: Fix memory leak
|
* src/libmdb/table.c: Fix memory leak
|
||||||
|
* include/mdbtools.h:
|
||||||
|
* src/libmdb/data.c:
|
||||||
|
* src/libmdb/write.c:
|
||||||
|
* src/util/prfreemap.c:
|
||||||
|
* src/util/prindex.c: Add mdb_find_row function
|
||||||
|
|
||||||
Fri Feb 25 23:02:42 CST 2005 Jeff Smith <whydoubt@yahoo.com>
|
Fri Feb 25 23:02:42 CST 2005 Jeff Smith <whydoubt@yahoo.com>
|
||||||
* src/libmdb/money.c: Fix bad declaration
|
* src/libmdb/money.c: Fix bad declaration
|
||||||
|
@@ -443,6 +443,7 @@ extern int mdb_fetch_row(MdbTableDef *table);
|
|||||||
extern int mdb_is_fixed_col(MdbColumn *col);
|
extern int mdb_is_fixed_col(MdbColumn *col);
|
||||||
extern char *mdb_col_to_string(MdbHandle *mdb, unsigned char *buf, int start, int datatype, int size);
|
extern char *mdb_col_to_string(MdbHandle *mdb, unsigned char *buf, int start, int datatype, int size);
|
||||||
extern int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len);
|
extern int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len);
|
||||||
|
extern int mdb_find_row(MdbHandle *mdb, int row, int *start, int *len);
|
||||||
extern int mdb_find_end_of_row(MdbHandle *mdb, int row);
|
extern int mdb_find_end_of_row(MdbHandle *mdb, int row);
|
||||||
extern int mdb_col_fixed_size(MdbColumn *col);
|
extern int mdb_col_fixed_size(MdbColumn *col);
|
||||||
extern int mdb_col_disp_size(MdbColumn *col);
|
extern int mdb_col_disp_size(MdbColumn *col);
|
||||||
|
@@ -96,47 +96,57 @@ int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len)
|
|||||||
if (mdb_read_alt_pg(mdb, pg) != mdb->fmt->pg_size)
|
if (mdb_read_alt_pg(mdb, pg) != mdb->fmt->pg_size)
|
||||||
return 1;
|
return 1;
|
||||||
mdb_swap_pgbuf(mdb);
|
mdb_swap_pgbuf(mdb);
|
||||||
*off = mdb_pg_get_int16(mdb, mdb->fmt->row_count_offset + 2 + (row*2));
|
mdb_find_row(mdb, row, off, len);
|
||||||
*len = mdb_find_end_of_row(mdb, row) - *off + 1;
|
|
||||||
mdb_swap_pgbuf(mdb);
|
mdb_swap_pgbuf(mdb);
|
||||||
*buf = mdb->alt_pg_buf;
|
*buf = mdb->alt_pg_buf;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mdb_find_row(MdbHandle *mdb, int row, int *start, int *len)
|
||||||
|
{
|
||||||
|
int rco = mdb->fmt->row_count_offset;
|
||||||
|
int next_start;
|
||||||
|
|
||||||
|
if (row > 1000) return -1;
|
||||||
|
|
||||||
|
*start = mdb_get_int16(mdb->pg_buf, rco + 2 + row*2);
|
||||||
|
next_start = (row == 0) ? mdb->fmt->pg_size :
|
||||||
|
mdb_get_int16(mdb->pg_buf, rco + row*2) & OFFSET_MASK;
|
||||||
|
*len = next_start - *start;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mdb_find_end_of_row(MdbHandle *mdb, int row)
|
mdb_find_end_of_row(MdbHandle *mdb, int row)
|
||||||
{
|
{
|
||||||
MdbFormatConstants *fmt = mdb->fmt;
|
int rco = mdb->fmt->row_count_offset;
|
||||||
int row_end;
|
int row_end;
|
||||||
|
|
||||||
/* Search the previous "row start" values for the first non-'lookupflag' one.
|
|
||||||
* If we don't find one, then the end of the page is the correct value.
|
|
||||||
*/
|
|
||||||
#if 1
|
#if 1
|
||||||
if (row==0) {
|
if (row > 1000) return -1;
|
||||||
row_end = fmt->pg_size - 1;
|
|
||||||
} else {
|
row_end = (row == 0) ? mdb->fmt->pg_size :
|
||||||
row_end = (mdb_pg_get_int16(mdb, ((fmt->row_count_offset + 2) + (row - 1) * 2)) & OFFSET_MASK) - 1;
|
mdb_get_int16(mdb->pg_buf, rco + row*2) & OFFSET_MASK;
|
||||||
}
|
|
||||||
return row_end;
|
|
||||||
#else
|
#else
|
||||||
|
/* Search the previous "row start" values for the first non-'lookupflag'
|
||||||
|
* one. If we don't find one, then the end of the page is the correct
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
int i, row_start;
|
int i, row_start;
|
||||||
|
|
||||||
|
if (row > 1000) return -1;
|
||||||
|
|
||||||
/* if lookupflag is not set, it's good (deleteflag is ok) */
|
/* if lookupflag is not set, it's good (deleteflag is ok) */
|
||||||
for (i = row - 1; i >= 0; i--) {
|
for (i = row; i > 0; i--) {
|
||||||
row_start = mdb_pg_get_int16(mdb, ((fmt->row_count_offset + 2) + i * 2));
|
row_start = mdb_get_int16(mdb->pg_buf, (rco + i*2));
|
||||||
if (!(row_start & 0x8000)) {
|
if (!(row_start & 0x8000)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == -1) {
|
row_end = (i == 0) ? mdb->fmt->pg_size : row_start & OFFSET_MASK;
|
||||||
row_end = fmt->pg_size - 1;
|
|
||||||
} else {
|
|
||||||
row_end = (row_start & OFFSET_MASK) - 1;
|
|
||||||
}
|
|
||||||
return row_end;
|
|
||||||
#endif
|
#endif
|
||||||
|
return row_end - 1;
|
||||||
}
|
}
|
||||||
int mdb_is_null(unsigned char *null_mask, int col_num)
|
int mdb_is_null(unsigned char *null_mask, int col_num)
|
||||||
{
|
{
|
||||||
@@ -226,7 +236,7 @@ int mdb_read_row(MdbTableDef *table, unsigned int row)
|
|||||||
MdbColumn *col;
|
MdbColumn *col;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int rc;
|
int rc;
|
||||||
int row_start, row_end;
|
int row_start, row_size;
|
||||||
int delflag, lookupflag;
|
int delflag, lookupflag;
|
||||||
MdbField fields[256];
|
MdbField fields[256];
|
||||||
int num_fields;
|
int num_fields;
|
||||||
@@ -234,8 +244,7 @@ int mdb_read_row(MdbTableDef *table, unsigned int row)
|
|||||||
if (table->num_rows == 0)
|
if (table->num_rows == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (row*2));
|
mdb_find_row(mdb, row, &row_start, &row_size);
|
||||||
row_end = mdb_find_end_of_row(mdb, row);
|
|
||||||
|
|
||||||
delflag = lookupflag = 0;
|
delflag = lookupflag = 0;
|
||||||
if (row_start & 0x8000) lookupflag++;
|
if (row_start & 0x8000) lookupflag++;
|
||||||
@@ -243,17 +252,17 @@ int mdb_read_row(MdbTableDef *table, unsigned int row)
|
|||||||
row_start &= OFFSET_MASK; /* remove flags */
|
row_start &= OFFSET_MASK; /* remove flags */
|
||||||
#if MDB_DEBUG
|
#if MDB_DEBUG
|
||||||
fprintf(stdout,"Row %d bytes %d to %d %s %s\n",
|
fprintf(stdout,"Row %d bytes %d to %d %s %s\n",
|
||||||
row, row_start, row_end,
|
row, row_start, row_start + row_size - 1,
|
||||||
lookupflag ? "[lookup]" : "",
|
lookupflag ? "[lookup]" : "",
|
||||||
delflag ? "[delflag]" : "");
|
delflag ? "[delflag]" : "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!table->noskip_del && delflag) {
|
if (!table->noskip_del && delflag) {
|
||||||
row_end = row_start-1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_fields = mdb_crack_row(table, row_start, row_end, fields);
|
num_fields = mdb_crack_row(table, row_start, row_start + row_size - 1,
|
||||||
|
fields);
|
||||||
if (!mdb_test_sargs(table, fields, num_fields)) return 0;
|
if (!mdb_test_sargs(table, fields, num_fields)) return 0;
|
||||||
|
|
||||||
#if MDB_DEBUG
|
#if MDB_DEBUG
|
||||||
@@ -261,7 +270,7 @@ int mdb_read_row(MdbTableDef *table, unsigned int row)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MDB_DEBUG
|
#if MDB_DEBUG
|
||||||
buffer_dump(mdb->pg_buf, row_start, row_end);
|
buffer_dump(mdb->pg_buf, row_start, row_start + row_size - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* take advantage of mdb_crack_row() to clean up binding */
|
/* take advantage of mdb_crack_row() to clean up binding */
|
||||||
|
@@ -593,7 +593,7 @@ guint16
|
|||||||
mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size)
|
mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size)
|
||||||
{
|
{
|
||||||
unsigned char *new_pg;
|
unsigned char *new_pg;
|
||||||
int num_rows, i, pos, row_start, row_end, row_size;
|
int num_rows, i, pos, row_start, row_size;
|
||||||
MdbCatalogEntry *entry = table->entry;
|
MdbCatalogEntry *entry = table->entry;
|
||||||
MdbHandle *mdb = entry->mdb;
|
MdbHandle *mdb = entry->mdb;
|
||||||
MdbFormatConstants *fmt = mdb->fmt;
|
MdbFormatConstants *fmt = mdb->fmt;
|
||||||
@@ -622,9 +622,7 @@ mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_siz
|
|||||||
|
|
||||||
/* copy existing rows */
|
/* 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));
|
mdb_find_row(mdb, i, &row_start, &row_size);
|
||||||
row_end = mdb_find_end_of_row(mdb, i);
|
|
||||||
row_size = row_end - row_start + 1;
|
|
||||||
pos -= row_size;
|
pos -= row_size;
|
||||||
memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
|
memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
|
||||||
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
|
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
|
||||||
@@ -670,9 +668,8 @@ unsigned int num_fields;
|
|||||||
fprintf(stderr, "File is not open for writing\n");
|
fprintf(stderr, "File is not open for writing\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + ((table->cur_row-1)*2));
|
mdb_find_row(mdb, table->cur_row-1, &row_start, &old_row_size);
|
||||||
row_end = mdb_find_end_of_row(mdb, table->cur_row-1);
|
row_end = row_start + old_row_size - 1;
|
||||||
old_row_size = row_end - row_start;
|
|
||||||
|
|
||||||
row_start &= 0x0FFF; /* remove flags */
|
row_start &= 0x0FFF; /* remove flags */
|
||||||
|
|
||||||
@@ -719,58 +716,55 @@ mdb_replace_row(MdbTableDef *table, int row, unsigned char *new_row, int new_row
|
|||||||
{
|
{
|
||||||
MdbCatalogEntry *entry = table->entry;
|
MdbCatalogEntry *entry = table->entry;
|
||||||
MdbHandle *mdb = entry->mdb;
|
MdbHandle *mdb = entry->mdb;
|
||||||
MdbFormatConstants *fmt = mdb->fmt;
|
int pg_size = mdb->fmt->pg_size;
|
||||||
|
int rco = mdb->fmt->row_count_offset;
|
||||||
unsigned char *new_pg;
|
unsigned char *new_pg;
|
||||||
guint16 num_rows;
|
guint16 num_rows;
|
||||||
int row_start, row_end, row_size;
|
int row_start, row_size;
|
||||||
int i, pos;
|
int i, pos;
|
||||||
|
|
||||||
if (mdb_get_option(MDB_DEBUG_WRITE)) {
|
if (mdb_get_option(MDB_DEBUG_WRITE)) {
|
||||||
buffer_dump(mdb->pg_buf, 0, 39);
|
buffer_dump(mdb->pg_buf, 0, 39);
|
||||||
buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
|
buffer_dump(mdb->pg_buf, pg_size - 160, pg_size-1);
|
||||||
}
|
}
|
||||||
mdb_debug(MDB_DEBUG_WRITE,"updating row %d on page %lu", row, (unsigned long) table->cur_phys_pg);
|
mdb_debug(MDB_DEBUG_WRITE,"updating row %d on page %lu", row, (unsigned long) table->cur_phys_pg);
|
||||||
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, rco);
|
||||||
_mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
|
_mdb_put_int16(new_pg, rco, num_rows);
|
||||||
|
|
||||||
pos = mdb->fmt->pg_size;
|
pos = pg_size;
|
||||||
|
|
||||||
/* rows before */
|
/* rows before */
|
||||||
for (i=0;i<row;i++) {
|
for (i=0;i<row;i++) {
|
||||||
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
|
mdb_find_row(mdb, i, &row_start, &row_size);
|
||||||
row_end = mdb_find_end_of_row(mdb, i);
|
|
||||||
row_size = row_end - row_start + 1;
|
|
||||||
pos -= row_size;
|
pos -= row_size;
|
||||||
memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
|
memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
|
||||||
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
|
_mdb_put_int16(new_pg, rco + 2 + i*2, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* our row */
|
/* our row */
|
||||||
pos -= new_row_size;
|
pos -= new_row_size;
|
||||||
memcpy(&new_pg[pos], new_row, new_row_size);
|
memcpy(&new_pg[pos], new_row, new_row_size);
|
||||||
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (row*2), pos);
|
_mdb_put_int16(new_pg, rco + 2 + row*2, pos);
|
||||||
|
|
||||||
/* rows after */
|
/* rows after */
|
||||||
for (i=row+1;i<num_rows;i++) {
|
for (i=row+1;i<num_rows;i++) {
|
||||||
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
|
mdb_find_row(mdb, i, &row_start, &row_size);
|
||||||
row_end = mdb_find_end_of_row(mdb, i);
|
|
||||||
row_size = row_end - row_start + 1;
|
|
||||||
pos -= row_size;
|
pos -= row_size;
|
||||||
memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
|
memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
|
||||||
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
|
_mdb_put_int16(new_pg, rco + 2 + i*2, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* almost done, copy page over current */
|
/* almost done, copy page over current */
|
||||||
memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
|
memcpy(mdb->pg_buf, new_pg, pg_size);
|
||||||
|
|
||||||
g_free(new_pg);
|
g_free(new_pg);
|
||||||
|
|
||||||
_mdb_put_int16(mdb->pg_buf, 2, mdb_pg_get_freespace(mdb));
|
_mdb_put_int16(mdb->pg_buf, 2, mdb_pg_get_freespace(mdb));
|
||||||
if (mdb_get_option(MDB_DEBUG_WRITE)) {
|
if (mdb_get_option(MDB_DEBUG_WRITE)) {
|
||||||
buffer_dump(mdb->pg_buf, 0, 39);
|
buffer_dump(mdb->pg_buf, 0, 39);
|
||||||
buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
|
buffer_dump(mdb->pg_buf, pg_size - 160, pg_size-1);
|
||||||
}
|
}
|
||||||
/* drum roll, please */
|
/* drum roll, please */
|
||||||
if (!mdb_write_pg(mdb, table->cur_phys_pg)) {
|
if (!mdb_write_pg(mdb, table->cur_phys_pg)) {
|
||||||
|
@@ -25,7 +25,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
MdbHandle *mdb;
|
MdbHandle *mdb;
|
||||||
int j;
|
int j;
|
||||||
long int pgnum = 0, row_start, row_end, map_sz;
|
long int pgnum = 0, row_start, map_sz;
|
||||||
int coln = 1;
|
int coln = 1;
|
||||||
unsigned char *map_buf;
|
unsigned char *map_buf;
|
||||||
|
|
||||||
@@ -38,10 +38,9 @@ unsigned char *map_buf;
|
|||||||
mdb = mdb_open(argv[1], MDB_NOFLAGS);
|
mdb = mdb_open(argv[1], MDB_NOFLAGS);
|
||||||
|
|
||||||
mdb_read_pg (mdb, 1);
|
mdb_read_pg (mdb, 1);
|
||||||
row_start = mdb_get_int16(mdb, (mdb->fmt->row_count_offset + 2));
|
mdb_find_row(mdb, 0, &row_start, &map_sz);
|
||||||
row_end = mdb_find_end_of_row(mdb, 0);
|
|
||||||
map_buf = &mdb->pg_buf[row_start];
|
map_buf = &mdb->pg_buf[row_start];
|
||||||
map_sz = row_end - row_start;
|
map_sz --;
|
||||||
/*
|
/*
|
||||||
* trim the end of a type 0 map
|
* trim the end of a type 0 map
|
||||||
*/
|
*/
|
||||||
|
@@ -79,20 +79,18 @@ page_name(int page_type)
|
|||||||
void check_row(MdbHandle *mdb, MdbIndex *idx, guint32 pg, int row, unsigned char *idxrow, int len)
|
void check_row(MdbHandle *mdb, MdbIndex *idx, guint32 pg, int row, unsigned char *idxrow, int len)
|
||||||
{
|
{
|
||||||
MdbField fields[256];
|
MdbField fields[256];
|
||||||
MdbFormatConstants *fmt;
|
|
||||||
unsigned int num_fields, i, j;
|
unsigned int num_fields, i, j;
|
||||||
int row_start, row_end;
|
int row_start, row_size;
|
||||||
MdbColumn *col;
|
MdbColumn *col;
|
||||||
guchar buf[256], key[256];
|
guchar buf[256], key[256];
|
||||||
int elem;
|
int elem;
|
||||||
MdbTableDef *table = idx->table;
|
MdbTableDef *table = idx->table;
|
||||||
|
|
||||||
fmt = mdb->fmt;
|
|
||||||
mdb_read_pg(mdb, pg);
|
mdb_read_pg(mdb, pg);
|
||||||
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (row*2));
|
mdb_find_row(mdb, row, &row_start, &row_size);
|
||||||
row_end = mdb_find_end_of_row(mdb, row);
|
|
||||||
|
|
||||||
num_fields = mdb_crack_row(table, row_start, row_end, fields);
|
num_fields = mdb_crack_row(table, row_start, row_start + row_size - 1,
|
||||||
|
fields);
|
||||||
for (i=0;i<idx->num_keys;i++) {
|
for (i=0;i<idx->num_keys;i++) {
|
||||||
col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
|
col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
|
||||||
if (col->col_type==MDB_TEXT) {
|
if (col->col_type==MDB_TEXT) {
|
||||||
|
Reference in New Issue
Block a user