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
21 #define MDBTOOLS_H_HAVE_ICONV_H @HAVE_ICONV_H@
22 #define MDBTOOLS_H_HAVE_XLOCALE_H @HAVE_XLOCALE_H@
30 #include <sys/types.h>
37 #include <@GLIB_INCLUDE_HEADER@>
39 #if MDBTOOLS_H_HAVE_ICONV_H
43 #if MDBTOOLS_H_HAVE_XLOCALE_H
51 /** \addtogroup mdbtools
57 #define MDB_PGSIZE 4096
58 //#define MDB_MAX_OBJ_NAME (256*3) /* unicode 16 -> utf-8 worst case */
59 #define MDB_MAX_OBJ_NAME 256
60 #define MDB_MAX_COLS 256
61 #define MDB_MAX_IDX_COLS 10
62 #define MDB_CATALOG_PG 18
63 #define MDB_MEMO_OVERHEAD 12
64 #define MDB_BIND_SIZE 16384 // override with mdb_set_bind_size(MdbHandle*, size_t)
66 // This attribute is not supported by all compilers:
67 // M$VC see http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
68 #define MDB_DEPRECATED(type, funcname) type __attribute__((deprecated)) funcname
70 typedef @LOCALE_T@ mdb_locale_t
;
83 MDB_VER_ACCDB_2007
= 0x02,
84 MDB_VER_ACCDB_2010
= 0x03,
85 MDB_VER_ACCDB_2013
= 0x04,
86 MDB_VER_ACCDB_2016
= 0x05,
87 MDB_VER_ACCDB_2019
= 0x06
100 MDB_UNKNOWN_0A
, /* User access */
101 MDB_DATABASE_PROPERTY
,
151 MDB_DEBUG_LIKE
= 0x0001,
152 MDB_DEBUG_WRITE
= 0x0002,
153 MDB_DEBUG_USAGE
= 0x0004,
154 MDB_DEBUG_OLE
= 0x0008,
155 MDB_DEBUG_ROW
= 0x0010,
156 MDB_DEBUG_PROPS
= 0x0020,
157 MDB_USE_INDEX
= 0x0040,
158 MDB_NO_MEMO
= 0x0080, /* don't follow memo fields */
162 MDB_BRACES_4_2_2_8
, /* "{XXXX-XX-XX-XXXXXXXX}" format */
163 MDB_NOBRACES_4_2_2_2_6
, /* "XXXX-XX-XX-XX-XXXXXX" format (matches MS Access ODBC driver) */
166 #define mdb_is_logical_op(x) (x == MDB_OR || \
170 #define mdb_is_relational_op(x) (x == MDB_EQUAL || \
187 MDB_IDX_UNIQUE
= 0x01,
188 MDB_IDX_IGNORENULLS
= 0x02,
189 MDB_IDX_REQUIRED
= 0x08
192 /* export schema options */
194 MDB_SHEXP_DROPTABLE
= 1<<0, /* issue drop table during export */
195 MDB_SHEXP_CST_NOTNULL
= 1<<1, /* generate NOT NULL constraints */
196 MDB_SHEXP_CST_NOTEMPTY
= 1<<2, /* <>'' constraints */
197 MDB_SHEXP_COMMENTS
= 1<<3, /* export comments on columns & tables */
198 MDB_SHEXP_DEFVALUES
= 1<<4, /* export default values */
199 MDB_SHEXP_INDEXES
= 1<<5, /* export indices */
200 MDB_SHEXP_RELATIONS
= 1<<6, /* export relation (foreign keys) */
201 MDB_SHEXP_BULK_INSERT
= 1 << 7 /* export data in bulk inserts */
203 #define MDB_SHEXP_DEFAULT (MDB_SHEXP_CST_NOTNULL | MDB_SHEXP_COMMENTS | MDB_SHEXP_INDEXES | MDB_SHEXP_RELATIONS)
205 /* csv export binary options */
210 MDB_BINEXPORT_HEXADECIMAL
,
212 /* Flags that can be OR'ed into the above when calling mdb_print_col */
213 MDB_EXPORT_ESCAPE_CONTROL_CHARS
= (1 << 4)
216 #define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4) /* obsolete */
217 #define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)
219 /* forward declarations */
220 typedef struct mdbindex MdbIndex
;
221 typedef struct mdbsargtree MdbSargNode
;
225 unsigned char needs_precision
;
226 unsigned char needs_scale
;
227 unsigned char needs_byte_length
;
228 unsigned char needs_char_length
;
232 guint32 capabilities
; /* see MDB_SHEXP_* */
233 const MdbBackendType
*types_table
;
234 const MdbBackendType
*type_shortdate
;
235 const MdbBackendType
*type_autonum
;
236 const char *short_now
;
237 const char *long_now
;
238 const char *date_fmt
;
239 const char *shortdate_fmt
;
240 const char *charset_statement
;
241 const char *drop_statement
;
242 const char *constaint_not_empty_statement
;
243 const char *column_comment_statement
;
244 const char *per_column_comment_statement
;
245 const char *table_comment_statement
;
246 const char *per_table_comment_statement
;
247 gchar
* (*quote_schema_name
)(const gchar
*, const gchar
*);
248 const char *create_table_statement
;
249 gchar
* (*normalise_case
)(const gchar
*);
254 unsigned long pg_reads
;
263 MdbStatistics
*stats
;
266 unsigned char *free_map
;
267 /* reference count */
273 /* offset to row count on data pages...version dependant */
276 guint16 row_count_offset
;
277 guint16 tab_num_rows_offset
;
278 guint16 tab_num_cols_offset
;
279 guint16 tab_num_idxs_offset
;
280 guint16 tab_num_ridxs_offset
;
281 guint16 tab_usage_map_offset
;
282 guint16 tab_first_dpg_offset
;
283 guint16 tab_cols_start_offset
;
284 guint16 tab_ridx_entry_size
;
285 guint16 col_flags_offset
;
286 guint16 col_size_offset
;
287 guint16 col_num_offset
;
288 guint16 tab_col_entry_size
;
289 guint16 tab_free_map_offset
;
290 guint16 tab_col_offset_var
;
291 guint16 tab_col_offset_fixed
;
292 guint16 tab_row_col_num_offset
;
293 guint16 col_scale_offset
;
294 guint16 col_prec_offset
;
295 } MdbFormatConstants
;
301 unsigned int cur_pos
;
302 unsigned char pg_buf
[MDB_PGSIZE
];
303 unsigned char alt_pg_buf
[MDB_PGSIZE
];
304 MdbFormatConstants
*fmt
;
307 char shortdate_fmt
[64];
308 MdbUuidFormat repid_fmt
;
309 const char *boolean_false_value
;
310 const char *boolean_true_value
;
311 unsigned int num_catalog
;
313 // Non-cloneable fields start here
315 MdbBackend
*default_backend
;
317 struct S_MdbTableDef
*relationships_table
;
318 char *relationships_values
[5];
319 MdbStatistics
*stats
;
320 GHashTable
*backends
;
321 #if MDBTOOLS_H_HAVE_ICONV_H
331 char object_name
[MDB_MAX_OBJ_NAME
+1];
333 unsigned long table_pg
; /* misnomer since object may not be a table */
334 //int num_props; please use props->len
335 GPtrArray
*props
; /* GPtrArray of MdbProperties */
350 struct S_MdbTableDef
; /* forward definition */
352 struct S_MdbTableDef
*table
;
353 char name
[MDB_MAX_OBJ_NAME
+1];
358 GHashTable
*properties
;
359 unsigned int num_sargs
;
361 GPtrArray
*idx_sarg_cache
;
362 unsigned char is_fixed
;
364 /* col_num is the current column order,
365 * does not include deletes */
369 /* MEMO/OLE readers */
370 guint32 cur_blob_pg_row
;
375 unsigned char is_long_auto
;
376 unsigned char is_uuid_auto
;
377 MdbProperties
*props
;
378 /* info needed for handling deleted/added columns */
380 unsigned int var_col_num
;
381 /* row_col_num is the row column number order,
382 * including deleted columns */
389 unsigned char val_type
;
402 guint16 idx_starts
[2000];
403 unsigned char cache_value
[256];
406 typedef int (*MdbSargTreeFunc
)(MdbSargNode
*, gpointer data
);
408 #define MDB_MAX_INDEX_DEPTH 10
412 guint32 last_leaf_found
;
414 MdbIndexPage pages
[MDB_MAX_INDEX_DEPTH
];
417 typedef struct S_MdbTableDef
{
418 MdbCatalogEntry
*entry
;
419 char name
[MDB_MAX_OBJ_NAME
+1];
420 unsigned int num_cols
;
422 unsigned int num_rows
;
424 unsigned int num_real_idxs
;
425 unsigned int num_idxs
;
427 guint32 first_data_pg
;
430 unsigned int cur_row
;
431 int noskip_del
; /* don't skip deleted rows */
432 /* object allocation map */
435 unsigned char *usage_map
;
436 /* pages with free space left */
437 guint32 freemap_base_pg
;
439 unsigned char *free_usage_map
;
441 MdbSargNode
*sarg_tree
;
442 MdbStrategy strategy
;
445 MdbIndexChain
*chain
;
446 MdbProperties
*props
;
447 unsigned int num_var_cols
; /* to know if row has variable columns */
449 unsigned int is_temp_table
;
450 GPtrArray
*temp_table_pages
;
455 char name
[MDB_MAX_OBJ_NAME
+1];
456 unsigned char index_type
;
458 int num_rows
; /* number rows in index */
459 unsigned int num_keys
;
460 short key_col_num
[MDB_MAX_IDX_COLS
];
461 unsigned char key_col_order
[MDB_MAX_IDX_COLS
];
467 char name
[MDB_MAX_OBJ_NAME
+1];
474 unsigned char is_null
;
475 unsigned char is_fixed
;
486 const char *mdb_get_version(void);
489 ssize_t
mdb_read_pg(MdbHandle
*mdb
, unsigned long pg
);
490 ssize_t
mdb_read_alt_pg(MdbHandle
*mdb
, unsigned long pg
);
491 unsigned char mdb_get_byte(void *buf
, int offset
);
492 int mdb_get_int16(void *buf
, int offset
);
493 long mdb_get_int32(void *buf
, int offset
);
494 long mdb_get_int32_msb(void *buf
, int offset
);
495 float mdb_get_single(void *buf
, int offset
);
496 double mdb_get_double(void *buf
, int offset
);
497 unsigned char mdb_pg_get_byte(MdbHandle
*mdb
, int offset
);
498 int mdb_pg_get_int16(MdbHandle
*mdb
, int offset
);
499 long mdb_pg_get_int32(MdbHandle
*mdb
, int offset
);
500 float mdb_pg_get_single(MdbHandle
*mdb
, int offset
);
501 double mdb_pg_get_double(MdbHandle
*mdb
, int offset
);
502 MdbHandle
*mdb_open(const char *filename
, MdbFileFlags flags
);
503 MdbHandle
*mdb_open_buffer(void *buffer
, size_t len
, MdbFileFlags flags
);
504 void mdb_close(MdbHandle
*mdb
);
505 MdbHandle
*mdb_clone_handle(MdbHandle
*mdb
);
506 void mdb_swap_pgbuf(MdbHandle
*mdb
);
509 void mdb_free_catalog(MdbHandle
*mdb
);
510 GPtrArray
*mdb_read_catalog(MdbHandle
*mdb
, int obj_type
);
511 MdbCatalogEntry
*mdb_get_catalogentry_by_name(MdbHandle
*mdb
, const gchar
* name
);
512 void mdb_dump_catalog(MdbHandle
*mdb
, int obj_type
);
513 const char *mdb_get_objtype_string(int obj_type
);
516 MdbTableDef
*mdb_alloc_tabledef(MdbCatalogEntry
*entry
);
517 void mdb_free_tabledef(MdbTableDef
*table
);
518 MdbTableDef
*mdb_read_table(MdbCatalogEntry
*entry
);
519 MdbTableDef
*mdb_read_table_by_name(MdbHandle
*mdb
, gchar
*table_name
, int obj_type
);
520 void mdb_append_column(GPtrArray
*columns
, MdbColumn
*in_col
);
521 void mdb_free_columns(GPtrArray
*columns
);
522 GPtrArray
*mdb_read_columns(MdbTableDef
*table
);
523 void mdb_table_dump(MdbCatalogEntry
*entry
);
524 guint8
read_pg_if_8(MdbHandle
*mdb
, int *cur_pos
);
525 guint16
read_pg_if_16(MdbHandle
*mdb
, int *cur_pos
);
526 guint32
read_pg_if_32(MdbHandle
*mdb
, int *cur_pos
);
527 void *read_pg_if_n(MdbHandle
*mdb
, void *buf
, int *cur_pos
, size_t len
);
528 int mdb_is_user_table(MdbCatalogEntry
*entry
);
529 int mdb_is_system_table(MdbCatalogEntry
*entry
);
530 const char *mdb_table_get_prop(const MdbTableDef
*table
, const gchar
*key
);
531 const char *mdb_col_get_prop(const MdbColumn
*col
, const gchar
*key
);
532 int mdb_col_is_shortdate(const MdbColumn
*col
);
535 int mdb_bind_column_by_name(MdbTableDef
*table
, gchar
*col_name
, void *bind_ptr
, int *len_ptr
);
536 void mdb_data_dump(MdbTableDef
*table
);
537 void mdb_date_to_tm(double td
, struct tm
*t
);
538 void mdb_tm_to_date(struct tm
*t
, double *td
);
539 char *mdb_uuid_to_string(const void *buf
, int start
); /* Uses default MDB_BRACES_4_2_2_8 format */
540 char *mdb_uuid_to_string_fmt(const void *buf
, int start
, MdbUuidFormat format
);
541 int mdb_bind_column(MdbTableDef
*table
, int col_num
, void *bind_ptr
, int *len_ptr
);
542 int mdb_rewind_table(MdbTableDef
*table
);
543 int mdb_fetch_row(MdbTableDef
*table
);
544 int mdb_is_fixed_col(MdbColumn
*col
);
545 char *mdb_col_to_string(MdbHandle
*mdb
, void *buf
, int start
, int datatype
, int size
);
546 int mdb_find_pg_row(MdbHandle
*mdb
, int pg_row
, void **buf
, int *off
, size_t *len
);
547 int mdb_find_row(MdbHandle
*mdb
, int row
, int *start
, size_t *len
);
548 int mdb_find_end_of_row(MdbHandle
*mdb
, int row
);
549 int mdb_col_fixed_size(MdbColumn
*col
);
550 int mdb_col_disp_size(MdbColumn
*col
);
551 size_t mdb_ole_read_next(MdbHandle
*mdb
, MdbColumn
*col
, void *ole_ptr
);
552 size_t mdb_ole_read(MdbHandle
*mdb
, MdbColumn
*col
, void *ole_ptr
, size_t chunk_size
);
553 void* mdb_ole_read_full(MdbHandle
*mdb
, MdbColumn
*col
, size_t *size
);
554 void mdb_set_bind_size(MdbHandle
*mdb
, size_t bind_size
);
555 void mdb_set_date_fmt(MdbHandle
*mdb
, const char *);
556 void mdb_set_shortdate_fmt(MdbHandle
*mdb
, const char *);
557 void mdb_set_repid_fmt(MdbHandle
*mdb
, MdbUuidFormat format
);
558 void mdb_set_boolean_fmt_words(MdbHandle
*mdb
);
559 void mdb_set_boolean_fmt_numbers(MdbHandle
*mdb
);
560 int mdb_read_row(MdbTableDef
*table
, unsigned int row
);
561 int mdb_read_next_dpg(MdbTableDef
*table
);
564 char *mdb_money_to_string(MdbHandle
*mdb
, int start
);
565 char *mdb_numeric_to_string(MdbHandle
*mdb
, int start
, int scale
, int prec
);
568 void mdb_buffer_dump(const void *buf
, off_t start
, size_t len
);
571 void mdb_init_backends(MdbHandle
*mdb
);
572 void mdb_remove_backends(MdbHandle
*mdb
);
573 const MdbBackendType
* mdb_get_colbacktype(const MdbColumn
*col
);
574 const char* mdb_get_colbacktype_string(const MdbColumn
*col
);
575 int mdb_colbacktype_takes_length(const MdbColumn
*col
);
576 void mdb_register_backend(MdbHandle
*mdb
, char *backend_name
, guint32 capabilities
,
577 const MdbBackendType
*backend_type
,
578 const MdbBackendType
*type_shortdate
,
579 const MdbBackendType
*type_autonum
,
580 const char *short_now
, const char *long_now
,
581 const char *date_fmt
, const char *shortdate_fmt
,
582 const char *charset_statement
, const char *drop_statement
, const char *constaint_not_empty_statement
,
583 const char *column_comment_statement
, const char *per_column_comment_statement
,
584 const char *table_comment_statement
, const char *per_table_comment_statement
,
585 gchar
* (*quote_schema_name
)(const gchar
*, const gchar
*));
586 int mdb_set_default_backend(MdbHandle
*mdb
, const char *backend_name
);
587 int mdb_print_schema(MdbHandle
*mdb
, FILE *outfile
, char *tabname
, char *dbnamespace
, guint32 export_options
);
588 void mdb_print_col(FILE *outfile
, gchar
*col_val
, int quote_text
, int col_type
, int bin_len
, char *quote_char
, char *escape_char
, int flags
);
589 gchar
*mdb_normalise_and_replace(MdbHandle
*mdb
, gchar
**str
);
592 int mdb_test_sargs(MdbTableDef
*table
, MdbField
*fields
, int num_fields
);
593 int mdb_test_sarg(MdbHandle
*mdb
, MdbColumn
*col
, MdbSargNode
*node
, MdbField
*field
);
594 void mdb_sql_walk_tree(MdbSargNode
*node
, MdbSargTreeFunc func
, gpointer data
);
595 int mdb_find_indexable_sargs(MdbSargNode
*node
, gpointer data
);
596 int mdb_add_sarg_by_name(MdbTableDef
*table
, char *colname
, MdbSarg
*in_sarg
);
597 int mdb_test_string(MdbSargNode
*node
, char *s
);
598 int mdb_test_int(MdbSargNode
*node
, gint32 i
);
599 int mdb_add_sarg(MdbColumn
*col
, MdbSarg
*in_sarg
);
604 GPtrArray
*mdb_read_indices(MdbTableDef
*table
);
605 void mdb_index_dump(MdbTableDef
*table
, MdbIndex
*idx
);
606 void mdb_index_scan_free(MdbTableDef
*table
);
607 int mdb_index_find_next_on_page(MdbHandle
*mdb
, MdbIndexPage
*ipg
);
608 int mdb_index_find_next(MdbHandle
*mdb
, MdbIndex
*idx
, MdbIndexChain
*chain
, guint32
*pg
, guint16
*row
);
609 void mdb_index_hash_text(MdbHandle
*mdb
, char *text
, char *hash
);
610 void mdb_index_scan_init(MdbHandle
*mdb
, MdbTableDef
*table
);
611 int mdb_index_find_row(MdbHandle
*mdb
, MdbIndex
*idx
, MdbIndexChain
*chain
, guint32 pg
, guint16 row
);
612 void mdb_index_swap_n(unsigned char *src
, int sz
, unsigned char *dest
);
613 void mdb_free_indices(GPtrArray
*indices
);
614 void mdb_index_page_reset(MdbHandle
*mdb
, MdbIndexPage
*ipg
);
615 int mdb_index_pack_bitmap(MdbHandle
*mdb
, MdbIndexPage
*ipg
);
618 void mdb_stats_on(MdbHandle
*mdb
);
619 void mdb_stats_off(MdbHandle
*mdb
);
620 void mdb_dump_stats(MdbHandle
*mdb
);
623 int mdb_like_cmp(char *s
, char *r
);
624 int mdb_ilike_cmp(char *s
, char *r
);
627 void mdb_put_int16(void *buf
, guint32 offset
, guint32 value
);
628 void mdb_put_int32(void *buf
, guint32 offset
, guint32 value
);
629 void mdb_put_int32_msb(void *buf
, guint32 offset
, guint32 value
);
630 int mdb_crack_row(MdbTableDef
*table
, int row_start
, size_t row_size
, MdbField
*fields
);
631 guint16
mdb_add_row_to_pg(MdbTableDef
*table
, unsigned char *row_buffer
, int new_row_size
);
632 int mdb_update_index(MdbTableDef
*table
, MdbIndex
*idx
, unsigned int num_fields
, MdbField
*fields
, guint32 pgnum
, guint16 rownum
);
633 int mdb_insert_row(MdbTableDef
*table
, int num_fields
, MdbField
*fields
);
634 int mdb_pack_row(MdbTableDef
*table
, unsigned char *row_buffer
, unsigned int num_fields
, MdbField
*fields
);
635 int mdb_replace_row(MdbTableDef
*table
, int row
, void *new_row
, int new_row_size
);
636 int mdb_pg_get_freespace(MdbHandle
*mdb
);
637 int mdb_update_row(MdbTableDef
*table
);
638 void *mdb_new_data_pg(MdbCatalogEntry
*entry
);
641 gint32
mdb_map_find_next_freepage(MdbTableDef
*table
, int row_size
);
642 gint32
mdb_map_find_next(MdbHandle
*mdb
, unsigned char *map
, unsigned int map_sz
, guint32 start_pg
);
645 void mdb_free_props(MdbProperties
*props
);
646 void mdb_dump_props(MdbProperties
*props
, FILE *outfile
, int show_name
);
647 GPtrArray
* mdb_kkd_to_props(MdbHandle
*mdb
, void *kkd
, size_t len
);
651 MdbTableDef
*mdb_create_temp_table(MdbHandle
*mdb
, char *name
);
652 void mdb_temp_table_add_col(MdbTableDef
*table
, MdbColumn
*col
);
653 void mdb_fill_temp_col(MdbColumn
*tcol
, char *col_name
, int col_size
, int col_type
, int is_fixed
);
654 void mdb_fill_temp_field(MdbField
*field
, void *value
, int siz
, int is_fixed
, int is_null
, int start
, int column
);
655 void mdb_temp_columns_end(MdbTableDef
*table
);
658 int mdb_get_option(unsigned long optnum
);
659 void mdb_debug(int klass
, char *fmt
, ...);
662 int mdb_unicode2ascii(MdbHandle
*mdb
, const char *src
, size_t slen
, char *dest
, size_t dlen
);
663 int mdb_ascii2unicode(MdbHandle
*mdb
, const char *src
, size_t slen
, char *dest
, size_t dlen
);
664 void mdb_iconv_init(MdbHandle
*mdb
);
665 void mdb_iconv_close(MdbHandle
*mdb
);
666 const char* mdb_target_charset(MdbHandle
*mdb
);
674 #endif /* _mdbtools_h_ */