1
/* MDB Tools - A library for reading MS Access database files
2
* Copyright (C) 2000 Brian Bruns
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Library General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Library General Public License for more details.
14
* You should have received a copy of the GNU Library General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27
#include <sys/types.h>
45
#define MDB_PGSIZE 4096
46
//#define MDB_MAX_OBJ_NAME (256*3) /* unicode 16 -> utf-8 worst case */
47
#define MDB_MAX_OBJ_NAME 256
48
#define MDB_MAX_COLS 256
49
#define MDB_MAX_IDX_COLS 10
50
#define MDB_CATALOG_PG 18
51
#define MDB_MEMO_OVERHEAD 12
52
#define MDB_BIND_SIZE 16384
54
#define MDB_NO_BACKENDS 1
55
#define MDB_NO_STATS 1
57
// Theses 2 atrbutes are not supported by all compilers:
58
// M$VC see http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
59
#define MDB_DEPRECATED(type, funcname) type __attribute__((deprecated)) funcname
60
#define MDB_CONSTRUCTOR(funcname) void __attribute__((constructor)) funcname()
73
MDB_VER_ACCDB_2007 = 0x02,
74
MDB_VER_ACCDB_2010 = 0x0103
87
MDB_UNKNOWN_0A, /* User access */
88
MDB_DATABASE_PROPERTY,
136
MDB_DEBUG_LIKE = 0x0001,
137
MDB_DEBUG_WRITE = 0x0002,
138
MDB_DEBUG_USAGE = 0x0004,
139
MDB_DEBUG_OLE = 0x0008,
140
MDB_DEBUG_ROW = 0x0010,
141
MDB_DEBUG_PROPS = 0x0020,
142
MDB_USE_INDEX = 0x0040,
143
MDB_NO_MEMO = 0x0080, /* don't follow memo fields */
146
#define mdb_is_logical_op(x) (x == MDB_OR || \
150
#define mdb_is_relational_op(x) (x == MDB_EQUAL || \
165
MDB_IDX_UNIQUE = 0x01,
166
MDB_IDX_IGNORENULLS = 0x02,
167
MDB_IDX_REQUIRED = 0x08
170
/* export schema options */
172
MDB_SHEXP_DROPTABLE = 1<<0, /* issue drop table during export */
173
MDB_SHEXP_CST_NOTNULL = 1<<1, /* generate NOT NULL constraints */
174
MDB_SHEXP_CST_NOTEMPTY = 1<<2, /* <>'' constraints */
175
MDB_SHEXP_COMMENTS = 1<<3, /* export comments on columns & tables */
176
MDB_SHEXP_DEFVALUES = 1<<4, /* export default values */
177
MDB_SHEXP_INDEXES = 1<<5, /* export indices */
178
MDB_SHEXP_RELATIONS = 1<<6 /* export relation (foreign keys) */
180
#define MDB_SHEXP_DEFAULT (MDB_SHEXP_CST_NOTNULL | MDB_SHEXP_COMMENTS | MDB_SHEXP_INDEXES | MDB_SHEXP_RELATIONS)
182
/* csv export binary options */
189
#define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4) /* obsolete */
190
#define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)
192
/* forward declarations */
193
typedef struct mdbindex MdbIndex;
194
typedef struct mdbsargtree MdbSargNode;
199
unsigned char needs_length; /* or precision */
200
unsigned char needs_scale;
201
unsigned char needs_quotes;
205
guint32 capabilities; /* see MDB_SHEXP_* */
206
MdbBackendType *types_table;
207
MdbBackendType *type_shortdate;
208
MdbBackendType *type_autonum;
209
const char *short_now;
210
const char *long_now;
211
const char *charset_statement;
212
const char *drop_statement;
213
const char *constaint_not_empty_statement;
214
const char *column_comment_statement;
215
const char *table_comment_statement;
216
gchar* (*quote_schema_name)(const gchar*, const gchar*);
223
unsigned long pg_reads;
235
MdbBackend *default_backend;
239
MdbStatistics *stats;
243
unsigned char *free_map;
244
/* reference count */
248
/* offset to row count on data pages...version dependant */
251
guint16 row_count_offset;
252
guint16 tab_num_rows_offset;
253
guint16 tab_num_cols_offset;
254
guint16 tab_num_idxs_offset;
255
guint16 tab_num_ridxs_offset;
256
guint16 tab_usage_map_offset;
257
guint16 tab_first_dpg_offset;
258
guint16 tab_cols_start_offset;
259
guint16 tab_ridx_entry_size;
260
guint16 col_flags_offset;
261
guint16 col_size_offset;
262
guint16 col_num_offset;
263
guint16 tab_col_entry_size;
264
guint16 tab_free_map_offset;
265
guint16 tab_col_offset_var;
266
guint16 tab_col_offset_fixed;
267
guint16 tab_row_col_num_offset;
268
} MdbFormatConstants;
274
unsigned int cur_pos;
275
unsigned char pg_buf[MDB_PGSIZE];
276
unsigned char alt_pg_buf[MDB_PGSIZE];
277
unsigned int num_catalog;
280
MdbBackend *default_backend;
283
MdbFormatConstants *fmt;
285
MdbStatistics *stats;
288
char* jet3_iconv_code;
296
char object_name[MDB_MAX_OBJ_NAME+1];
298
unsigned long table_pg; /* misnomer since object may not be a table */
299
//int num_props; please use props->len
300
GArray *props; /* GArray of MdbProperties */
316
struct S_MdbTableDef; /* forward definition */
318
struct S_MdbTableDef *table;
319
char name[MDB_MAX_OBJ_NAME+1];
324
GHashTable *properties;
325
unsigned int num_sargs;
327
GPtrArray *idx_sarg_cache;
328
unsigned char is_fixed;
330
/* col_num is the current column order,
331
* does not include deletes */
335
/* MEMO/OLE readers */
336
guint32 cur_blob_pg_row;
341
unsigned char is_long_auto;
342
unsigned char is_uuid_auto;
343
MdbProperties *props;
344
/* info needed for handling deleted/added columns */
346
unsigned int var_col_num;
347
/* row_col_num is the row column number order,
348
* including deleted columns */
366
guint16 idx_starts[2000];
367
unsigned char cache_value[256];
370
typedef int (*MdbSargTreeFunc)(MdbSargNode *, gpointer data);
372
#define MDB_MAX_INDEX_DEPTH 10
376
guint32 last_leaf_found;
378
MdbIndexPage pages[MDB_MAX_INDEX_DEPTH];
381
typedef struct S_MdbTableDef {
382
MdbCatalogEntry *entry;
383
char name[MDB_MAX_OBJ_NAME+1];
384
unsigned int num_cols;
386
unsigned int num_rows;
388
unsigned int num_real_idxs;
389
unsigned int num_idxs;
391
guint32 first_data_pg;
394
unsigned int cur_row;
395
int noskip_del; /* don't skip deleted rows */
396
/* object allocation map */
399
unsigned char *usage_map;
400
/* pages with free space left */
401
guint32 freemap_base_pg;
403
unsigned char *free_usage_map;
405
MdbSargNode *sarg_tree;
406
MdbStrategy strategy;
409
MdbIndexChain *chain;
410
MdbProperties *props;
411
unsigned int num_var_cols; /* to know if row has variable columns */
413
unsigned int is_temp_table;
414
GPtrArray *temp_table_pages;
419
char name[MDB_MAX_OBJ_NAME+1];
420
unsigned char index_type;
422
int num_rows; /* number rows in index */
423
unsigned int num_keys;
424
short key_col_num[MDB_MAX_IDX_COLS];
425
unsigned char key_col_order[MDB_MAX_IDX_COLS];
431
char name[MDB_MAX_OBJ_NAME+1];
438
unsigned char is_null;
439
unsigned char is_fixed;
450
extern MDB_DEPRECATED(void, mdb_init());
451
extern MDB_DEPRECATED(void, mdb_exit());
454
extern ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg);
455
extern ssize_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg);
456
extern unsigned char mdb_get_byte(void *buf, int offset);
457
extern int mdb_get_int16(void *buf, int offset);
458
extern long mdb_get_int32(void *buf, int offset);
459
extern long mdb_get_int32_msb(void *buf, int offset);
460
extern float mdb_get_single(void *buf, int offset);
461
extern double mdb_get_double(void *buf, int offset);
462
extern unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset);
463
extern int mdb_pg_get_int16(MdbHandle *mdb, int offset);
464
extern long mdb_pg_get_int32(MdbHandle *mdb, int offset);
465
extern float mdb_pg_get_single(MdbHandle *mdb, int offset);
466
extern double mdb_pg_get_double(MdbHandle *mdb, int offset);
467
extern void mdb_set_encoding(MdbHandle *mdb, const char *encoding_name);
468
extern MdbHandle *mdb_open(const char *filename, MdbFileFlags flags);
469
extern void mdb_close(MdbHandle *mdb);
470
extern MdbHandle *mdb_clone_handle(MdbHandle *mdb);
471
extern void mdb_swap_pgbuf(MdbHandle *mdb);
474
extern void mdb_free_catalog(MdbHandle *mdb);
475
extern GPtrArray *mdb_read_catalog(MdbHandle *mdb, int obj_type);
476
MdbCatalogEntry *mdb_get_catalogentry_by_name(MdbHandle *mdb, const gchar* name);
477
extern void mdb_dump_catalog(MdbHandle *mdb, int obj_type);
478
extern const char *mdb_get_objtype_string(int obj_type);
481
extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry);
482
extern void mdb_free_tabledef(MdbTableDef *table);
483
extern MdbTableDef *mdb_read_table(MdbCatalogEntry *entry);
484
extern MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type);
485
extern void mdb_append_column(GPtrArray *columns, MdbColumn *in_col);
486
extern void mdb_free_columns(GPtrArray *columns);
487
extern GPtrArray *mdb_read_columns(MdbTableDef *table);
488
extern void mdb_table_dump(MdbCatalogEntry *entry);
489
extern guint8 read_pg_if_8(MdbHandle *mdb, int *cur_pos);
490
extern guint16 read_pg_if_16(MdbHandle *mdb, int *cur_pos);
491
extern guint32 read_pg_if_32(MdbHandle *mdb, int *cur_pos);
492
extern void *read_pg_if_n(MdbHandle *mdb, void *buf, int *cur_pos, size_t len);
493
extern int mdb_is_user_table(MdbCatalogEntry *entry);
494
extern int mdb_is_system_table(MdbCatalogEntry *entry);
495
extern const char *mdb_table_get_prop(const MdbTableDef *table, const gchar *key);
496
extern const char *mdb_col_get_prop(const MdbColumn *col, const gchar *key);
499
extern int mdb_bind_column_by_name(MdbTableDef *table, const gchar *col_name, void *bind_ptr, int *len_ptr);
500
extern void mdb_data_dump(MdbTableDef *table);
501
extern void mdb_date_to_tm(double td, struct tm *t);
502
extern void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr, int *len_ptr);
503
extern int mdb_rewind_table(MdbTableDef *table);
504
extern int mdb_fetch_row(MdbTableDef *table);
505
extern int mdb_is_fixed_col(MdbColumn *col);
506
extern char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int datatype, int size);
507
extern int mdb_find_pg_row(MdbHandle *mdb, int pg_row, void **buf, int *off, size_t *len);
508
extern int mdb_find_row(MdbHandle *mdb, int row, int *start, size_t *len);
509
extern int mdb_find_end_of_row(MdbHandle *mdb, int row);
510
extern int mdb_col_fixed_size(MdbColumn *col);
511
extern int mdb_col_disp_size(MdbColumn *col);
512
extern size_t mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr);
513
extern size_t mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size);
514
extern void* mdb_ole_read_full(MdbHandle *mdb, MdbColumn *col, size_t *size);
515
extern void mdb_set_date_fmt(const char *);
516
extern int mdb_read_row(MdbTableDef *table, unsigned int row);
519
extern void mdb_buffer_dump(const void *buf, int start, size_t len);
523
extern MDB_DEPRECATED(char*, mdb_get_coltype_string(MdbBackend *backend, int col_type));
524
extern MDB_DEPRECATED(int, mdb_coltype_takes_length(MdbBackend *backend, int col_type));
525
extern const MdbBackendType* mdb_get_colbacktype(const MdbColumn *col);
526
extern const char* mdb_get_colbacktype_string(const MdbColumn *col);
527
extern int mdb_colbacktype_takes_length(const MdbColumn *col);
528
extern MDB_DEPRECATED(void, mdb_init_backends());
529
extern void mdb_register_backend(char *backend_name, guint32 capabilities, MdbBackendType *backend_type, MdbBackendType *type_shortdate, MdbBackendType *type_autonum, const char *short_now, const char *long_now, const char *charset_statement, const char *drop_statement, const char *constaint_not_empty_statement, const char *column_comment_statement, const char *table_comment_statement, gchar* (*quote_schema_name)(const gchar*, const gchar*));
530
extern MDB_DEPRECATED(void, mdb_remove_backends());
531
extern int mdb_set_default_backend(MdbHandle *mdb, const char *backend_name);
532
extern void mdb_print_schema(MdbHandle *mdb, FILE *outfile, char *tabname, char *dbnamespace, guint32 export_options);
536
extern int mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields);
537
extern int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field);
538
extern void mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data);
539
extern int mdb_find_indexable_sargs(MdbSargNode *node, gpointer data);
540
extern int mdb_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg);
541
extern int mdb_test_string(MdbSargNode *node, char *s);
542
extern int mdb_test_int(MdbSargNode *node, gint32 i);
543
extern int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg);
548
extern GPtrArray *mdb_read_indices(MdbTableDef *table);
549
extern void mdb_index_dump(MdbTableDef *table, MdbIndex *idx);
550
extern void mdb_index_scan_free(MdbTableDef *table);
551
extern int mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg);
552
extern int mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row);
553
extern void mdb_index_hash_text(char *text, char *hash);
554
extern void mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table);
555
extern int mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row);
556
extern void mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest);
557
extern void mdb_free_indices(GPtrArray *indices);
558
void mdb_index_page_reset(MdbIndexPage *ipg);
559
extern int mdb_index_pack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg);
563
extern void mdb_stats_on(MdbHandle *mdb);
564
extern void mdb_stats_off(MdbHandle *mdb);
565
extern void mdb_dump_stats(MdbHandle *mdb);
569
extern int mdb_like_cmp(char *s, char *r);
572
extern void mdb_put_int16(void *buf, guint32 offset, guint32 value);
573
extern void mdb_put_int32(void *buf, guint32 offset, guint32 value);
574
extern void mdb_put_int32_msb(void *buf, guint32 offset, guint32 value);
575
extern int mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields);
576
extern guint16 mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size);
577
extern int mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum);
578
extern int mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields);
579
extern int mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields);
580
extern int mdb_replace_row(MdbTableDef *table, int row, void *new_row, int new_row_size);
581
extern int mdb_pg_get_freespace(MdbHandle *mdb);
582
extern int mdb_update_row(MdbTableDef *table);
583
extern void *mdb_new_data_pg(MdbCatalogEntry *entry);
586
extern guint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size);
587
extern gint32 mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg);
590
extern void mdb_free_props(MdbProperties *props);
591
extern void mdb_dump_props(MdbProperties *props, FILE *outfile, int show_name);
592
extern GArray* mdb_kkd_to_props(MdbHandle *mdb, void *kkd, size_t len);
596
extern MdbTableDef *mdb_create_temp_table(MdbHandle *mdb, char *name);
597
extern void mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col);
598
extern void mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed);
599
extern void mdb_fill_temp_field(MdbField *field, void *value, int siz, int is_fixed, int is_null, int start, int column);
600
extern void mdb_temp_columns_end(MdbTableDef *table);
603
extern int mdb_get_option(unsigned long optnum);
604
extern void mdb_debug(int klass, const char *fmt, ...);
607
extern int mdb_unicode2ascii(MdbHandle *mdb, char *src, size_t slen, char *dest, size_t dlen);
608
extern int mdb_ascii2unicode(MdbHandle *mdb, char *src, size_t slen, char *dest, size_t dlen);
609
extern void mdb_iconv_init(MdbHandle *mdb);
610
extern void mdb_iconv_close(MdbHandle *mdb);
611
extern const char* mdb_target_charset(MdbHandle *mdb);
617
#endif /* _mdbtools_h_ */