2000-03-01 11:34:33 +08:00
|
|
|
/* MDB Tools - A library for reading MS Access database file
|
|
|
|
* Copyright (C) 2000 Brian Bruns
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "mdbtools.h"
|
|
|
|
|
2003-01-29 07:51:06 +08:00
|
|
|
#ifdef DMALLOC
|
|
|
|
#include "dmalloc.h"
|
|
|
|
#endif
|
|
|
|
|
2002-12-27 23:09:02 +08:00
|
|
|
|
2004-06-15 12:12:36 +08:00
|
|
|
static gint mdb_col_comparer(MdbColumn **a, MdbColumn **b)
|
2002-02-03 10:49:08 +08:00
|
|
|
{
|
2004-06-15 12:12:36 +08:00
|
|
|
if ((*a)->col_num > (*b)->col_num)
|
2002-02-03 10:49:08 +08:00
|
|
|
return 1;
|
2004-06-15 12:12:36 +08:00
|
|
|
else if ((*a)->col_num < (*b)->col_num)
|
2002-02-03 10:49:08 +08:00
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
2000-03-01 11:34:33 +08:00
|
|
|
|
|
|
|
unsigned char mdb_col_needs_size(int col_type)
|
|
|
|
{
|
|
|
|
if (col_type == MDB_TEXT) {
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-23 20:31:54 +08:00
|
|
|
MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry)
|
|
|
|
{
|
|
|
|
MdbTableDef *table;
|
|
|
|
|
|
|
|
table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef));
|
|
|
|
table->entry=entry;
|
|
|
|
strcpy(table->name, entry->object_name);
|
|
|
|
|
|
|
|
return table;
|
|
|
|
}
|
|
|
|
void mdb_free_tabledef(MdbTableDef *table)
|
|
|
|
{
|
|
|
|
if (!table) return;
|
2004-09-09 11:44:35 +08:00
|
|
|
if (table->is_temp_table) {
|
|
|
|
unsigned int i;
|
2004-12-01 14:34:27 +08:00
|
|
|
/* Temp table pages are being stored in memory */
|
2004-09-09 11:44:35 +08:00
|
|
|
for (i=0; i<table->temp_table_pages->len; i++)
|
|
|
|
g_free(g_ptr_array_index(table->temp_table_pages,i));
|
|
|
|
g_ptr_array_free(table->temp_table_pages, TRUE);
|
2004-12-01 14:34:27 +08:00
|
|
|
/* Temp tables use dummy entries */
|
|
|
|
g_free(table->entry);
|
2004-09-09 11:44:35 +08:00
|
|
|
}
|
2004-06-23 20:31:54 +08:00
|
|
|
mdb_free_columns(table->columns);
|
2004-06-24 12:22:40 +08:00
|
|
|
mdb_free_indices(table->indices);
|
2004-06-23 20:31:54 +08:00
|
|
|
g_free(table->usage_map);
|
|
|
|
g_free(table->free_usage_map);
|
|
|
|
g_free(table);
|
|
|
|
}
|
|
|
|
MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
|
2000-03-05 01:31:07 +08:00
|
|
|
{
|
2004-02-12 06:05:13 +08:00
|
|
|
MdbTableDef *table;
|
|
|
|
MdbHandle *mdb = entry->mdb;
|
|
|
|
MdbFormatConstants *fmt = mdb->fmt;
|
2004-09-08 20:38:24 +08:00
|
|
|
int len, row_start, pg_row;
|
|
|
|
char *buf;
|
2000-03-05 01:31:07 +08:00
|
|
|
|
|
|
|
mdb_read_pg(mdb, entry->table_pg);
|
2005-03-07 12:11:27 +08:00
|
|
|
if (mdb->pg_buf[0] != 0x02) /* not a valid table def page */
|
|
|
|
return NULL;
|
|
|
|
table = mdb_alloc_tabledef(entry);
|
2004-01-11 05:46:14 +08:00
|
|
|
|
2003-04-30 01:55:09 +08:00
|
|
|
len = mdb_pg_get_int16(mdb,8);
|
2000-03-05 01:31:07 +08:00
|
|
|
|
2003-04-30 01:55:09 +08:00
|
|
|
table->num_rows = mdb_pg_get_int32(mdb, fmt->tab_num_rows_offset);
|
2004-08-05 11:33:41 +08:00
|
|
|
table->num_var_cols = mdb_pg_get_int16(mdb, fmt->tab_num_cols_offset-2);
|
2003-04-30 01:55:09 +08:00
|
|
|
table->num_cols = mdb_pg_get_int16(mdb, fmt->tab_num_cols_offset);
|
|
|
|
table->num_idxs = mdb_pg_get_int32(mdb, fmt->tab_num_idxs_offset);
|
|
|
|
table->num_real_idxs = mdb_pg_get_int32(mdb, fmt->tab_num_ridxs_offset);
|
2002-12-20 14:17:41 +08:00
|
|
|
/* grab a copy of the usage map */
|
2004-09-08 20:38:24 +08:00
|
|
|
pg_row = mdb_pg_get_int32(mdb, fmt->tab_usage_map_offset);
|
|
|
|
mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->map_sz));
|
|
|
|
table->usage_map = g_memdup(buf + row_start, table->map_sz);
|
2004-02-16 10:00:45 +08:00
|
|
|
if (mdb_get_option(MDB_DEBUG_USAGE))
|
2004-09-08 20:38:24 +08:00
|
|
|
buffer_dump(buf, row_start, row_start+table->map_sz-1);
|
|
|
|
mdb_debug(MDB_DEBUG_USAGE,"usage map found on page %ld row %d start %d len %d",
|
|
|
|
pg_row >> 8, pg_row & 0xff, row_start, table->map_sz);
|
|
|
|
|
|
|
|
/* grab a copy of the free space page map */
|
|
|
|
pg_row = mdb_pg_get_int32(mdb, fmt->tab_free_map_offset);
|
|
|
|
mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->freemap_sz));
|
|
|
|
table->free_usage_map = g_memdup(buf + row_start, table->freemap_sz);
|
|
|
|
mdb_debug(MDB_DEBUG_USAGE,"free map found on page %ld row %d start %d len %d\n",
|
|
|
|
pg_row >> 8, pg_row & 0xff, row_start, table->freemap_sz);
|
2003-02-10 07:19:21 +08:00
|
|
|
|
2003-04-30 01:55:09 +08:00
|
|
|
table->first_data_pg = mdb_pg_get_int16(mdb, fmt->tab_first_dpg_offset);
|
2000-03-05 01:31:07 +08:00
|
|
|
|
|
|
|
return table;
|
|
|
|
}
|
2004-07-02 20:29:09 +08:00
|
|
|
MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
MdbCatalogEntry *entry;
|
|
|
|
|
|
|
|
mdb_read_catalog(mdb, obj_type);
|
|
|
|
|
|
|
|
for (i=0; i<mdb->num_catalog; i++) {
|
|
|
|
entry = g_ptr_array_index(mdb->catalog, i);
|
|
|
|
if (!strcasecmp(entry->object_name, table_name))
|
|
|
|
return mdb_read_table(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2000-03-05 01:31:07 +08:00
|
|
|
|
2000-10-14 05:33:04 +08:00
|
|
|
/*
|
|
|
|
** read the next page if offset is > pg_size
|
|
|
|
** return true if page was read
|
|
|
|
*/
|
2003-01-29 07:51:06 +08:00
|
|
|
int
|
|
|
|
read_pg_if(MdbHandle *mdb, int *cur_pos, int offset)
|
2000-10-14 05:33:04 +08:00
|
|
|
{
|
2003-01-02 06:29:39 +08:00
|
|
|
if (*cur_pos + offset >= mdb->fmt->pg_size) {
|
2003-04-30 01:55:09 +08:00
|
|
|
mdb_read_pg(mdb, mdb_pg_get_int32(mdb,4));
|
2003-01-02 06:29:39 +08:00
|
|
|
*cur_pos = 8 - (mdb->fmt->pg_size - (*cur_pos));
|
2000-10-14 05:33:04 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2003-01-29 07:51:06 +08:00
|
|
|
guint32
|
|
|
|
read_pg_if_32(MdbHandle *mdb, int *cur_pos)
|
|
|
|
{
|
|
|
|
unsigned char c[4];
|
|
|
|
int i, rc = 0;
|
|
|
|
|
|
|
|
for (i=0;i<4;i++) {
|
|
|
|
rc += read_pg_if(mdb, cur_pos, i);
|
|
|
|
c[i] = mdb->pg_buf[(*cur_pos) + i];
|
|
|
|
}
|
2003-04-30 01:55:09 +08:00
|
|
|
return mdb_get_int32(c, 0);
|
2003-01-29 07:51:06 +08:00
|
|
|
}
|
|
|
|
guint16
|
|
|
|
read_pg_if_16(MdbHandle *mdb, int *cur_pos)
|
|
|
|
{
|
|
|
|
unsigned char low_byte, high_byte;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
rc += read_pg_if(mdb, cur_pos, 0);
|
|
|
|
low_byte = mdb->pg_buf[*cur_pos];
|
|
|
|
rc += read_pg_if(mdb, cur_pos, 1);
|
|
|
|
high_byte = mdb->pg_buf[(*cur_pos) + 1];
|
|
|
|
|
|
|
|
return (high_byte * 256 + low_byte);
|
|
|
|
}
|
|
|
|
guint16
|
|
|
|
read_pg_if_n(MdbHandle *mdb, unsigned char *buf, int *cur_pos, int len)
|
|
|
|
{
|
|
|
|
if (*cur_pos + len < mdb->fmt->pg_size) {
|
|
|
|
memcpy(buf, &mdb->pg_buf[*cur_pos], len);
|
|
|
|
return 0;
|
2004-06-12 05:57:19 +08:00
|
|
|
} else {
|
|
|
|
int half = mdb->fmt->pg_size - *cur_pos;
|
|
|
|
memcpy(buf, &mdb->pg_buf[*cur_pos], half);
|
|
|
|
mdb_read_pg(mdb, mdb_pg_get_int32(mdb,4));
|
|
|
|
memcpy(buf + half, &mdb->pg_buf[8], len - half);
|
|
|
|
*cur_pos = 8 - half;
|
|
|
|
return 1;
|
2003-01-29 07:51:06 +08:00
|
|
|
}
|
|
|
|
}
|
2000-10-14 05:33:04 +08:00
|
|
|
|
2004-06-23 20:31:54 +08:00
|
|
|
void mdb_append_column(GPtrArray *columns, MdbColumn *in_col)
|
|
|
|
{
|
|
|
|
g_ptr_array_add(columns, g_memdup(in_col,sizeof(MdbColumn)));
|
|
|
|
}
|
|
|
|
void mdb_free_columns(GPtrArray *columns)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
if (!columns) return;
|
|
|
|
for (i=0; i<columns->len; i++)
|
|
|
|
g_free (g_ptr_array_index(columns, i));
|
|
|
|
g_ptr_array_free(columns, TRUE);
|
|
|
|
}
|
2000-03-12 22:08:53 +08:00
|
|
|
GPtrArray *mdb_read_columns(MdbTableDef *table)
|
2000-03-01 11:34:33 +08:00
|
|
|
{
|
2004-01-06 08:42:07 +08:00
|
|
|
MdbHandle *mdb = table->entry->mdb;
|
|
|
|
MdbFormatConstants *fmt = mdb->fmt;
|
2004-06-14 20:13:25 +08:00
|
|
|
MdbColumn *pcol;
|
|
|
|
unsigned char *col;
|
2004-07-09 20:47:04 +08:00
|
|
|
unsigned int i;
|
|
|
|
int cur_pos, name_sz;
|
2000-03-05 21:10:42 +08:00
|
|
|
|
2000-03-12 22:08:53 +08:00
|
|
|
table->columns = g_ptr_array_new();
|
2000-03-05 01:31:07 +08:00
|
|
|
|
2004-06-14 20:13:25 +08:00
|
|
|
col = (unsigned char *) g_malloc(fmt->tab_col_entry_size);
|
|
|
|
|
|
|
|
cur_pos = fmt->tab_cols_start_offset +
|
2003-01-02 06:29:39 +08:00
|
|
|
(table->num_real_idxs * fmt->tab_ridx_entry_size);
|
2000-03-01 11:34:33 +08:00
|
|
|
|
2000-10-14 05:33:04 +08:00
|
|
|
/* new code based on patch submitted by Tim Nelson 2000.09.27 */
|
2000-03-01 11:34:33 +08:00
|
|
|
|
2000-10-14 05:33:04 +08:00
|
|
|
/*
|
|
|
|
** column attributes
|
|
|
|
*/
|
2002-02-03 10:49:08 +08:00
|
|
|
for (i=0;i<table->num_cols;i++) {
|
2002-12-11 07:35:24 +08:00
|
|
|
#ifdef MDB_DEBUG
|
|
|
|
/* printf("column %d\n", i);
|
2004-06-14 20:13:25 +08:00
|
|
|
buffer_dump(mdb->pg_buf, cur_pos ,cur_pos + 18); */
|
2002-12-11 07:35:24 +08:00
|
|
|
#endif
|
2004-06-14 20:13:25 +08:00
|
|
|
read_pg_if_n(mdb, col, &cur_pos, fmt->tab_col_entry_size);
|
|
|
|
cur_pos += fmt->tab_col_entry_size;
|
|
|
|
pcol = (MdbColumn *) g_malloc0(sizeof(MdbColumn));
|
2000-03-05 21:10:42 +08:00
|
|
|
|
2004-06-14 20:13:25 +08:00
|
|
|
pcol->col_type = col[0];
|
2000-10-14 05:33:04 +08:00
|
|
|
|
2004-06-14 20:13:25 +08:00
|
|
|
// col_num_offset == 1 or 5
|
|
|
|
pcol->col_num = col[fmt->col_num_offset];
|
2004-01-06 08:42:07 +08:00
|
|
|
|
2004-06-14 20:13:25 +08:00
|
|
|
//fprintf(stdout,"----- column %d -----\n",pcol->col_num);
|
|
|
|
// col_var == 3 or 7
|
|
|
|
pcol->var_col_num = mdb_get_int16(col, fmt->tab_col_offset_var);
|
|
|
|
//fprintf(stdout,"var column pos %d\n",pcol->var_col_num);
|
2004-03-05 05:25:09 +08:00
|
|
|
|
2004-06-14 20:13:25 +08:00
|
|
|
// col_var == 5 or 9
|
|
|
|
pcol->row_col_num = mdb_get_int16(col, fmt->tab_row_col_num_offset);
|
|
|
|
//fprintf(stdout,"row column num %d\n",pcol->row_col_num);
|
2004-03-05 05:25:09 +08:00
|
|
|
|
2004-01-06 08:42:07 +08:00
|
|
|
/* FIXME: can this be right in Jet3 and Jet4? */
|
2004-06-14 20:13:25 +08:00
|
|
|
if (pcol->col_type == MDB_NUMERIC) {
|
|
|
|
pcol->col_prec = col[11];
|
|
|
|
pcol->col_scale = col[12];
|
2002-12-11 07:35:24 +08:00
|
|
|
}
|
2000-03-01 11:34:33 +08:00
|
|
|
|
2004-06-14 20:13:25 +08:00
|
|
|
// col_fixed_offset == 13 or 15
|
|
|
|
pcol->is_fixed = col[fmt->col_fixed_offset] & 0x01 ? 1 : 0;
|
|
|
|
|
|
|
|
// col_fixed_offset == 13 or 15
|
|
|
|
pcol->fixed_offset = mdb_get_int16(col, fmt->tab_col_offset_fixed);
|
|
|
|
//fprintf(stdout,"fixed column offset %d\n",pcol->fixed_offset);
|
|
|
|
//fprintf(stdout,"col type %s\n",pcol->is_fixed ? "fixed" : "variable");
|
|
|
|
|
|
|
|
if (pcol->col_type != MDB_BOOL) {
|
|
|
|
// col_size_offset == 16 or 23
|
|
|
|
pcol->col_size = mdb_get_int16(col, fmt->col_size_offset);
|
|
|
|
} else {
|
|
|
|
pcol->col_size=0;
|
|
|
|
}
|
2002-02-03 10:49:08 +08:00
|
|
|
|
2004-06-15 12:12:36 +08:00
|
|
|
g_ptr_array_add(table->columns, pcol);
|
2000-03-05 21:10:42 +08:00
|
|
|
}
|
|
|
|
|
2004-06-14 20:13:25 +08:00
|
|
|
g_free (col);
|
|
|
|
|
2000-10-14 05:33:04 +08:00
|
|
|
/*
|
2004-06-15 12:12:36 +08:00
|
|
|
** column names - ordered the same as the column attributes table
|
2000-10-14 05:33:04 +08:00
|
|
|
*/
|
|
|
|
for (i=0;i<table->num_cols;i++) {
|
2004-12-11 14:07:20 +08:00
|
|
|
char *tmp_buf;
|
2004-06-15 12:12:36 +08:00
|
|
|
pcol = g_ptr_array_index(table->columns, i);
|
2000-10-14 05:33:04 +08:00
|
|
|
|
2003-01-02 06:29:39 +08:00
|
|
|
if (IS_JET4(mdb)) {
|
2004-06-14 20:13:25 +08:00
|
|
|
name_sz = read_pg_if_16(mdb, &cur_pos);
|
|
|
|
cur_pos += 2;
|
2003-01-02 06:29:39 +08:00
|
|
|
} else if (IS_JET3(mdb)) {
|
2004-06-14 20:13:25 +08:00
|
|
|
read_pg_if(mdb, &cur_pos, 0);
|
|
|
|
name_sz = mdb->pg_buf[cur_pos];
|
|
|
|
cur_pos++;
|
2002-02-03 10:49:08 +08:00
|
|
|
} else {
|
|
|
|
fprintf(stderr,"Unknown MDB version\n");
|
2004-12-02 07:31:48 +08:00
|
|
|
continue;
|
2000-10-14 05:33:04 +08:00
|
|
|
}
|
2004-12-02 07:31:48 +08:00
|
|
|
tmp_buf = (char *) g_malloc(name_sz);
|
|
|
|
read_pg_if_n(mdb, tmp_buf, &cur_pos, name_sz);
|
2004-12-11 14:07:20 +08:00
|
|
|
mdb_unicode2ascii(mdb, tmp_buf, name_sz, pcol->name, MDB_MAX_OBJ_NAME);
|
2004-12-02 07:31:48 +08:00
|
|
|
g_free(tmp_buf);
|
|
|
|
cur_pos += name_sz;
|
|
|
|
|
2000-10-14 05:33:04 +08:00
|
|
|
}
|
2002-02-03 10:49:08 +08:00
|
|
|
|
2004-06-15 12:12:36 +08:00
|
|
|
/* Sort the columns by col_num */
|
|
|
|
g_ptr_array_sort(table->columns, (GCompareFunc)mdb_col_comparer);
|
2002-02-03 10:49:08 +08:00
|
|
|
|
2004-06-14 20:13:25 +08:00
|
|
|
table->index_start = cur_pos;
|
2000-03-05 21:10:42 +08:00
|
|
|
return table->columns;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mdb_table_dump(MdbCatalogEntry *entry)
|
|
|
|
{
|
|
|
|
MdbTableDef *table;
|
2000-03-12 22:08:53 +08:00
|
|
|
MdbColumn *col;
|
2003-01-02 06:29:39 +08:00
|
|
|
int coln;
|
2001-04-02 06:10:15 +08:00
|
|
|
MdbIndex *idx;
|
2000-03-05 21:10:42 +08:00
|
|
|
MdbHandle *mdb = entry->mdb;
|
2004-07-09 20:47:04 +08:00
|
|
|
unsigned int i, bitn;
|
2003-01-21 00:04:24 +08:00
|
|
|
guint32 pgnum;
|
2000-03-05 21:10:42 +08:00
|
|
|
|
|
|
|
table = mdb_read_table(entry);
|
2003-01-13 06:59:41 +08:00
|
|
|
fprintf(stdout,"definition page = %lu\n",entry->table_pg);
|
2000-03-05 21:10:42 +08:00
|
|
|
fprintf(stdout,"number of datarows = %d\n",table->num_rows);
|
|
|
|
fprintf(stdout,"number of columns = %d\n",table->num_cols);
|
2001-04-02 06:10:15 +08:00
|
|
|
fprintf(stdout,"number of indices = %d\n",table->num_real_idxs);
|
2000-03-05 21:10:42 +08:00
|
|
|
|
2000-03-09 12:48:59 +08:00
|
|
|
mdb_read_columns(table);
|
2001-04-02 06:10:15 +08:00
|
|
|
mdb_read_indices(table);
|
|
|
|
|
2000-03-05 21:10:42 +08:00
|
|
|
for (i=0;i<table->num_cols;i++) {
|
2000-03-12 22:08:53 +08:00
|
|
|
col = g_ptr_array_index(table->columns,i);
|
2000-03-05 21:10:42 +08:00
|
|
|
|
2000-03-09 12:48:59 +08:00
|
|
|
fprintf(stdout,"column %d Name: %-20s Type: %s(%d)\n",
|
2000-03-12 22:08:53 +08:00
|
|
|
i, col->name,
|
2000-04-03 01:08:30 +08:00
|
|
|
mdb_get_coltype_string(mdb->default_backend, col->col_type),
|
2000-03-12 22:08:53 +08:00
|
|
|
col->col_size);
|
2000-03-01 11:34:33 +08:00
|
|
|
}
|
2001-04-02 06:10:15 +08:00
|
|
|
|
|
|
|
for (i=0;i<table->num_idxs;i++) {
|
|
|
|
idx = g_ptr_array_index (table->indices, i);
|
2001-05-23 09:42:46 +08:00
|
|
|
mdb_index_dump(table, idx);
|
2001-04-02 06:10:15 +08:00
|
|
|
}
|
2002-12-20 14:17:41 +08:00
|
|
|
if (table->usage_map) {
|
2003-01-21 00:04:24 +08:00
|
|
|
printf("pages reserved by this object\n");
|
2004-07-17 15:48:11 +08:00
|
|
|
printf("usage map pg %" G_GUINT32_FORMAT "\n",
|
|
|
|
table->map_base_pg);
|
|
|
|
printf("free map pg %" G_GUINT32_FORMAT "\n",
|
|
|
|
table->freemap_base_pg);
|
2003-04-30 01:55:09 +08:00
|
|
|
pgnum = mdb_get_int32(table->usage_map,1);
|
2002-12-20 14:17:41 +08:00
|
|
|
/* the first 5 bytes of the usage map mean something */
|
2003-01-02 06:29:39 +08:00
|
|
|
coln = 0;
|
2002-12-20 14:17:41 +08:00
|
|
|
for (i=5;i<table->map_sz;i++) {
|
|
|
|
for (bitn=0;bitn<8;bitn++) {
|
2003-01-02 06:29:39 +08:00
|
|
|
if (table->usage_map[i] & 1 << bitn) {
|
|
|
|
coln++;
|
2004-07-17 15:48:11 +08:00
|
|
|
printf("%6" G_GUINT32_FORMAT, pgnum);
|
2003-01-02 06:29:39 +08:00
|
|
|
if (coln==10) {
|
|
|
|
printf("\n");
|
|
|
|
coln = 0;
|
2004-07-17 15:48:11 +08:00
|
|
|
} else {
|
|
|
|
printf(" ");
|
2003-01-02 06:29:39 +08:00
|
|
|
}
|
|
|
|
}
|
2002-12-20 14:17:41 +08:00
|
|
|
pgnum++;
|
|
|
|
}
|
|
|
|
}
|
2004-02-12 06:05:13 +08:00
|
|
|
printf("\n");
|
2002-12-20 14:17:41 +08:00
|
|
|
}
|
2000-03-01 11:34:33 +08:00
|
|
|
}
|
2004-09-16 12:00:39 +08:00
|
|
|
|
|
|
|
int mdb_is_user_table(MdbCatalogEntry *entry)
|
|
|
|
{
|
|
|
|
return ((entry->object_type == MDB_TABLE)
|
|
|
|
&& !(entry->flags & 0x80000002)) ? 1 : 0;
|
|
|
|
}
|
|
|
|
int mdb_is_system_table(MdbCatalogEntry *entry)
|
|
|
|
{
|
|
|
|
return ((entry->object_type == MDB_TABLE)
|
|
|
|
&& (entry->flags & 0x80000002)) ? 1 : 0;
|
|
|
|
}
|