Exemplo n.º 1
0
/**
 * mdb_find_pg_row
 * @mdb: Database file handle
 * @pg_row: Lower byte contains the row number, the upper three contain page
 * @buf: Pointer for returning a pointer to the page
 * @off: Pointer for returning an offset to the row
 * @len: Pointer for returning the length of the row
 * 
 * Returns: 0 on success.  1 on failure.
 */
int mdb_find_pg_row(MdbHandle *mdb, int pg_row, void **buf, int *off, size_t *len)
{
	unsigned int pg = pg_row >> 8;
	unsigned int row = pg_row & 0xff;

	if (mdb_read_alt_pg(mdb, pg) != mdb->fmt->pg_size)
		return 1;
	mdb_swap_pgbuf(mdb);
	mdb_find_row(mdb, row, off, len);
	mdb_swap_pgbuf(mdb);
	*buf = mdb->alt_pg_buf;
	return 0;
}
Exemplo n.º 2
0
static gint32
mdb_map_find_next1(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
{
	guint32 map_ind, max_map_pgs, offset, usage_bitlen;

	/*
	* start_pg will tell us where to (re)start the scan
	* for the next data page.  each usage_map entry points to a
	* 0x05 page which bitmaps (mdb->fmt->pg_size - 4) * 8 pages.
	*
	* map_ind gives us the starting usage_map entry
	* offset gives us a page offset into the bitmap
	*/
	usage_bitlen = (mdb->fmt->pg_size - 4) * 8;
	max_map_pgs = (map_sz - 1) / 4;
	map_ind = (start_pg + 1) / usage_bitlen;
	offset = (start_pg + 1) % usage_bitlen;

	for (; map_ind<max_map_pgs; map_ind++) {
		unsigned char *usage_bitmap;
		guint32 i, map_pg;

		if (!(map_pg = mdb_get_int32(map, (map_ind*4)+1))) {
			continue;
		}
		if(mdb_read_alt_pg(mdb, map_pg) != mdb->fmt->pg_size) {
			mdb->fatal_error_handler("Oops! didn't get a full page at %d\n", map_pg);
			exit(1);
		} 

		usage_bitmap = mdb->alt_pg_buf + 4;
		for (i=offset; i<usage_bitlen; i++) {
			if (usage_bitmap[i/8] & (1 << (i%8))) {
				return map_ind*usage_bitlen + i;
			}
		}
		offset = 0;
	}
	/* didn't find anything */
	return 0;
}
Exemplo n.º 3
0
GPtrArray *
mdb_read_indices(MdbTableDef *table)
{
	MdbCatalogEntry *entry = table->entry;
	MdbHandle *mdb = entry->mdb;
	MdbFormatConstants *fmt = mdb->fmt;
	MdbIndex *pidx;
	unsigned int i, j;
	int idx_num, key_num, col_num;
	int cur_pos, name_sz, idx2_sz, type_offset;
	int index_start_pg = mdb->cur_pg;
	guchar *tmpbuf;

        table->indices = g_ptr_array_new();

        if (IS_JET4(mdb)) {
		cur_pos = table->index_start + 52 * table->num_real_idxs;
		idx2_sz = 28;
		type_offset = 23;
	} else {
		cur_pos = table->index_start + 39 * table->num_real_idxs;
		idx2_sz = 20;
		type_offset = 19;
	}

	tmpbuf = (guchar *) g_malloc(idx2_sz);
	for (i=0;i<table->num_idxs;i++) {
		read_pg_if_n(mdb, tmpbuf, &cur_pos, idx2_sz);
		cur_pos += idx2_sz;
		pidx = (MdbIndex *) g_malloc0(sizeof(MdbIndex));
		pidx->table = table;
		pidx->index_num = mdb_get_int16(tmpbuf, 4);
		pidx->index_type = tmpbuf[type_offset]; 
		g_ptr_array_add(table->indices, pidx);
	}
	g_free(tmpbuf);

	for (i=0;i<table->num_idxs;i++) {
		pidx = g_ptr_array_index (table->indices, i);
		if (IS_JET4(mdb)) {
			name_sz=read_pg_if_16(mdb, &cur_pos);
			cur_pos += 2;
			tmpbuf = g_malloc(name_sz);
			read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz);
			cur_pos += name_sz;
			mdb_unicode2ascii(mdb, tmpbuf, 0, name_sz, pidx->name); 
			g_free(tmpbuf);
		} else {
			read_pg_if(mdb, &cur_pos, 0);
			name_sz=mdb->pg_buf[cur_pos++];
			read_pg_if_n(mdb, (unsigned char *) pidx->name, &cur_pos, name_sz);
			cur_pos += name_sz;
			pidx->name[name_sz]='\0';		
		}
		//fprintf(stderr, "index name %s\n", pidx->name);
	}

	mdb_read_alt_pg(mdb, entry->table_pg);
	mdb_read_pg(mdb, index_start_pg);
	cur_pos = table->index_start;
	idx_num=0;
	for (i=0;i<table->num_real_idxs;i++) {
		if (IS_JET4(mdb)) cur_pos += 4;
		do {
			pidx = g_ptr_array_index (table->indices, idx_num++);
		} while (pidx && pidx->index_type==2);

		/* if there are more real indexes than index entries left after
		   removing type 2's decrement real indexes and continue.  Happens
		   on Northwind Orders table.
		*/
		if (!pidx) {
			table->num_real_idxs--;
			continue;
		}

		pidx->num_rows = mdb_get_int32(mdb->alt_pg_buf, 
				fmt->tab_cols_start_offset +
				(i*fmt->tab_ridx_entry_size));

		key_num=0;
		for (j=0;j<MDB_MAX_IDX_COLS;j++) {
			col_num=read_pg_if_16(mdb,&cur_pos);
			cur_pos += 2;
			read_pg_if(mdb, &cur_pos, 0);
			cur_pos++;
			if (col_num == 0xFFFF)
				continue;
			/* set column number to a 1 based column number and store */
			pidx->key_col_num[key_num] = col_num + 1;
			pidx->key_col_order[key_num] =
				(mdb->pg_buf[cur_pos-1]) ? MDB_ASC : MDB_DESC;
			key_num++;
		}
		pidx->num_keys = key_num;

		cur_pos += 4;
		pidx->first_pg = read_pg_if_32(mdb, &cur_pos);
		cur_pos += 4;
		read_pg_if(mdb, &cur_pos, 0);
		pidx->flags = mdb->pg_buf[cur_pos++];
		if (IS_JET4(mdb)) cur_pos += 9;
	}
	return NULL;
}