[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kexi] src/migration/mdb: MDB Import: Update to mdbtools from June 2014
From: Jaroslaw Staniek <staniek () kde ! org>
Date: 2016-02-29 23:12:19
Message-ID: E1aaWzD-0000sv-UI () scm ! kde ! org
[Download RAW message or body]
Git commit 5a2ab83ab935d3710ea9daa924427e75a833f247 by Jaroslaw Staniek.
Committed on 29/02/2016 at 23:07.
Pushed by staniek into branch 'master'.
MDB Import: Update to mdbtools from June 2014
BUG:277583
This also fixes primary keys import
BUG:336560
FIXED-IN:2.9.11
Test Plan: Northwind database imports properly with keys, try e.g. from \
http://www.2013.net/courses/access/
Differential Revision: https://phabricator.kde.org/D855
(from calligra.git)
M +92 -38 src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h
M +53 -18 src/migration/mdb/3rdparty/mdbtools/libmdb/catalog.c
M +201 -131 src/migration/mdb/3rdparty/mdbtools/libmdb/data.c
M +19 -1 src/migration/mdb/3rdparty/mdbtools/libmdb/dump.c
M +132 -12 src/migration/mdb/3rdparty/mdbtools/libmdb/file.c
M +41 -21 src/migration/mdb/3rdparty/mdbtools/libmdb/iconv.c
M +122 -78 src/migration/mdb/3rdparty/mdbtools/libmdb/index.c
M +3 -4 src/migration/mdb/3rdparty/mdbtools/libmdb/like.c
M +13 -8 src/migration/mdb/3rdparty/mdbtools/libmdb/map.c
M +9 -34 src/migration/mdb/3rdparty/mdbtools/libmdb/mem.c
M +53 -24 src/migration/mdb/3rdparty/mdbtools/libmdb/money.c
M +22 -22 src/migration/mdb/3rdparty/mdbtools/libmdb/options.c
A +215 -0 src/migration/mdb/3rdparty/mdbtools/libmdb/props.c [License: LGPL \
(v2+)] M +53 -8 src/migration/mdb/3rdparty/mdbtools/libmdb/sargs.c
A +77 -0 src/migration/mdb/3rdparty/mdbtools/libmdb/stats.c [License: LGPL \
(v2+)] M +86 -39 src/migration/mdb/3rdparty/mdbtools/libmdb/table.c
M +3 -3 src/migration/mdb/3rdparty/mdbtools/libmdb/worktable.c
M +113 -78 src/migration/mdb/3rdparty/mdbtools/libmdb/write.c
D +0 -7 src/migration/mdb/3rdparty/mdbtools/update_diffs.sh
M +4 -0 src/migration/mdb/ChangeLog
M +6 -1 src/migration/mdb/src/CMakeLists.txt
M +6 -21 src/migration/mdb/src/keximdb/mdbmigrate.cpp
M +1 -4 src/migration/mdb/src/keximdb/mdbmigrate.h
http://commits.kde.org/kexi/5a2ab83ab935d3710ea9daa924427e75a833f247
diff --git a/src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h \
b/src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h index 0c69c18..68b326f \
100644
--- a/src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h
+++ b/src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h
@@ -12,9 +12,8 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _mdbtools_h_
#define _mdbtools_h_
@@ -33,14 +32,18 @@
#include <string.h>
#include <glib.h>
-
#ifdef HAVE_ICONV
#include <iconv.h>
#endif
+#ifdef _WIN32
+#include <io.h>
+#endif
+
#define MDB_DEBUG 0
#define MDB_PGSIZE 4096
+//#define MDB_MAX_OBJ_NAME (256*3) /* unicode 16 -> utf-8 worst case */
#define MDB_MAX_OBJ_NAME 256
#define MDB_MAX_COLS 256
#define MDB_MAX_IDX_COLS 10
@@ -51,6 +54,11 @@
#define MDB_NO_BACKENDS 1
#define MDB_NO_STATS 1
+// Theses 2 atrbutes are not supported by all compilers:
+// M$VC see http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
+#define MDB_DEPRECATED(type, funcname) type __attribute__((deprecated)) funcname
+#define MDB_CONSTRUCTOR(funcname) void __attribute__((constructor)) funcname()
+
enum {
MDB_PAGE_DB = 0,
MDB_PAGE_DATA,
@@ -61,7 +69,9 @@ enum {
};
enum {
MDB_VER_JET3 = 0,
- MDB_VER_JET4 = 1
+ MDB_VER_JET4 = 1,
+ MDB_VER_ACCDB_2007 = 0x02,
+ MDB_VER_ACCDB_2010 = 0x0103
};
enum {
MDB_FORM = 0,
@@ -74,7 +84,7 @@ enum {
MDB_MODULE,
MDB_RELATIONSHIP,
MDB_UNKNOWN_09,
- MDB_UNKNOWN_0A,
+ MDB_UNKNOWN_0A, /* User access */
MDB_DATABASE_PROPERTY,
MDB_ANY = -1
};
@@ -86,12 +96,14 @@ enum {
MDB_MONEY = 0x05,
MDB_FLOAT = 0x06,
MDB_DOUBLE = 0x07,
- MDB_SDATETIME = 0x08,
+ MDB_DATETIME = 0x08,
+ MDB_BINARY = 0x09,
MDB_TEXT = 0x0a,
MDB_OLE = 0x0b,
MDB_MEMO = 0x0c,
MDB_REPID = 0x0f,
- MDB_NUMERIC = 0x10
+ MDB_NUMERIC = 0x10,
+ MDB_COMPLEX = 0x12
};
/* SARG operators */
@@ -126,8 +138,9 @@ enum {
MDB_DEBUG_USAGE = 0x0004,
MDB_DEBUG_OLE = 0x0008,
MDB_DEBUG_ROW = 0x0010,
- MDB_USE_INDEX = 0x0020,
- MDB_NO_MEMO = 0x0040 /* don't follow memo fields */
+ MDB_DEBUG_PROPS = 0x0020,
+ MDB_USE_INDEX = 0x0040,
+ MDB_NO_MEMO = 0x0080, /* don't follow memo fields */
};
#define mdb_is_logical_op(x) (x == MDB_OR || \
@@ -154,13 +167,27 @@ enum {
MDB_IDX_REQUIRED = 0x08
};
-#define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4)
-#define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)
+/* export schema options */
+enum {
+ MDB_SHEXP_DROPTABLE = 1<<0, /* issue drop table during export */
+ MDB_SHEXP_CST_NOTNULL = 1<<1, /* generate NOT NULL constraints */
+ MDB_SHEXP_CST_NOTEMPTY = 1<<2, /* <>'' constraints */
+ MDB_SHEXP_COMMENTS = 1<<3, /* export comments on columns & tables */
+ MDB_SHEXP_DEFVALUES = 1<<4, /* export default values */
+ MDB_SHEXP_INDEXES = 1<<5, /* export indices */
+ MDB_SHEXP_RELATIONS = 1<<6 /* export relation (foreign keys) */
+};
+#define MDB_SHEXP_DEFAULT (MDB_SHEXP_CST_NOTNULL | MDB_SHEXP_COMMENTS | \
MDB_SHEXP_INDEXES | MDB_SHEXP_RELATIONS)
-#if !MDB_NO_BACKENDS
-/* hash to store registered backends */
-extern GHashTable *mdb_backends;
-#endif
+/* csv export binary options */
+enum {
+ MDB_BINEXPORT_STRIP,
+ MDB_BINEXPORT_RAW,
+ MDB_BINEXPORT_OCTAL
+};
+
+#define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4) /* obsolete */
+#define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)
/* forward declarations */
typedef struct mdbindex MdbIndex;
@@ -175,7 +202,18 @@ typedef struct {
} MdbBackendType;
typedef struct {
- MdbBackendType *types_table;
+ guint32 capabilities; /* see MDB_SHEXP_* */
+ MdbBackendType *types_table;
+ 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*);
} MdbBackend;
#endif
@@ -219,7 +257,7 @@ typedef struct {
guint16 tab_first_dpg_offset;
guint16 tab_cols_start_offset;
guint16 tab_ridx_entry_size;
- guint16 col_fixed_offset;
+ guint16 col_flags_offset;
guint16 col_size_offset;
guint16 col_num_offset;
guint16 tab_col_entry_size;
@@ -258,10 +296,8 @@ typedef struct {
char object_name[MDB_MAX_OBJ_NAME+1];
int object_type;
unsigned long table_pg; /* misnomer since object may not be a table */
- unsigned long kkd_pg;
- unsigned int kkd_rowid;
- int num_props;
- GArray *props;
+ //int num_props; please use props->len
+ GArray *props; /* GArray of MdbProperties */
GArray *columns;
int flags;
} MdbCatalogEntry;
@@ -277,7 +313,9 @@ typedef union {
char s[256];
} MdbAny;
+struct S_MdbTableDef; /* forward definition */
typedef struct {
+ struct S_MdbTableDef *table;
char name[MDB_MAX_OBJ_NAME+1];
int col_type;
int col_size;
@@ -300,6 +338,8 @@ typedef struct {
/* numerics only */
int col_prec;
int col_scale;
+ unsigned char is_long_auto;
+ unsigned char is_uuid_auto;
MdbProperties *props;
/* info needed for handling deleted/added columns */
int fixed_offset;
@@ -338,7 +378,7 @@ typedef struct {
MdbIndexPage pages[MDB_MAX_INDEX_DEPTH];
} MdbIndexChain;
-typedef struct {
+typedef struct S_MdbTableDef {
MdbCatalogEntry *entry;
char name[MDB_MAX_OBJ_NAME+1];
unsigned int num_cols;
@@ -407,8 +447,8 @@ typedef struct {
} MdbSarg;
/* mem.c */
-extern void mdb_init();
-extern void mdb_exit();
+extern MDB_DEPRECATED(void, mdb_init());
+extern MDB_DEPRECATED(void, mdb_exit());
/* file.c */
extern ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg);
@@ -433,8 +473,9 @@ extern void mdb_swap_pgbuf(MdbHandle *mdb);
/* catalog.c */
extern void mdb_free_catalog(MdbHandle *mdb);
extern GPtrArray *mdb_read_catalog(MdbHandle *mdb, int obj_type);
+MdbCatalogEntry *mdb_get_catalogentry_by_name(MdbHandle *mdb, const gchar* name);
extern void mdb_dump_catalog(MdbHandle *mdb, int obj_type);
-extern char *mdb_get_objtype_string(int obj_type);
+extern const char *mdb_get_objtype_string(int obj_type);
/* table.c */
extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry);
@@ -451,10 +492,13 @@ extern guint32 read_pg_if_32(MdbHandle *mdb, int *cur_pos);
extern void *read_pg_if_n(MdbHandle *mdb, void *buf, int *cur_pos, size_t len);
extern int mdb_is_user_table(MdbCatalogEntry *entry);
extern int mdb_is_system_table(MdbCatalogEntry *entry);
+extern const char *mdb_table_get_prop(const MdbTableDef *table, const gchar *key);
+extern const char *mdb_col_get_prop(const MdbColumn *col, const gchar *key);
/* data.c */
-extern int mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void \
*bind_ptr, int *len_ptr); +extern int mdb_bind_column_by_name(MdbTableDef *table, \
const gchar *col_name, void *bind_ptr, int *len_ptr); extern void \
mdb_data_dump(MdbTableDef *table); +extern void mdb_date_to_tm(double td, struct tm \
*t); extern void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr, \
int *len_ptr); extern int mdb_rewind_table(MdbTableDef *table);
extern int mdb_fetch_row(MdbTableDef *table);
@@ -467,21 +511,25 @@ extern int mdb_col_fixed_size(MdbColumn *col);
extern int mdb_col_disp_size(MdbColumn *col);
extern size_t mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr);
extern size_t mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int \
chunk_size); +extern void* mdb_ole_read_full(MdbHandle *mdb, MdbColumn *col, size_t \
*size); extern void mdb_set_date_fmt(const char *);
extern int mdb_read_row(MdbTableDef *table, unsigned int row);
/* dump.c */
-extern void buffer_dump(const void *buf, int start, size_t len);
+extern void mdb_buffer_dump(const void *buf, int start, size_t len);
#if !MDB_NO_BACKENDS
/* backend.c */
-extern char *mdb_get_coltype_string(MdbBackend *backend, int col_type);
-extern int mdb_coltype_takes_length(MdbBackend *backend, int col_type);
-extern void mdb_init_backends();
-extern void mdb_register_backend(MdbBackendType *backend, char *backend_name);
-extern void mdb_remove_backends();
+extern MDB_DEPRECATED(char*, mdb_get_coltype_string(MdbBackend *backend, int \
col_type)); +extern MDB_DEPRECATED(int, mdb_coltype_takes_length(MdbBackend *backend, \
int col_type)); +extern const MdbBackendType* mdb_get_colbacktype(const MdbColumn \
*col); +extern const char* mdb_get_colbacktype_string(const MdbColumn *col);
+extern int mdb_colbacktype_takes_length(const MdbColumn *col);
+extern MDB_DEPRECATED(void, mdb_init_backends());
+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*)); \
+extern MDB_DEPRECATED(void, mdb_remove_backends()); extern int \
mdb_set_default_backend(MdbHandle *mdb, const char *backend_name);
-extern char *mdb_get_relationships(MdbHandle *mdb);
+extern void mdb_print_schema(MdbHandle *mdb, FILE *outfile, char *tabname, char \
*dbnamespace, guint32 export_options); #endif
/* sargs.c */
@@ -521,9 +569,13 @@ extern void mdb_dump_stats(MdbHandle *mdb);
extern int mdb_like_cmp(char *s, char *r);
/* write.c */
+extern void mdb_put_int16(void *buf, guint32 offset, guint32 value);
+extern void mdb_put_int32(void *buf, guint32 offset, guint32 value);
+extern void mdb_put_int32_msb(void *buf, guint32 offset, guint32 value);
extern int mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField \
*fields); extern guint16 mdb_add_row_to_pg(MdbTableDef *table, unsigned char \
*row_buffer, int new_row_size); extern int mdb_update_index(MdbTableDef *table, \
MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 \
rownum); +extern int mdb_insert_row(MdbTableDef *table, int num_fields, MdbField \
*fields); extern int mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, \
unsigned int num_fields, MdbField *fields); extern int mdb_replace_row(MdbTableDef \
*table, int row, void *new_row, int new_row_size); extern int \
mdb_pg_get_freespace(MdbHandle *mdb); @@ -532,12 +584,13 @@ extern void \
*mdb_new_data_pg(MdbCatalogEntry *entry);
/* map.c */
extern guint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size);
-extern guint32 mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int \
map_sz, guint32 start_pg); +extern gint32 mdb_map_find_next(MdbHandle *mdb, unsigned \
char *map, unsigned int map_sz, guint32 start_pg);
/* props.c */
-extern GPtrArray *mdb_read_props_list(gchar *kkd, int len);
extern void mdb_free_props(MdbProperties *props);
-extern MdbProperties *mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, \
int len); +extern void mdb_dump_props(MdbProperties *props, FILE *outfile, int \
show_name); +extern GArray* mdb_kkd_to_props(MdbHandle *mdb, void *kkd, size_t len);
+
/* worktable.c */
extern MdbTableDef *mdb_create_temp_table(MdbHandle *mdb, char *name);
@@ -548,13 +601,14 @@ extern void mdb_temp_columns_end(MdbTableDef *table);
/* options.c */
extern int mdb_get_option(unsigned long optnum);
-extern void mdb_debug(int klass, char *fmt, ...);
+extern void mdb_debug(int klass, const char *fmt, ...);
/* iconv.c */
extern int mdb_unicode2ascii(MdbHandle *mdb, char *src, size_t slen, char *dest, \
size_t dlen); extern int mdb_ascii2unicode(MdbHandle *mdb, char *src, size_t slen, \
char *dest, size_t dlen); extern void mdb_iconv_init(MdbHandle *mdb);
extern void mdb_iconv_close(MdbHandle *mdb);
+extern const char* mdb_target_charset(MdbHandle *mdb);
#ifdef __cplusplus
}
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/catalog.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/catalog.c index a857ccf..4736652 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/catalog.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/catalog.c
@@ -12,9 +12,8 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mdbtools.h"
@@ -23,10 +22,10 @@
#include "dmalloc.h"
#endif
-char *
+const char *
mdb_get_objtype_string(int obj_type)
{
-static char *type_name[] = {"Form",
+static const char *type_name[] = {"Form",
"Table",
"Macro",
"System Table",
@@ -36,7 +35,7 @@ static char *type_name[] = {"Form",
"Module",
"Relationship",
"Unknown 0x09",
- "Unknown 0x0a",
+ "User Info",
"Database"
};
@@ -49,11 +48,21 @@ static char *type_name[] = {"Form",
void mdb_free_catalog(MdbHandle *mdb)
{
- unsigned int i;
+ unsigned int i, j;
+ MdbCatalogEntry *entry;
if ((!mdb) || (!mdb->catalog)) return;
- for (i=0; i<mdb->catalog->len; i++)
- g_free (g_ptr_array_index(mdb->catalog, i));
+ for (i=0; i<mdb->catalog->len; i++) {
+ entry = (MdbCatalogEntry *)g_ptr_array_index(mdb->catalog, i);
+ if (entry) {
+ if (entry->props) {
+ for (j=0; j<entry->props->len; j++)
+ mdb_free_props(g_array_index(entry->props, MdbProperties*, j));
+ g_array_free(entry->props, TRUE);
+ }
+ g_free(entry);
+ }
+ }
g_ptr_array_free(mdb->catalog, TRUE);
mdb->catalog = NULL;
}
@@ -63,10 +72,14 @@ GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
MdbCatalogEntry *entry, msysobj;
MdbTableDef *table;
char obj_id[256];
- char obj_name[256];
+ char obj_name[MDB_MAX_OBJ_NAME];
char obj_type[256];
char obj_flags[256];
+ char obj_props[MDB_BIND_SIZE];
int type;
+ unsigned int i;
+ MdbColumn *col_props;
+ int kkd_size_ole;
if (!mdb) return NULL;
if (mdb->catalog) mdb_free_catalog(mdb);
@@ -91,14 +104,16 @@ GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
mdb_bind_column_by_name(table, "Name", obj_name, NULL);
mdb_bind_column_by_name(table, "Type", obj_type, NULL);
mdb_bind_column_by_name(table, "Flags", obj_flags, NULL);
+ i = mdb_bind_column_by_name(table, "LvProp", obj_props, &kkd_size_ole);
+ col_props = g_ptr_array_index(table->columns, i-1);
mdb_rewind_table(table);
while (mdb_fetch_row(table)) {
type = atoi(obj_type);
if (objtype==MDB_ANY || type == objtype) {
-
-
+ //fprintf(stderr, "obj_id: %10ld objtype: %-3d (0x%04x) obj_name: %s\n",
+ // (atol(obj_id) & 0x00FFFFFF), type, type, obj_name);
entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
entry->mdb = mdb;
strcpy(entry->object_name, obj_name);
@@ -107,15 +122,37 @@ GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
entry->flags = atol(obj_flags);
mdb->num_catalog++;
g_ptr_array_add(mdb->catalog, entry);
+ if (kkd_size_ole) {
+ size_t kkd_len;
+ void *kkd = mdb_ole_read_full(mdb, col_props, &kkd_len);
+ //mdb_buffer_dump(kkd, 0, kkd_len);
+ entry->props = mdb_kkd_to_props(mdb, kkd, kkd_len);
+ free(kkd);
+ }
}
}
-
+ //mdb_dump_catalog(mdb, MDB_TABLE);
mdb_free_tabledef(table);
return mdb->catalog;
}
+
+MdbCatalogEntry *
+mdb_get_catalogentry_by_name(MdbHandle *mdb, const gchar* name)
+{
+ unsigned int i;
+ MdbCatalogEntry *entry;
+
+ for (i=0; i<mdb->num_catalog; i++) {
+ entry = g_ptr_array_index(mdb->catalog, i);
+ if (!strcasecmp(entry->object_name, name))
+ return entry;
+ }
+ return NULL;
+}
+
void
mdb_dump_catalog(MdbHandle *mdb, int obj_type)
{
@@ -126,14 +163,12 @@ mdb_dump_catalog(MdbHandle *mdb, int obj_type)
for (i=0;i<mdb->num_catalog;i++) {
entry = g_ptr_array_index(mdb->catalog,i);
if (obj_type==MDB_ANY || entry->object_type==obj_type) {
- fprintf(stdout,"Type: %-10s Name: %-18s T pg: %04x KKD pg: %04x row: %2d\n",
+ printf("Type: %-12s Name: %-48s Page: %06lx\n",
mdb_get_objtype_string(entry->object_type),
entry->object_name,
- (unsigned int) entry->table_pg,
- (unsigned int) entry->kkd_pg,
- entry->kkd_rowid);
+ entry->table_pg);
}
- }
+ }
return;
}
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/data.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/data.c index 1e03418..756aefb 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/data.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/data.c
@@ -12,14 +12,13 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <time.h>
+#include <math.h>
#include "mdbtools.h"
-#include "time.h"
-#include "math.h"
#ifdef DMALLOC
#include "dmalloc.h"
@@ -28,9 +27,10 @@
#define OFFSET_MASK 0x1fff
char *mdb_money_to_string(MdbHandle *mdb, int start);
+char *mdb_numeric_to_string(MdbHandle *mdb, int start, int prec, int scale);
+
static int _mdb_attempt_bind(MdbHandle *mdb,
MdbColumn *col, unsigned char isnull, int offset, int len);
-static char *mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, \
int scale); static char *mdb_date_to_string(MdbHandle *mdb, int start);
#ifdef MDB_COPY_OLE
static size_t mdb_copy_ole(MdbHandle *mdb, void *dest, int start, int size);
@@ -59,7 +59,7 @@ void mdb_bind_column(MdbTableDef *table, int col_num, void \
*bind_ptr, int *len_p col->len_ptr = len_ptr;
}
int
-mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr, int \
*len_ptr) +mdb_bind_column_by_name(MdbTableDef *table, const gchar *col_name, void \
*bind_ptr, int *len_ptr) {
unsigned int i;
int col_num = -1;
@@ -139,12 +139,12 @@ mdb_find_end_of_row(MdbHandle *mdb, int row)
if (row > 1000) return -1;
/* if lookupflag is not set, it's good (deleteflag is ok) */
- for (i = row; i > 0; i--) {
- row_start = mdb_get_int16(mdb->pg_buf, (rco + i*2));
- if (!(row_start & 0x8000)) {
- break;
- }
- }
+ for (i = row; i > 0; i--) {
+ row_start = mdb_get_int16(mdb->pg_buf, (rco + i*2));
+ if (!(row_start & 0x8000)) {
+ break;
+ }
+ }
row_end = (i == 0) ? mdb->fmt->pg_size : row_start & OFFSET_MASK;
#endif
@@ -206,9 +206,9 @@ static size_t
mdb_xfer_bound_data(MdbHandle *mdb, int start, MdbColumn *col, int len)
{
int ret;
-
-
-
+ //if (!strcmp("Name",col->name)) {
+ //printf("start %d %d\n",start, len);
+ //}
if (len) {
col->cur_value_start = start;
col->cur_value_len = len;
@@ -220,22 +220,12 @@ int ret;
if (!len) {
strcpy(col->bind_ptr, "");
} else {
-
+ //fprintf(stdout,"len %d size %d\n",len, col->col_size);
char *str;
if (col->col_type == MDB_NUMERIC) {
- /*fprintf(stdout,"MDB_NUMERIC\n");*/
- str = mdb_num_to_string(mdb, start,
- col->col_type, col->col_prec,
- col->col_scale);
- /*fprintf(stdout,"mdb_num_to_string()=%d '%s'\n", strlen(str), \
str);*/ + str = mdb_numeric_to_string(mdb, start, col->col_prec, col->col_scale);
} else {
- /*fprintf(stdout,"!MDB_NUMERIC : %d len=%d\n", col->col_type, \
len);*/
- str = mdb_col_to_string(mdb, mdb->pg_buf, start,
- col->col_type, len);
- /*if (strlen(str) > MDB_BIND_SIZE) {
- fprintf(stdout, "!!!!!!\n");
- }
- fprintf(stdout,"mdb_col_to_string()=%d '%s'\n", strlen(str), str);*/
+ str = mdb_col_to_string(mdb, mdb->pg_buf, start, col->col_type, len);
}
strcpy(col->bind_ptr, str);
g_free(str);
@@ -253,7 +243,6 @@ int mdb_read_row(MdbTableDef *table, unsigned int row)
MdbHandle *mdb = table->entry->mdb;
MdbColumn *col;
unsigned int i;
- int rc;
int row_start;
size_t row_size;
int delflag, lookupflag;
@@ -263,7 +252,10 @@ int mdb_read_row(MdbTableDef *table, unsigned int row)
if (table->num_rows == 0)
return 0;
- mdb_find_row(mdb, row, &row_start, &row_size);
+ if (mdb_find_row(mdb, row, &row_start, &row_size)) {
+ fprintf(stderr, "warning: mdb_find_row failed.");
+ return 0;
+ }
delflag = lookupflag = 0;
if (row_start & 0x8000) lookupflag++;
@@ -289,14 +281,14 @@ int mdb_read_row(MdbTableDef *table, unsigned int row)
#endif
#if MDB_DEBUG
- buffer_dump(mdb->pg_buf, row_start, row_size);
+ mdb_buffer_dump(mdb->pg_buf, row_start, row_size);
#endif
/* take advantage of mdb_crack_row() to clean up binding */
/* use num_cols instead of num_fields -- bsb 03/04/02 */
for (i = 0; i < table->num_cols; i++) {
col = g_ptr_array_index(table->columns,fields[i].colnum);
- rc = _mdb_attempt_bind(mdb, col, fields[i].is_null,
+ _mdb_attempt_bind(mdb, col, fields[i].is_null,
fields[i].start, fields[i].siz);
}
@@ -315,13 +307,15 @@ static int _mdb_attempt_bind(MdbHandle *mdb,
} else if (col->col_type == MDB_OLE) {
mdb_xfer_bound_ole(mdb, offset, col, len);
} else {
-
-
-
+ //if (!mdb_test_sargs(mdb, col, offset, len)) {
+ //return 0;
+ //}
mdb_xfer_bound_data(mdb, offset, col, len);
}
return 1;
}
+
+/* Read next data page into mdb->pg_buf */
int mdb_read_next_dpg(MdbTableDef *table)
{
MdbCatalogEntry *entry = table->entry;
@@ -329,16 +323,28 @@ int mdb_read_next_dpg(MdbTableDef *table)
int next_pg;
#ifndef SLOW_READ
- next_pg = mdb_map_find_next(mdb, table->usage_map,
- table->map_sz, table->cur_phys_pg);
+ while (1) {
+ next_pg = mdb_map_find_next(mdb, table->usage_map,
+ table->map_sz, table->cur_phys_pg);
+ if (next_pg < 0)
+ break; /* unknow map type: goto fallback */
+ if (!next_pg)
+ return 0;
- if (next_pg >= 0) {
- if (mdb_read_pg(mdb, next_pg)) {
- table->cur_phys_pg = next_pg;
- return table->cur_phys_pg;
- } else {
+ if (!mdb_read_pg(mdb, next_pg)) {
+ fprintf(stderr, "error: reading page %d failed.\n", next_pg);
return 0;
}
+
+ table->cur_phys_pg = next_pg;
+ if (mdb->pg_buf[0]==MDB_PAGE_DATA && mdb_get_int32(mdb->pg_buf, \
4)==entry->table_pg) + return table->cur_phys_pg;
+
+ /* On rare occasion, mdb_map_find_next will return a wrong page */
+ /* Found in a big file, over 4,000,000 records */
+ fprintf(stderr,
+ "warning: page %d from map doesn't match: Type=%d, buf[4..7]=%ld Expected \
table_pg=%ld\n", + next_pg, mdb->pg_buf[0], mdb_get_int32(mdb->pg_buf, 4), \
entry->table_pg); }
fprintf(stderr, "Warning: defaulting to brute force read\n");
#endif
@@ -346,7 +352,7 @@ int mdb_read_next_dpg(MdbTableDef *table)
do {
if (!mdb_read_pg(mdb, table->cur_phys_pg++))
return 0;
- } while (mdb->pg_buf[0]!=0x01 || mdb_get_int32(mdb->pg_buf, 4)!=entry->table_pg);
+ } while (mdb->pg_buf[0]!=MDB_PAGE_DATA || mdb_get_int32(mdb->pg_buf, \
4)!=entry->table_pg); /* fprintf(stderr,"returning new page %ld\n", \
table->cur_phys_pg); */ return table->cur_phys_pg;
}
@@ -403,7 +409,7 @@ mdb_fetch_row(MdbTableDef *table)
} else {
rows = mdb_get_int16(mdb->pg_buf,fmt->row_count_offset);
- /* if at end of page, find a new page */
+ /* if at end of page, find a new data page */
if (table->cur_row >= rows) {
table->cur_row=0;
@@ -457,6 +463,12 @@ int i;
return text;
}
#endif
+/*
+ * ole_ptr should point to the original blob value of the field.
+ * If omited, there will be no multi-page check to that the caller is
+ * responsible for not calling this function. Then, it doesn't have to
+ * preserve the original value.
+ */
size_t
mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr)
{
@@ -465,24 +477,30 @@ mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void \
*ole_ptr) int row_start;
size_t len;
- ole_len = mdb_get_int32(ole_ptr, 0);
+ if (ole_ptr) {
+ ole_len = mdb_get_int32(ole_ptr, 0);
+ mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %02x",
+ ole_len & 0x00ffffff, ole_len >> 24);
- if ((ole_len & 0x80000000)
- || (ole_len & 0x40000000)) {
- /* inline or single-page fields don't have a next */
- return 0;
- } else {
- if (mdb_find_pg_row(mdb, col->cur_blob_pg_row,
- &buf, &row_start, &len)) {
+ if ((ole_len & 0x80000000)
+ || (ole_len & 0x40000000))
+ /* inline or single-page fields don't have a next */
return 0;
- }
- if (col->bind_ptr)
- memcpy(col->bind_ptr, (char*)buf + row_start + 4, len - 4);
- col->cur_blob_pg_row = mdb_get_int32(buf, row_start);
-
- return len;
}
- return 0;
+ mdb_debug(MDB_DEBUG_OLE, "pg_row %d", col->cur_blob_pg_row);
+ if (!col->cur_blob_pg_row)
+ return 0; /* we are done */
+ if (mdb_find_pg_row(mdb, col->cur_blob_pg_row,
+ &buf, &row_start, &len)) {
+ return 0;
+ }
+ mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len);
+
+ if (col->bind_ptr)
+ memcpy(col->bind_ptr, (char*)buf + row_start + 4, len - 4);
+ col->cur_blob_pg_row = mdb_get_int32(buf, row_start);
+
+ return len - 4;
}
size_t
mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size)
@@ -526,26 +544,64 @@ mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int \
chunk_size) if (col->bind_ptr) {
memcpy(col->bind_ptr, (char*)buf + row_start, len);
if (mdb_get_option(MDB_DEBUG_OLE))
- buffer_dump(col->bind_ptr, 0, 16);
+ mdb_buffer_dump(col->bind_ptr, 0, 16);
}
return len;
} else if ((ole_len & 0xff000000) == 0) {
col->cur_blob_pg_row = mdb_get_int32(ole_ptr, 4);
+ mdb_debug(MDB_DEBUG_OLE,"ole row = %d ole pg = %ld",
+ col->cur_blob_pg_row & 0xff,
+ col->cur_blob_pg_row >> 8);
if (mdb_find_pg_row(mdb, col->cur_blob_pg_row,
&buf, &row_start, &len)) {
return 0;
}
+ mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len);
+
if (col->bind_ptr)
memcpy(col->bind_ptr, (char*)buf + row_start + 4, len - 4);
col->cur_blob_pg_row = mdb_get_int32(buf, row_start);
+ mdb_debug(MDB_DEBUG_OLE, "next pg_row %d", col->cur_blob_pg_row);
- return len;
+ return len - 4;
} else {
fprintf(stderr,"Unhandled ole field flags = %02x\n", ole_len >> 24);
return 0;
}
}
+/*
+ * mdb_ole_read_full calls mdb_ole_read then loop over mdb_ole_read_next as much as \
necessary. + * returns the result in a big buffer.
+ * The call must free it.
+ * Note that this function is not indempotent: It may be called only once per column \
after each bind. + */
+void*
+mdb_ole_read_full(MdbHandle *mdb, MdbColumn *col, size_t *size)
+{
+ char ole_ptr[MDB_MEMO_OVERHEAD];
+ char *result = malloc(MDB_BIND_SIZE);
+ size_t result_buffer_size = MDB_BIND_SIZE;
+ size_t len, pos;
+
+ memcpy(ole_ptr, col->bind_ptr, MDB_MEMO_OVERHEAD);
+
+ len = mdb_ole_read(mdb, col, ole_ptr, MDB_BIND_SIZE);
+ memcpy(result, col->bind_ptr, len);
+ pos = len;
+ while ((len = mdb_ole_read_next(mdb, col, ole_ptr))) {
+ if (pos+len >= result_buffer_size) {
+ result_buffer_size += MDB_BIND_SIZE;
+ result = realloc(result, result_buffer_size);
+ }
+ memcpy(result + pos, col->bind_ptr, len);
+ pos += len;
+ }
+ if (size)
+ *size = pos;
+ return result;
+}
+
#ifdef MDB_COPY_OLE
static size_t mdb_copy_ole(MdbHandle *mdb, void *dest, int start, int size)
{
@@ -617,17 +673,15 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int \
size) gint32 row_start, pg_row;
size_t len;
void *buf, *pg_buf = mdb->pg_buf;
- char *text = 0;
+ char *text = (char *) g_malloc(MDB_BIND_SIZE);
- /*printf("mdb_memo_to_string: size=%d\n", size);*/
if (size<MDB_MEMO_OVERHEAD) {
- text = (char *) g_malloc(MDB_BIND_SIZE);
strcpy(text, "");
return text;
}
#if MDB_DEBUG
- buffer_dump(pg_buf, start, MDB_MEMO_OVERHEAD);
+ mdb_buffer_dump(pg_buf, start, MDB_MEMO_OVERHEAD);
#endif
/* The 32 bit integer at offset 0 is the length of the memo field
@@ -635,18 +689,13 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int \
size)
* The 32 bit integer at offset 4 contains page and row information.
*/
memo_len = mdb_get_int32(pg_buf, start);
- /*printf("memo_len=%d\n", memo_len);*/
if (memo_len & 0x80000000) {
- text = (char *) g_malloc(MDB_BIND_SIZE);
- /*printf("INLINE MEMO\n");*/
/* inline memo field */
mdb_unicode2ascii(mdb, (char*)pg_buf + start + MDB_MEMO_OVERHEAD,
size - MDB_MEMO_OVERHEAD, text, MDB_BIND_SIZE);
return text;
} else if (memo_len & 0x40000000) {
- text = (char *) g_malloc(MDB_BIND_SIZE);
- /*printf("SINGLE-PAGE MEMO\n");*/
/* single-page memo field */
pg_row = mdb_get_int32(pg_buf, start+4);
#if MDB_DEBUG
@@ -659,12 +708,11 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int \
size) #if MDB_DEBUG
printf("row num %d start %d len %d\n",
pg_row & 0xff, row_start, len);
- buffer_dump(buf, row_start, len);
+ mdb_buffer_dump(buf, row_start, len);
#endif
mdb_unicode2ascii(mdb, (char*)buf + row_start, len, text, MDB_BIND_SIZE);
return text;
- } else if ((memo_len & 0xff000000) == 0) { /* assume all flags in MSB */
- /*printf("MULTI-PAGE MEMO\n");*/
+ } else if ((memo_len & 0xff000000) == 0) { // assume all flags in MSB
/* multi-page memo field */
guint32 tmpoff = 0;
char *tmp;
@@ -693,9 +741,7 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int \
size) if (tmpoff < memo_len) {
fprintf(stderr, "Warning: incorrect memo length\n");
}
- /*printf("ALLOCATING tmpoff *2: %d\n", tmpoff * 2);*/
- text = (char *) g_malloc(tmpoff);
- mdb_unicode2ascii(mdb, tmp, tmpoff, text, tmpoff);
+ mdb_unicode2ascii(mdb, tmp, tmpoff, text, MDB_BIND_SIZE);
g_free(tmp);
return text;
} else {
@@ -704,28 +750,8 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int \
size) return text;
}
}
-static char *
-mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale)
-{
- char *text;
- int negative;
- gint32 l;
-
- memcpy(&l, mdb->pg_buf+start+13, 4);
- negative = (*(mdb->pg_buf+start) & 0x80) ? 1 : 0;
- text = (char *) g_malloc(prec+2+negative);
- if (negative) {
- sprintf(text, "-%0*" G_GINT32_FORMAT, prec, GINT32_FROM_LE(l));
- } else {
- sprintf(text, "%0*" G_GINT32_FORMAT, prec, GINT32_FROM_LE(l));
- }
- if (scale) {
- memmove(text+prec-scale+1+negative, text+prec-scale+negative, scale+1);
- text[prec-scale+negative] = '.';
- }
- return text;
-}
+#if 0
static int trim_trailing_zeros(char * buff)
{
char *p;
@@ -746,66 +772,96 @@ static int trim_trailing_zeros(char * buff)
return 0;
}
+#endif
/* Date/Time is stored as a double, where the whole
part is the days from 12/30/1899 and the fractional
part is the fractional part of one day. */
-static char *
-mdb_date_to_string(MdbHandle *mdb, int start)
+
+void
+mdb_date_to_tm(double td, struct tm *t)
{
- struct tm t;
long int day, time;
int yr, q;
int *cal;
int noleap_cal[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
int leap_cal[] = {0,31,60,91,121,152,182,213,244,274,305,335,366};
- char *text = (char *) g_malloc(MDB_BIND_SIZE);
- double td = mdb_get_double(mdb->pg_buf, start);
-
day = (long int)(td);
time = (long int)(fabs(td - day) * 86400.0 + 0.5);
- t.tm_hour = time / 3600;
- t.tm_min = (time / 60) % 60;
- t.tm_sec = time % 60;
- t.tm_year = 1 - 1900;
+ t->tm_hour = time / 3600;
+ t->tm_min = (time / 60) % 60;
+ t->tm_sec = time % 60;
+ t->tm_year = 1 - 1900;
day += 693593; /* Days from 1/1/1 to 12/31/1899 */
- t.tm_wday = (day+1) % 7;
+ t->tm_wday = (day+1) % 7;
q = day / 146097; /* 146097 days in 400 years */
- t.tm_year += 400 * q;
+ t->tm_year += 400 * q;
day -= q * 146097;
q = day / 36524; /* 36524 days in 100 years */
if (q > 3) q = 3;
- t.tm_year += 100 * q;
+ t->tm_year += 100 * q;
day -= q * 36524;
q = day / 1461; /* 1461 days in 4 years */
- t.tm_year += 4 * q;
+ t->tm_year += 4 * q;
day -= q * 1461;
q = day / 365; /* 365 days in 1 year */
if (q > 3) q = 3;
- t.tm_year += q;
+ t->tm_year += q;
day -= q * 365;
- yr = t.tm_year + 1900;
+ yr = t->tm_year + 1900;
cal = ((yr)%4==0 && ((yr)%100!=0 || (yr)%400==0)) ?
leap_cal : noleap_cal;
- for (t.tm_mon=0; t.tm_mon<12; t.tm_mon++) {
- if (day < cal[t.tm_mon+1]) break;
+ for (t->tm_mon=0; t->tm_mon<12; t->tm_mon++) {
+ if (day < cal[t->tm_mon+1]) break;
}
- t.tm_mday = day - cal[t.tm_mon] + 1;
- t.tm_yday = day;
- t.tm_isdst = -1;
+ t->tm_mday = day - cal[t->tm_mon] + 1;
+ t->tm_yday = day;
+ t->tm_isdst = -1;
+}
+
+static char *
+mdb_date_to_string(MdbHandle *mdb, int start)
+{
+ struct tm t;
+ char *text = (char *) g_malloc(MDB_BIND_SIZE);
+ double td = mdb_get_double(mdb->pg_buf, start);
+
+ mdb_date_to_tm(td, &t);
strftime(text, MDB_BIND_SIZE, date_fmt, &t);
return text;
}
+static char *
+mdb_uuid_to_string(MdbHandle *mdb, int start)
+{
+ char *text = NULL;
+ unsigned short uuid1, uuid2, uuid3, uuid4, uuid5, uuid6, uuid7, uuid8;
+
+ uuid1 = mdb_get_int16(mdb->pg_buf, start);
+ uuid2 = mdb_get_int16(mdb->pg_buf, start + 2);
+ uuid3 = mdb_get_int16(mdb->pg_buf, start + 4);
+ uuid4 = mdb_get_int16(mdb->pg_buf, start + 6);
+ uuid5 = mdb_get_int16(mdb->pg_buf, start + 8);
+ uuid6 = mdb_get_int16(mdb->pg_buf, start + 10);
+ uuid7 = mdb_get_int16(mdb->pg_buf, start + 12);
+ uuid8 = mdb_get_int16(mdb->pg_buf, start + 14);
+
+ text = g_strdup_printf("{%04x%04x-%04x-%04x-%04x-%04x%04x%04x}",
+ uuid1, uuid2, uuid3, uuid4, uuid5, uuid6, uuid7, uuid8);
+
+ return text;
+}
+
+#if 0
int floor_log10(double f, int is_single)
{
unsigned int i;
@@ -814,7 +870,7 @@ int floor_log10(double f, int is_single)
if (f < 0.0)
f = -f;
- if ((f == 0.0) || (f == 1.0)) {
+ if ((f == 0.0) || (f == 1.0) || isinf(f)) {
return 0;
} else if (f < 1.0) {
if (is_single) {
@@ -834,6 +890,7 @@ int floor_log10(double f, int is_single)
return (int)i;
}
}
+#endif
char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int datatype, int \
size) {
@@ -850,24 +907,29 @@ char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, \
int datatype, int text = g_strdup_printf("%d", mdb_get_byte(buf, start));
break;
case MDB_INT:
- text = g_strdup_printf("%ld",
- (long)mdb_get_int16(buf, start));
+ text = g_strdup_printf("%hd",
+ (short)mdb_get_int16(buf, start));
break;
case MDB_LONGINT:
+ case MDB_COMPLEX:
text = g_strdup_printf("%ld",
mdb_get_int32(buf, start));
break;
case MDB_FLOAT:
tf = mdb_get_single(buf, start);
- text = g_strdup_printf("%.*f",
- FLT_DIG - floor_log10(tf,1) - 1, tf);
- trim_trailing_zeros(text);
+ text = g_strdup_printf("%.8e", tf);
break;
case MDB_DOUBLE:
td = mdb_get_double(buf, start);
- text = g_strdup_printf("%.*f",
- DBL_DIG - floor_log10(td,0) - 1, td);
- trim_trailing_zeros(text);
+ text = g_strdup_printf("%.16e", td);
+ break;
+ case MDB_BINARY:
+ if (size<0) {
+ text = g_strdup("");
+ } else {
+ text = g_malloc(size);
+ memcpy((char*)buf+start, text, size);
+ }
break;
case MDB_TEXT:
if (size<0) {
@@ -878,7 +940,7 @@ char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int \
datatype, int size, text, MDB_BIND_SIZE);
}
break;
- case MDB_SDATETIME:
+ case MDB_DATETIME:
text = mdb_date_to_string(mdb, start);
break;
case MDB_MEMO:
@@ -888,6 +950,9 @@ char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int \
datatype, int text = mdb_money_to_string(mdb, start);
case MDB_NUMERIC:
break;
+ case MDB_REPID:
+ text = mdb_uuid_to_string(mdb, start);
+ break;
default:
text = g_strdup("");
break;
@@ -907,6 +972,7 @@ int mdb_col_disp_size(MdbColumn *col)
return 6;
break;
case MDB_LONGINT:
+ case MDB_COMPLEX:
return 11;
break;
case MDB_FLOAT:
@@ -918,7 +984,7 @@ int mdb_col_disp_size(MdbColumn *col)
case MDB_TEXT:
return col->col_size;
break;
- case MDB_SDATETIME:
+ case MDB_DATETIME:
return 20;
break;
case MDB_MEMO:
@@ -943,6 +1009,7 @@ int mdb_col_fixed_size(MdbColumn *col)
return 2;
break;
case MDB_LONGINT:
+ case MDB_COMPLEX:
return 4;
break;
case MDB_FLOAT:
@@ -954,9 +1021,12 @@ int mdb_col_fixed_size(MdbColumn *col)
case MDB_TEXT:
return -1;
break;
- case MDB_SDATETIME:
+ case MDB_DATETIME:
return 4;
break;
+ case MDB_BINARY:
+ return -1;
+ break;
case MDB_MEMO:
return -1;
break;
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/dump.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/dump.c index ffd9c11..afa002d 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/dump.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/dump.c
@@ -1,3 +1,21 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000-2011 Brian Bruns and others
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#include <ctype.h>
#include <string.h>
#include <stdio.h>
@@ -6,7 +24,7 @@
#include "dmalloc.h"
#endif
-void buffer_dump(const void* buf, int start, size_t len)
+void mdb_buffer_dump(const void* buf, int start, size_t len)
{
char asc[20];
int j, k;
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/file.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/file.c index d8688d2..1792e9f 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/file.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/file.c
@@ -12,11 +12,11 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <inttypes.h>
#include "mdbtools.h"
#ifdef DMALLOC
@@ -35,7 +35,7 @@ typedef struct {
guint16 tab_first_dpg_offset;
guint16 tab_cols_start_offset;
guint16 tab_ridx_entry_size;
- guint16 col_fixed_offset;
+ guint16 col_flags_offset;
guint16 col_size_offset;
guint16 col_num_offset;
guint16 tab_col_entry_size;
@@ -52,8 +52,69 @@ MdbFormatConstants MdbJet3Constants = {
2048, 0x08, 12, 25, 27, 31, 35, 36, 43, 8, 13, 16, 1, 18, 39, 3, 14, 5
};
+typedef struct _RC4_KEY
+{
+ unsigned char state[256];
+ unsigned char x;
+ unsigned char y;
+} RC4_KEY;
+
+#define swap_byte(x,y) t = *(x); *(x) = *(y); *(y) = t
+
static ssize_t _mdb_read_pg(MdbHandle *mdb, void *pg_buf, unsigned long pg);
+static void RC4_set_key(RC4_KEY *key, int key_data_len, unsigned char *key_data_ptr)
+{
+ unsigned char t;
+ unsigned char index1;
+ unsigned char index2;
+ unsigned char* state;
+ short counter;
+
+ state = &key->state[0];
+ for(counter = 0; counter < 256; counter++)
+ state[counter] = counter;
+ key->x = 0;
+ key->y = 0;
+ index1 = 0;
+ index2 = 0;
+ for(counter = 0; counter < 256; counter++) {
+ index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
+ swap_byte(&state[counter], &state[index2]);
+ index1 = (index1 + 1) % key_data_len;
+ }
+}
+
+/*
+ * this algorithm does 'encrypt in place' instead of inbuff/outbuff
+ * note also: encryption and decryption use same routine
+ * implementation supplied by (Adam Back) at <adam at cypherspace dot org>
+ */
+
+static void RC4(RC4_KEY *key, int buffer_len, unsigned char * buff)
+{
+ unsigned char t;
+ unsigned char x;
+ unsigned char y;
+ unsigned char* state;
+ unsigned char xorIndex;
+ short counter;
+
+ x = key->x;
+ y = key->y;
+ state = &key->state[0];
+ for(counter = 0; counter < buffer_len; counter++) {
+ x = (x + 1) % 256;
+ y = (state[x] + y) % 256;
+ swap_byte(&state[x], &state[y]);
+ xorIndex = (state[x] + state[y]) % 256;
+ buff[counter] ^= state[xorIndex];
+ }
+ key->x = x;
+ key->y = y;
+}
+
+
/**
* mdb_find_file:
* @filename: path to MDB (database) file
@@ -73,7 +134,11 @@ static char *mdb_find_file(const char *file_name)
/* try the provided file name first */
if (!stat(file_name, &status)) {
- return g_strdup(file_name);
+ char *result;
+ result = g_strdup(file_name);
+ if (!result)
+ fprintf(stderr, "Can't alloc filename\n");
+ return result;
}
/* Now pull apart $MDBPATH and try those */
@@ -134,6 +199,8 @@ void mdb_set_encoding(MdbHandle *mdb, const char *encoding_name)
MdbHandle *mdb_open(const char *filename, MdbFileFlags flags)
{
MdbHandle *mdb;
+ int key[] = {0x86, 0xfb, 0xec, 0x37, 0x5d, 0x44, 0x9c, 0xfa, 0xc6, 0x5e, 0x28, \
0xe6, 0x13, 0xb6}; + int j, pos;
int open_flags;
mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle));
@@ -152,7 +219,7 @@ MdbHandle *mdb_open(const char *filename, MdbFileFlags flags)
mdb->f->fd = -1;
mdb->f->filename = mdb_find_file(filename);
if (!mdb->f->filename) {
- fprintf(stderr, "Can't alloc filename\n");
+ fprintf(stderr, "File not found\n");
mdb_close(mdb);
return NULL;
}
@@ -184,15 +251,56 @@ MdbHandle *mdb_open(const char *filename, MdbFileFlags flags)
return NULL;
}
mdb->f->jet_version = mdb_get_int32(mdb->pg_buf, 0x14);
- if (IS_JET4(mdb)) {
- mdb->fmt = &MdbJet4Constants;
- } else if (IS_JET3(mdb)) {
+ switch(mdb->f->jet_version) {
+ case MDB_VER_JET3:
mdb->fmt = &MdbJet3Constants;
- } else {
+ break;
+ case MDB_VER_JET4:
+ case MDB_VER_ACCDB_2007:
+ case MDB_VER_ACCDB_2010:
+ mdb->fmt = &MdbJet4Constants;
+ break;
+ default:
fprintf(stderr,"Unknown Jet version.\n");
mdb_close(mdb);
return NULL;
}
+ mdb->f->db_key = mdb_get_int32(mdb->pg_buf, 0x3e);
+ /* I don't know if this value is valid for some versions?
+ * it doesn't seem to be valid for the databases I have
+ *
+ * f->db_key ^= 0xe15e01b9;
+ */
+ mdb->f->db_key ^= 0x4ebc8afb;
+ /* fprintf(stderr, "Encrypted file, RC4 key seed= %d\n", mdb->f->db_key); */
+ if (mdb->f->db_key) {
+ /* write is not supported for encrypted files yet */
+ mdb->f->writable = FALSE;
+ /* that should be enought, but reopen the file read only just to be
+ * sure we don't write invalid data */
+ close(mdb->f->fd);
+ open_flags = O_RDONLY;
+#ifdef _WIN32
+ open_flags |= O_BINARY;
+#endif
+ mdb->f->fd = open(mdb->f->filename, open_flags);
+ if (mdb->f->fd==-1) {
+ fprintf(stderr, "Couldn't ropen file %s in read only\n", mdb->f->filename);
+ mdb_close(mdb);
+ return NULL;
+ }
+ }
+
+ /* get the db password located at 0x42 bytes into the file */
+ for (pos=0;pos<14;pos++) {
+ j = mdb_get_int32(mdb->pg_buf, 0x42+pos);
+ j ^= key[pos];
+ if ( j != 0)
+ mdb->f->db_passwd[pos] = j;
+ else
+ mdb->f->db_passwd[pos] = '\0';
+ }
+
mdb_iconv_init(mdb);
return mdb;
@@ -282,7 +390,7 @@ ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg)
if (pg && mdb->cur_pg == pg) return mdb->fmt->pg_size;
len = _mdb_read_pg(mdb, mdb->pg_buf, pg);
-
+ //fprintf(stderr, "read page %d type %02x\n", pg, mdb->pg_buf[0]);
mdb->cur_pg = pg;
/* kan - reset the cur_pos on a new page read */
mdb->cur_pos = 0; /* kan */
@@ -303,7 +411,7 @@ static ssize_t _mdb_read_pg(MdbHandle *mdb, void *pg_buf, \
unsigned long pg)
fstat(mdb->f->fd, &status);
if (status.st_size < offset) {
- fprintf(stderr,"offset %lu is beyond EOF\n",offset);
+ fprintf(stderr,"offset %jd is beyond EOF\n",(intmax_t)offset);
return 0;
}
#if !MDB_NO_STATS
@@ -320,6 +428,18 @@ static ssize_t _mdb_read_pg(MdbHandle *mdb, void *pg_buf, \
unsigned long pg) /* fprintf(stderr,"EOF reached %d bytes returned.\n",len, \
mdb->fmt->pg_size); */ return 0;
}
+ /*
+ * unencrypt the page if necessary.
+ * it might make sense to cache the unencrypted data blocks?
+ */
+ if (pg != 0 && mdb->f->db_key != 0)
+ {
+ RC4_KEY rc4_key;
+ unsigned int tmp_key = mdb->f->db_key ^ pg;
+ RC4_set_key(&rc4_key, 4, (unsigned char *)&tmp_key);
+ RC4(&rc4_key, mdb->fmt->pg_size, pg_buf);
+ }
+
return len;
}
void mdb_swap_pgbuf(MdbHandle *mdb)
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/iconv.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/iconv.c index ab19cbd..7f19cc0 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/iconv.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/iconv.c
@@ -12,13 +12,12 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <errno.h>
#include "mdbtools.h"
-#include "errno.h"
#ifdef DMALLOC
#include "dmalloc.h"
@@ -43,7 +42,7 @@ mdb_unicode2ascii(MdbHandle *mdb, char *src, size_t slen, char \
*dest, size_t dle return 0;
/* Uncompress 'Unicode Compressed' string into tmp */
- if (IS_JET4(mdb) && (slen>=2)
+ if (!IS_JET3(mdb) && (slen>=2)
&& ((src[0]&0xff)==0xff) && ((src[1]&0xff)==0xfe)) {
unsigned int compress=1;
src += 2;
@@ -72,22 +71,25 @@ mdb_unicode2ascii(MdbHandle *mdb, char *src, size_t slen, char \
*dest, size_t dle len_out = dlen;
#if HAVE_ICONV
-
+ //printf("1 len_in %d len_out %d\n",len_in, len_out);
while (1) {
iconv(mdb->iconv_in, &in_ptr, &len_in, &out_ptr, &len_out);
if ((!len_in) || (errno == E2BIG)) break;
/* Don't bail if impossible conversion is encountered */
- in_ptr += (IS_JET4(mdb)) ? 2 : 1;
- len_in -= (IS_JET4(mdb)) ? 2 : 1;
+ in_ptr += (IS_JET3(mdb)) ? 1 : 2;
+ len_in -= (IS_JET3(mdb)) ? 1 : 2;
*out_ptr++ = '?';
len_out--;
}
-
+ //printf("2 len_in %d len_out %d\n",len_in, len_out);
dlen -= len_out;
#else
if (IS_JET3(mdb)) {
- strncpy(out_ptr, in_ptr, len_in);
- dlen = len_in;
+ size_t copy_len = len_in;
+ if (copy_len > dlen)
+ copy_len = dlen;
+ strncpy(out_ptr, in_ptr, copy_len);
+ dlen = copy_len;
} else {
/* rough UCS-2LE to ISO-8859-1 conversion */
unsigned int i;
@@ -99,7 +101,7 @@ mdb_unicode2ascii(MdbHandle *mdb, char *src, size_t slen, char \
*dest, size_t dle
if (tmp) g_free(tmp);
dest[dlen]='\0';
-
+ //printf("dest %s\n",dest);
return dlen;
}
@@ -123,7 +125,7 @@ mdb_ascii2unicode(MdbHandle *mdb, char *src, size_t slen, char \
*dest, size_t dle
#ifdef HAVE_ICONV
iconv(mdb->iconv_out, &in_ptr, &len_in, &out_ptr, &len_out);
-
+ //printf("len_in %d len_out %d\n", len_in, len_out);
dlen -= len_out;
#else
if (IS_JET3(mdb)) {
@@ -141,7 +143,7 @@ mdb_ascii2unicode(MdbHandle *mdb, char *src, size_t slen, char \
*dest, size_t dle #endif
/* Unicode Compression */
- if(IS_JET4(mdb) && (dlen>4)) {
+ if(!IS_JET3(mdb) && (dlen>4)) {
unsigned char *tmp = g_malloc(dlen);
unsigned int tptr = 0, dptr = 0;
int comp = 1;
@@ -182,6 +184,21 @@ mdb_ascii2unicode(MdbHandle *mdb, char *src, size_t slen, char \
*dest, size_t dle return dlen;
}
+const char*
+mdb_target_charset(MdbHandle *mdb)
+{
+#ifdef HAVE_ICONV
+ const char *iconv_code = getenv("MDBICONV");
+ if (!iconv_code)
+ iconv_code = "UTF-8";
+ return iconv_code;
+#else
+ if (!IS_JET3(mdb))
+ return "ISO-8859-1";
+ return NULL; // same as input: unknown
+#endif
+}
+
void mdb_iconv_init(MdbHandle *mdb)
{
const char *iconv_code;
@@ -192,10 +209,10 @@ void mdb_iconv_init(MdbHandle *mdb)
}
#ifdef HAVE_ICONV
- if (IS_JET4(mdb)) {
- mdb->iconv_out = iconv_open("UCS-2LE", iconv_code);
- mdb->iconv_in = iconv_open(iconv_code, "UCS-2LE");
- } else {
+ if (!IS_JET3(mdb)) {
+ mdb->iconv_out = iconv_open("UCS-2LE", iconv_code);
+ mdb->iconv_in = iconv_open(iconv_code, "UCS-2LE");
+ } else {
/* According to Microsoft Knowledge Base pages 289525 and */
/* 202427, code page info is not contained in the database */
@@ -208,8 +225,9 @@ void mdb_iconv_init(MdbHandle *mdb)
// get the default from OS
char default_encoding[] = "CP ";
if (GetLocaleInfoA( MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \
SORT_DEFAULT),
- LOCALE_IDEFAULTANSICODEPAGE, default_encoding+2, sizeof(default_encoding)-2-1 ))
+ LOCALE_IDEFAULTANSICODEPAGE, default_encoding+2, \
sizeof(default_encoding)-2-1 )) { mdb->jet3_iconv_code = g_strdup(default_encoding);
+ }
else
#endif
mdb->jet3_iconv_code = g_strdup("CP1252");
@@ -223,7 +241,9 @@ void mdb_iconv_init(MdbHandle *mdb)
void mdb_iconv_close(MdbHandle *mdb)
{
#ifdef HAVE_ICONV
- if (mdb->iconv_out != (iconv_t)-1) iconv_close(mdb->iconv_out);
- if (mdb->iconv_in != (iconv_t)-1) iconv_close(mdb->iconv_in);
+ if (mdb->iconv_out != (iconv_t)-1) iconv_close(mdb->iconv_out);
+ if (mdb->iconv_in != (iconv_t)-1) iconv_close(mdb->iconv_in);
#endif
}
+
+
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/index.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/index.c index f517f2b..865d5a4 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/index.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/index.c
@@ -12,9 +12,8 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mdbtools.h"
@@ -69,24 +68,29 @@ mdb_read_indices(MdbTableDef *table)
MdbHandle *mdb = entry->mdb;
MdbFormatConstants *fmt = mdb->fmt;
MdbIndex *pidx;
- unsigned int i, j;
- int idx_num, key_num, col_num;
+ unsigned int i, j, k;
+ int key_num, col_num, cleaned_col_num;
int cur_pos, name_sz, idx2_sz, type_offset;
int index_start_pg = mdb->cur_pg;
gchar *tmpbuf;
- table->indices = g_ptr_array_new();
+ 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 {
+ if (IS_JET3(mdb)) {
cur_pos = table->index_start + 39 * table->num_real_idxs;
idx2_sz = 20;
type_offset = 19;
+ } else {
+ cur_pos = table->index_start + 52 * table->num_real_idxs;
+ idx2_sz = 28;
+ type_offset = 23;
}
+ //fprintf(stderr, "num_idxs:%d num_real_idxs:%d\n", table->num_idxs, \
table->num_real_idxs); + /* num_real_idxs should be the number of indexes of type 2.
+ * It's not always the case. Happens on Northwind Orders table.
+ */
+ table->num_real_idxs = 0;
tmpbuf = (gchar *) g_malloc(idx2_sz);
for (i=0;i<table->num_idxs;i++) {
read_pg_if_n(mdb, tmpbuf, &cur_pos, idx2_sz);
@@ -95,45 +99,64 @@ mdb_read_indices(MdbTableDef *table)
pidx->index_num = mdb_get_int16(tmpbuf, 4);
pidx->index_type = tmpbuf[type_offset];
g_ptr_array_add(table->indices, pidx);
+ /*
+ {
+ gint32 dumy0 = mdb_get_int32(tmpbuf, 0);
+ gint8 dumy1 = tmpbuf[8];
+ gint32 dumy2 = mdb_get_int32(tmpbuf, 9);
+ gint32 dumy3 = mdb_get_int32(tmpbuf, 13);
+ gint16 dumy4 = mdb_get_int16(tmpbuf, 17);
+ fprintf(stderr, "idx #%d: num2:%d type:%d\n", i, pidx->index_num, \
pidx->index_type); + fprintf(stderr, "idx #%d: %d %d %d %d %d\n", i, dumy0, dumy1, \
dumy2, dumy3, dumy4); + }*/
+ if (pidx->index_type!=2)
+ table->num_real_idxs++;
}
+ //fprintf(stderr, "num_idxs:%d num_real_idxs:%d\n", table->num_idxs, \
table->num_real_idxs); 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);
- } else {
+ if (IS_JET3(mdb)) {
name_sz=read_pg_if_8(mdb, &cur_pos);
+ } else {
+ name_sz=read_pg_if_16(mdb, &cur_pos);
}
tmpbuf = g_malloc(name_sz);
read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz);
mdb_unicode2ascii(mdb, tmpbuf, name_sz, pidx->name, MDB_MAX_OBJ_NAME);
g_free(tmpbuf);
-
+ //fprintf(stderr, "index %d type %d name %s\n", pidx->index_num, pidx->index_type, \
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 (idx_num < table->num_real_idxs && pidx /*&& pidx != \
0x736e6f6300616d65 && pidx!=(MdbIndex*)0xbaadf00d*/ /*(js) temp? hack*/&& \
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 (idx_num == table->num_real_idxs || !pidx /*|| pidx==(MdbIndex*)0xbaadf00d*/ \
/*(js) temp? hack*/ /*|| pidx != 0x736e6f6300616d65*/) {
- table->num_real_idxs--;
+ if (!IS_JET3(mdb)) cur_pos += 4;
+ /* look for index number i */
+ for (j=0; j<table->num_idxs; ++j) {
+ pidx = g_ptr_array_index (table->indices, j);
+ if (pidx->index_type!=2 && pidx->index_num==i)
+ break;
+ }
+ if (j==table->num_idxs) {
+ fprintf(stderr, "ERROR: can't find index #%d.\n", i);
continue;
}
+ //fprintf(stderr, "index %d #%d (%s) index_type:%d\n", i, pidx->index_num, \
pidx->name, pidx->index_type);
pidx->num_rows = mdb_get_int32(mdb->alt_pg_buf,
fmt->tab_cols_start_offset +
- (i*fmt->tab_ridx_entry_size));
+ (pidx->index_num*fmt->tab_ridx_entry_size));
+ /*
+ fprintf(stderr, "ridx block1 i:%d data1:0x%08x data2:0x%08x\n",
+ i,
+ mdb_get_int32(mdb->pg_buf,
+ fmt->tab_cols_start_offset + pidx->index_num * fmt->tab_ridx_entry_size),
+ mdb_get_int32(mdb->pg_buf,
+ fmt->tab_cols_start_offset + pidx->index_num * fmt->tab_ridx_entry_size +4));
+ fprintf(stderr, "pidx->num_rows:%d\n", pidx->num_rows);*/
key_num=0;
for (j=0;j<MDB_MAX_IDX_COLS;j++) {
@@ -142,18 +165,37 @@ mdb_read_indices(MdbTableDef *table)
cur_pos++;
continue;
}
+ /* here we have the internal column number that does not
+ * always match the table columns because of deletions */
+ cleaned_col_num = -1;
+ for (k=0; k<table->num_cols; k++) {
+ MdbColumn *col = g_ptr_array_index(table->columns,k);
+ if (col->col_num == col_num) {
+ cleaned_col_num = k;
+ break;
+ }
+ }
+ if (cleaned_col_num==-1) {
+ fprintf(stderr, "CRITICAL: can't find column with internal id %d in index %s\n",
+ col_num, pidx->name);
+ cur_pos++;
+ continue;
+ }
/* set column number to a 1 based column number and store */
- pidx->key_col_num[key_num] = col_num + 1;
+ pidx->key_col_num[key_num] = cleaned_col_num + 1;
pidx->key_col_order[key_num] =
(read_pg_if_8(mdb, &cur_pos)) ? MDB_ASC : MDB_DESC;
+ //fprintf(stderr, "component %d using column #%d (internally %d)\n", j, \
cleaned_col_num, col_num); key_num++;
}
pidx->num_keys = key_num;
cur_pos += 4;
+ //fprintf(stderr, "pidx->unknown_pre_first_pg:0x%08x\n", read_pg_if_32(mdb, \
&cur_pos)); pidx->first_pg = read_pg_if_32(mdb, &cur_pos);
pidx->flags = read_pg_if_8(mdb, &cur_pos);
- if (IS_JET4(mdb)) cur_pos += 9;
+ //fprintf(stderr, "pidx->first_pg:%d pidx->flags:0x%02x\n", pidx->first_pg, \
pidx->flags); + if (!IS_JET3(mdb)) cur_pos += 9;
}
return NULL;
}
@@ -185,7 +227,7 @@ mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest)
void
mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
{
-
+ //guint32 cache_int;
unsigned char *c;
switch (col->col_type) {
@@ -195,10 +237,10 @@ mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg \
*idx_sarg)
case MDB_LONGINT:
idx_sarg->value.i = GUINT32_SWAP_LE_BE(sarg->value.i);
-
+ //cache_int = sarg->value.i * -1;
c = (unsigned char *) &(idx_sarg->value.i);
c[0] |= 0x80;
-
+ //printf("int %08x %02x %02x %02x %02x\n", sarg->value.i, c[0], c[1], c[2], c[3]);
break;
case MDB_INT:
@@ -247,25 +289,25 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, char *buf, \
int len) MdbSarg *sarg;
MdbField field;
MdbSargNode node;
-
+ //int c_offset = 0,
int c_len;
-
-
-
-
+ //fprintf(stderr,"mdb_index_test_sargs called on ");
+ //for (i=0;i<len;i++)
+ //fprintf(stderr,"%02x ",buf[i]); //mdb->pg_buf[offset+i]);
+ //fprintf(stderr,"\n");
for (i=0;i<idx->num_keys;i++) {
-
+ //c_offset++; /* the per column null indicator/flags */
col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
/*
* This will go away eventually
*/
if (col->col_type==MDB_TEXT) {
-
+ //c_len = strlen(&mdb->pg_buf[offset + c_offset]);
c_len = strlen(buf);
} else {
c_len = col->col_size;
-
+ //fprintf(stderr,"Only text types currently supported. How did we get here?\n");
}
/*
* If we have no cached index values for this column,
@@ -276,7 +318,7 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, char *buf, \
int len) for (j=0;j<col->num_sargs;j++) {
sarg = g_ptr_array_index (col->sargs, j);
idx_sarg = g_memdup(sarg,sizeof(MdbSarg));
-
+ //printf("calling mdb_index_cache_sarg\n");
mdb_index_cache_sarg(col, sarg, idx_sarg);
g_ptr_array_add(col->idx_sarg_cache, idx_sarg);
}
@@ -287,7 +329,7 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, char *buf, \
int len) /* XXX - kludge */
node.op = sarg->op;
node.value = sarg->value;
-
+ //field.value = &mdb->pg_buf[offset + c_offset];
field.value = buf;
field.siz = c_len;
field.is_null = FALSE;
@@ -314,9 +356,9 @@ mdb_index_pack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
start = ipg->idx_starts[elem++];
while (start) {
-
+ //fprintf(stdout, "elem %d is %d\n", elem, ipg->idx_starts[elem]);
len = ipg->idx_starts[elem] - start;
-
+ //fprintf(stdout, "len is %d\n", len);
for (i=0; i < len; i++) {
mask_bit++;
if (mask_bit==8) {
@@ -327,7 +369,7 @@ mdb_index_pack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
/* upon reaching the len, set the bit */
}
mask_byte = (1 << mask_bit) | mask_byte;
-
+ //fprintf(stdout, "mask byte is %02x at %d\n", mask_byte, mask_pos);
start = ipg->idx_starts[elem++];
}
/* flush the last byte if any */
@@ -353,7 +395,7 @@ mdb_index_unpack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
ipg->idx_starts[elem++]=start;
-
+ //fprintf(stdout, "Unpacking index page %lu\n", ipg->pg);
do {
len = 0;
do {
@@ -365,7 +407,7 @@ mdb_index_unpack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
mask_byte = mdb->pg_buf[mask_pos];
len++;
} while (mask_pos <= 0xf8 && !((1 << mask_bit) & mask_byte));
-
+ //fprintf(stdout, "%d %d %d %d\n", mask_pos, mask_bit, mask_byte, len);
start += len;
if (mask_pos < 0xf8) ipg->idx_starts[elem++]=start;
@@ -388,7 +430,7 @@ mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg)
/* if this page has not been unpacked to it */
if (!ipg->idx_starts[0]){
-
+ //fprintf(stdout, "Unpacking page %d\n", ipg->pg);
mdb_index_unpack_bitmap(mdb, ipg);
}
@@ -396,7 +438,7 @@ mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg)
if (ipg->idx_starts[ipg->start_pos + 1]==0) return 0;
ipg->len = ipg->idx_starts[ipg->start_pos+1] - ipg->idx_starts[ipg->start_pos];
ipg->start_pos++;
-
+ //fprintf(stdout, "Start pos %d\n", ipg->start_pos);
return ipg->len;
}
@@ -443,13 +485,13 @@ mdb_find_next_leaf(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain \
*chain)
*/
do {
ipg->len = 0;
-
+ //printf("finding next on pg %lu\n", ipg->pg);
if (!mdb_index_find_next_on_page(mdb, ipg)) {
-
+ //printf("find_next_on_page returned 0\n");
return 0;
}
pg = mdb_get_int32_msb(mdb->pg_buf, ipg->offset + ipg->len - 3) >> 8;
-
+ //printf("Looking at pg %lu at %lu %d\n", pg, ipg->offset, ipg->len);
ipg->offset += ipg->len;
/*
@@ -458,7 +500,7 @@ mdb_find_next_leaf(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain \
*chain)
*/
newipg = mdb_chain_add_page(mdb, chain, pg);
newipg = mdb_find_next_leaf(mdb, idx, chain);
-
+ //printf("returning pg %lu\n",newipg->pg);
return newipg;
} while (!passed);
/* no more pages */
@@ -517,9 +559,9 @@ mdb_index_unwind(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain \
*chain) {
MdbIndexPage *ipg;
-
+ //printf("page %lu finished\n",ipg->pg);
if (chain->cur_depth==1) {
-
+ //printf("cur_depth == 1 we're out\n");
return NULL;
}
/*
@@ -528,13 +570,13 @@ mdb_index_unwind(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain \
*chain)
*/
ipg = NULL;
while (chain->cur_depth>1 && ipg==NULL) {
-
+ //printf("chain depth %d\n", chain->cur_depth);
chain->cur_depth--;
ipg = mdb_find_next_leaf(mdb, idx, chain);
if (ipg) mdb_index_find_next_on_page(mdb, ipg);
}
if (chain->cur_depth==1) {
-
+ //printf("last leaf %lu\n", chain->last_leaf_found);
return NULL;
}
return ipg;
@@ -577,20 +619,20 @@ mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, \
MdbIndexChain *chain, guint32 chain->clean_up_mode = 1;
}
if (chain->clean_up_mode) {
-
+ //fprintf(stdout,"in cleanup mode\n");
if (!chain->last_leaf_found) return 0;
mdb_read_pg(mdb, chain->last_leaf_found);
chain->last_leaf_found = mdb_get_int32(
mdb->pg_buf, 0x0c);
-
+ //printf("next leaf %lu\n", chain->last_leaf_found);
mdb_read_pg(mdb, chain->last_leaf_found);
/* reuse the chain for cleanup mode */
chain->cur_depth = 1;
ipg = &chain->pages[0];
mdb_index_page_init(ipg);
ipg->pg = chain->last_leaf_found;
-
+ //printf("next on page %d\n",
if (!mdb_index_find_next_on_page(mdb, ipg))
return 0;
}
@@ -598,28 +640,28 @@ mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, \
MdbIndexChain *chain, guint32 pg_row = mdb_get_int32_msb(mdb->pg_buf, ipg->offset + \
ipg->len - 4);
*row = pg_row & 0xff;
*pg = pg_row >> 8;
-
+ //printf("row = %d pg = %lu ipg->pg = %lu offset = %lu len = %d\n", *row, *pg, \
ipg->pg, ipg->offset, ipg->len); \
col=g_ptr_array_index(idx->table->columns,idx->key_col_num[0]-1); idx_sz = \
mdb_col_fixed_size(col); /* handle compressed indexes, single key indexes only? */
if (idx->num_keys==1 && idx_sz>0 && ipg->len - 4 < idx_sz) {
-
-
+ //printf("short index found\n");
+ //mdb_buffer_dump(ipg->cache_value, 0, idx_sz);
memcpy(&ipg->cache_value[idx_sz - (ipg->len - 4)], &mdb->pg_buf[ipg->offset], \
ipg->len);
-
+ //mdb_buffer_dump(ipg->cache_value, 0, idx_sz);
} else {
idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
memcpy(ipg->cache_value, &mdb->pg_buf[idx_start], idx_sz);
}
-
+ //idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
passed = mdb_index_test_sargs(mdb, idx, (char *)(ipg->cache_value), idx_sz);
ipg->offset += ipg->len;
} while (!passed);
-
-
+ //fprintf(stdout,"len = %d pos %d\n", ipg->len, ipg->mask_pos);
+ //mdb_buffer_dump(mdb->pg_buf, ipg->offset, ipg->len);
return ipg->len;
}
@@ -677,11 +719,12 @@ mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain \
*chain, guint32
void mdb_index_walk(MdbTableDef *table, MdbIndex *idx)
{
-MdbHandle *mdb = table->entry->mdb;
-int cur_pos = 0;
-unsigned char marker;
-MdbColumn *col;
-unsigned int i;
+/*
+ MdbHandle *mdb = table->entry->mdb;
+ int cur_pos = 0;
+ unsigned char marker;
+ MdbColumn *col;
+ unsigned int i;
if (idx->num_keys!=1) return;
@@ -691,8 +734,9 @@ unsigned int i;
for (i=0;i<idx->num_keys;i++) {
marker = mdb->pg_buf[cur_pos++];
col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
-
+ //printf("column %d coltype %d col_size %d (%d)\n",i,col->col_type, \
mdb_col_fixed_size(col), col->col_size); }
+*/
}
void
mdb_index_dump(MdbTableDef *table, MdbIndex *idx)
@@ -759,7 +803,7 @@ int mdb_index_compute_cost(MdbTableDef *table, MdbIndex *idx)
*/
if (idx->flags & MDB_IDX_UNIQUE) {
if (idx->num_keys == 1) {
-
+ //printf("op is %d\n", sarg->op);
switch (sarg->op) {
case MDB_EQUAL:
return 1; break;
@@ -831,7 +875,7 @@ mdb_choose_index(MdbTableDef *table, int *choice)
for (i=0;i<table->num_idxs;i++) {
idx = g_ptr_array_index (table->indices, i);
cost = mdb_index_compute_cost(table, idx);
-
+ //printf("cost for %s is %d\n", idx->name, cost);
if (cost && cost < least) {
least = cost;
*choice = i;
@@ -852,9 +896,9 @@ mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table)
table->chain = g_malloc0(sizeof(MdbIndexChain));
table->mdbidx = mdb_clone_handle(mdb);
mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
-
+ //printf("best index is %s\n",table->scan_idx->name);
}
-
+ //printf("TABLE SCAN? %d\n", table->strategy);
}
void
mdb_index_scan_free(MdbTableDef *table)
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/like.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/like.c index 4e6d554..e89c11d 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/like.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/like.c
@@ -12,14 +12,13 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
-#include <mdbtools.h>
+#include "mdbtools.h"
#ifdef DMALLOC
#include "dmalloc.h"
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/map.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/map.c index 1788b27..2566074 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/map.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/map.c
@@ -12,9 +12,8 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mdbtools.h"
@@ -23,7 +22,7 @@
#include "dmalloc.h"
#endif
-static guint32
+static gint32
mdb_map_find_next0(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 \
start_pg) {
guint32 pgnum, i, usage_bitlen;
@@ -42,7 +41,7 @@ mdb_map_find_next0(MdbHandle *mdb, unsigned char *map, unsigned int \
map_sz, guin /* didn't find anything */
return 0;
}
-static int
+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;
@@ -83,7 +82,10 @@ mdb_map_find_next1(MdbHandle *mdb, unsigned char *map, unsigned \
int map_sz, guin /* didn't find anything */
return 0;
}
-guint32
+
+/* returns 0 on EOF */
+/* returns -1 on error (unsupported map type) */
+gint32
mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 \
start_pg) {
if (map[0] == 0) {
@@ -114,11 +116,14 @@ mdb_map_find_next_freepage(MdbTableDef *table, int row_size)
pgnum = mdb_map_find_next(mdb,
table->free_usage_map,
table->freemap_sz, cur_pg);
-
+ //printf("looking at page %d\n", pgnum);
if (!pgnum) {
/* allocate new page */
pgnum = mdb_alloc_page(table);
return pgnum;
+ } else if (pgnum==-1) {
+ fprintf(stderr, "Error: mdb_map_find_next_freepage error while reading maps.\n");
+ exit(1);
}
cur_pg = pgnum;
@@ -127,7 +132,7 @@ mdb_map_find_next_freepage(MdbTableDef *table, int row_size)
} while (free_space < row_size);
-
+ //printf("page %d has %d bytes left\n", pgnum, free_space);
return pgnum;
}
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/mem.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/mem.c index 92fc20c..6f871cd 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/mem.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/mem.c
@@ -12,45 +12,20 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef JAVA
-#include "javadefines.h"
-#else
+
#include "mdbtools.h"
-#include <locale.h>
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-#endif /* JAVA */
-/**
- * mdb_init:
- *
- * Initializes the LibMDB library. This function should be called exactly once
- * by calling program and prior to any other function.
- *
- **/
-/* METHOD */ void mdb_init()
+MDB_DEPRECATED(void,
+mdb_init())
{
-#if !MDB_NO_BACKENDS
- mdb_init_backends();
-#endif
+ fprintf(stderr, "mdb_init() is DEPRECATED and does nothing. Stop calling it.\n");
}
-/**
- * mdb_exit:
- *
- * Cleans up the LibMDB library. This function should be called exactly once
- * by the calling program prior to exiting (or prior to final use of LibMDB
- * functions).
- *
- **/
-/* METHOD */ void mdb_exit()
+MDB_DEPRECATED(void,
+mdb_exit())
{
-#if !MDB_NO_BACKENDS
- mdb_remove_backends();
-#endif
+ fprintf(stderr, "mdb_exit() is DEPRECATED and does nothing. Stop calling it.\n");
}
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/money.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/money.c index 370d632..488d570 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/money.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/money.c
@@ -12,9 +12,8 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
@@ -24,10 +23,10 @@
#include "dmalloc.h"
#endif
-#define MAXPRECISION 19
+#define MAX_NUMERIC_PRECISION 28
/*
** these routines are copied from the freetds project which does something
-** very similar
+** very similiar
*/
static int multiply_byte(unsigned char *product, int num, unsigned char \
*multiplier); @@ -43,41 +42,70 @@ static char *array_to_string(unsigned char *array, \
int unsigned scale, int neg);
*/
char *mdb_money_to_string(MdbHandle *mdb, int start)
{
- #define num_bytes 8
+ int num_bytes=8, scale=4;
int i;
int neg=0;
- unsigned char multiplier[MAXPRECISION], temp[MAXPRECISION];
- unsigned char product[MAXPRECISION];
- unsigned char money[num_bytes];
+ unsigned char multiplier[MAX_NUMERIC_PRECISION], temp[MAX_NUMERIC_PRECISION];
+ unsigned char product[MAX_NUMERIC_PRECISION];
+ unsigned char bytes[num_bytes];
- memset(multiplier,0,MAXPRECISION);
- memset(product,0,MAXPRECISION);
+ memset(multiplier,0,MAX_NUMERIC_PRECISION);
+ memset(product,0,MAX_NUMERIC_PRECISION);
multiplier[0]=1;
- memcpy(money, mdb->pg_buf + start, num_bytes);
+ memcpy(bytes, mdb->pg_buf + start, num_bytes);
/* Perform two's complement for negative numbers */
- if (money[7] & 0x80) {
+ if (bytes[num_bytes-1] & 0x80) {
neg = 1;
for (i=0;i<num_bytes;i++) {
- money[i] = ~money[i];
+ bytes[i] = ~bytes[i];
}
for (i=0; i<num_bytes; i++) {
- money[i] ++;
- if (money[i]!=0) break;
+ bytes[i] ++;
+ if (bytes[i]!=0) break;
}
}
for (i=0;i<num_bytes;i++) {
/* product += multiplier * current byte */
- multiply_byte(product, money[i], multiplier);
+ multiply_byte(product, bytes[i], multiplier);
/* multiplier = multiplier * 256 */
- memcpy(temp, multiplier, MAXPRECISION);
- memset(multiplier,0,MAXPRECISION);
+ memcpy(temp, multiplier, MAX_NUMERIC_PRECISION);
+ memset(multiplier, 0, MAX_NUMERIC_PRECISION);
multiply_byte(multiplier, 256, temp);
}
- return array_to_string(product, 4, neg);
+ return array_to_string(product, scale, neg);
+
+}
+
+char *mdb_numeric_to_string(MdbHandle *mdb, int start, int prec, int scale) {
+ int num_bytes = 16;
+ int i;
+ int neg=0;
+ unsigned char multiplier[MAX_NUMERIC_PRECISION], temp[MAX_NUMERIC_PRECISION];
+ unsigned char product[MAX_NUMERIC_PRECISION];
+ unsigned char bytes[num_bytes];
+
+ memset(multiplier,0,MAX_NUMERIC_PRECISION);
+ memset(product,0,MAX_NUMERIC_PRECISION);
+ multiplier[0]=1;
+ memcpy(bytes, mdb->pg_buf + start + 1, num_bytes);
+
+ /* Perform two's complement for negative numbers */
+ if (mdb->pg_buf[start] & 0x80) neg = 1;
+ for (i=0;i<num_bytes;i++) {
+ /* product += multiplier * current byte */
+ multiply_byte(product, bytes[12-4*(i/4)+i%4], multiplier);
+
+ /* multiplier = multiplier * 256 */
+ memcpy(temp, multiplier, MAX_NUMERIC_PRECISION);
+ memset(multiplier, 0, MAX_NUMERIC_PRECISION);
+ multiply_byte(multiplier, 256, temp);
+ }
+ return array_to_string(product, scale, neg);
}
+
static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier)
{
unsigned char number[3];
@@ -87,7 +115,7 @@ static int multiply_byte(unsigned char *product, int num, unsigned \
char *multipl number[1]=(num/10)%10;
number[2]=(num/100)%10;
- for (i=0;i<MAXPRECISION;i++) {
+ for (i=0;i<MAX_NUMERIC_PRECISION;i++) {
if (multiplier[i] == 0) continue;
for (j=0;j<3;j++) {
if (number[j] == 0) continue;
@@ -101,7 +129,7 @@ static int do_carry(unsigned char *product)
{
unsigned int j;
- for (j=0;j<MAXPRECISION-1;j++) {
+ for (j=0;j<MAX_NUMERIC_PRECISION-1;j++) {
if (product[j]>9) {
product[j+1]+=product[j]/10;
product[j]=product[j]%10;
@@ -117,9 +145,10 @@ static char *array_to_string(unsigned char *array, unsigned int \
scale, int neg) char *s;
unsigned int top, i, j=0;
- for (top=MAXPRECISION;(top>0) && (top-1>scale) && !array[top-1];top--);
+ for (top=MAX_NUMERIC_PRECISION;(top>0) && (top-1>scale) && \
!array[top-1];top--);
- s = (char *) g_malloc(22);
+ /* allocate enough space for all digits + minus sign + decimal point + \
trailing NULL byte */ + s = (char *) g_malloc(MAX_NUMERIC_PRECISION+3);
if (neg)
s[j++] = '-';
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/options.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/options.c index 6b43a0e..02af719 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/options.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/options.c
@@ -12,17 +12,15 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
-
-#include <mdbtools.h>
+#include "mdbtools.h"
#ifdef DMALLOC
#include "dmalloc.h"
@@ -36,17 +34,17 @@ static int optset;
static void load_options();
void
-mdb_debug(int klass, char *fmt, ...)
+mdb_debug(int klass, const char *fmt, ...)
{
#ifdef DEBUG
va_list ap;
if (!optset) load_options();
if (klass & opts) {
- va_start(ap, fmt);
- vfprintf (stdout,fmt, ap);
- va_end(ap);
- fprintf(stdout,"\n");
+ va_start(ap, fmt);
+ vfprintf (stderr,fmt, ap);
+ va_end(ap);
+ fprintf(stderr,"\n");
}
#endif
}
@@ -57,26 +55,28 @@ load_options()
char *opt;
char *s;
- if (!optset && (s=getenv("MDBOPTS"))) {
+ if (!optset && (s=getenv("MDBOPTS"))) {
opt = strtok(s, ":");
- do {
- if (!strcmp(opt, "use_index")) opts |= MDB_USE_INDEX;
- if (!strcmp(opt, "no_memo")) opts |= MDB_NO_MEMO;
- if (!strcmp(opt, "debug_like")) opts |= MDB_DEBUG_LIKE;
- if (!strcmp(opt, "debug_write")) opts |= MDB_DEBUG_WRITE;
- if (!strcmp(opt, "debug_usage")) opts |= MDB_DEBUG_USAGE;
- if (!strcmp(opt, "debug_ole")) opts |= MDB_DEBUG_OLE;
- if (!strcmp(opt, "debug_row")) opts |= MDB_DEBUG_ROW;
- if (!strcmp(opt, "debug_all")) {
+ while (opt) {
+ if (!strcmp(opt, "use_index")) opts |= MDB_USE_INDEX;
+ if (!strcmp(opt, "no_memo")) opts |= MDB_NO_MEMO;
+ if (!strcmp(opt, "debug_like")) opts |= MDB_DEBUG_LIKE;
+ if (!strcmp(opt, "debug_write")) opts |= MDB_DEBUG_WRITE;
+ if (!strcmp(opt, "debug_usage")) opts |= MDB_DEBUG_USAGE;
+ if (!strcmp(opt, "debug_ole")) opts |= MDB_DEBUG_OLE;
+ if (!strcmp(opt, "debug_row")) opts |= MDB_DEBUG_ROW;
+ if (!strcmp(opt, "debug_props")) opts |= MDB_DEBUG_PROPS;
+ if (!strcmp(opt, "debug_all")) {
opts |= MDB_DEBUG_LIKE;
opts |= MDB_DEBUG_WRITE;
opts |= MDB_DEBUG_USAGE;
opts |= MDB_DEBUG_OLE;
opts |= MDB_DEBUG_ROW;
+ opts |= MDB_DEBUG_PROPS;
}
opt = strtok(NULL,":");
- } while (opt);
- }
+ }
+ }
optset = 1;
}
int
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/props.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/props.c new file mode 100644
index 0000000..38e0660
--- /dev/null
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/props.c
@@ -0,0 +1,215 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000-2011 Brian Bruns and others
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mdbtools.h"
+
+static GPtrArray *
+mdb_read_props_list(MdbHandle *mdb, gchar *kkd, int len)
+{
+ guint32 record_len;
+ int pos = 0;
+ gchar *name;
+ GPtrArray *names = NULL;
+ int i=0;
+
+ names = g_ptr_array_new();
+#if MDB_DEBUG
+ mdb_buffer_dump(kkd, 0, len);
+#endif
+ pos = 0;
+ while (pos < len) {
+ record_len = mdb_get_int16(kkd, pos);
+ pos += 2;
+ if (mdb_get_option(MDB_DEBUG_PROPS)) {
+ fprintf(stderr, "%02d ",i++);
+ mdb_buffer_dump(kkd, pos - 2, record_len + 2);
+ }
+ name = g_malloc(3*record_len + 1); /* worst case scenario is 3 bytes out per byte \
in */ + mdb_unicode2ascii(mdb, &kkd[pos], record_len, name, 3*record_len);
+
+ pos += record_len;
+ g_ptr_array_add(names, name);
+#if MDB_DEBUG
+ printf("new len = %d\n", names->len);
+#endif
+ }
+ return names;
+}
+static gboolean
+free_hash_entry(gpointer key, gpointer value, gpointer user_data)
+{
+ g_free(key);
+ g_free(value);
+ return TRUE;
+}
+void
+mdb_free_props(MdbProperties *props)
+{
+ if (!props) return;
+
+ if (props->name) g_free(props->name);
+ if (props->hash) {
+ g_hash_table_foreach(props->hash, (GHFunc)free_hash_entry, 0);
+ g_hash_table_destroy(props->hash);
+ }
+ g_free(props);
+}
+
+static void
+free_names(GPtrArray *names) {
+ g_ptr_array_foreach(names, (GFunc)g_free, NULL);
+ g_ptr_array_free(names, TRUE);
+}
+MdbProperties *
+mdb_alloc_props()
+{
+ MdbProperties *props;
+
+ props = g_malloc0(sizeof(MdbProperties));
+
+ return props;
+}
+static MdbProperties *
+mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len)
+{
+ guint32 record_len, name_len;
+ int pos = 0;
+ int elem, dtype, dsize;
+ gchar *name, *value;
+ MdbProperties *props;
+ int i=0;
+
+#if MDB_DEBUG
+ mdb_buffer_dump(kkd, 0, len);
+#endif
+ pos = 0;
+
+ record_len = mdb_get_int16(kkd, pos);
+ pos += 4;
+ name_len = mdb_get_int16(kkd, pos);
+ pos += 2;
+ props = mdb_alloc_props();
+ if (name_len) {
+ props->name = g_malloc(3*name_len + 1);
+ mdb_unicode2ascii(mdb, kkd+pos, name_len, props->name, 3*name_len);
+ mdb_debug(MDB_DEBUG_PROPS,"prop block named: %s", props->name);
+ }
+ pos += name_len;
+
+ props->hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+ while (pos < len) {
+ record_len = mdb_get_int16(kkd, pos);
+ dtype = kkd[pos + 3];
+ elem = mdb_get_int16(kkd, pos + 4);
+ dsize = mdb_get_int16(kkd, pos + 6);
+ value = g_malloc(dsize + 1);
+ strncpy(value, &kkd[pos + 8], dsize);
+ value[dsize] = '\0';
+ name = g_ptr_array_index(names,elem);
+ if (mdb_get_option(MDB_DEBUG_PROPS)) {
+ fprintf(stderr, "%02d ",i++);
+ mdb_debug(MDB_DEBUG_PROPS,"elem %d (%s) dsize %d dtype %d", elem, name, dsize, \
dtype); + mdb_buffer_dump(value, 0, dsize);
+ }
+ if (dtype == MDB_MEMO) dtype = MDB_TEXT;
+ if (dtype == MDB_BOOL) {
+ g_hash_table_insert(props->hash, g_strdup(name),
+ g_strdup(kkd[pos + 8] ? "yes" : "no"));
+ } else {
+ g_hash_table_insert(props->hash, g_strdup(name),
+ mdb_col_to_string(mdb, kkd, pos + 8, dtype, dsize));
+ }
+ g_free(value);
+ pos += record_len;
+ }
+ return props;
+
+}
+
+static void
+print_keyvalue(gpointer key, gpointer value, gpointer outfile)
+{
+ fprintf((FILE*)outfile,"\t%s: %s\n", (gchar *)key, (gchar *)value);
+}
+void
+mdb_dump_props(MdbProperties *props, FILE *outfile, int show_name) {
+ if (show_name)
+ fprintf(outfile,"name: %s\n", props->name ? props->name : "(none)");
+ g_hash_table_foreach(props->hash, print_keyvalue, outfile);
+ if (show_name)
+ fputc('\n', outfile);
+}
+
+/*
+ * That function takes a raw KKD/MR2 binary buffer,
+ * typically read from LvProp in table MSysbjects
+ * and returns a GArray of MdbProps*
+ */
+GArray*
+mdb_kkd_to_props(MdbHandle *mdb, void *buffer, size_t len) {
+ guint32 record_len;
+ guint16 record_type;
+ size_t pos;
+ GPtrArray *names = NULL;
+ MdbProperties *props;
+ GArray *result;
+
+#if MDB_DEBUG
+ mdb_buffer_dump(buffer, 0, len);
+#endif
+ mdb_debug(MDB_DEBUG_PROPS,"starting prop parsing of type %s", buffer);
+
+ if (strcmp("KKD", buffer) && strcmp("MR2", buffer)) {
+ fprintf(stderr, "Unrecognized format.\n");
+ mdb_buffer_dump(buffer, 0, len);
+ return NULL;
+ }
+
+ result = g_array_new(0, 0, sizeof(MdbProperties*));
+
+ pos = 4;
+ while (pos < len) {
+ record_len = mdb_get_int32(buffer, pos);
+ record_type = mdb_get_int16(buffer, pos + 4);
+ mdb_debug(MDB_DEBUG_PROPS,"prop chunk type:0x%04x len:%d", record_type, \
record_len); + //mdb_buffer_dump(buffer, pos+4, record_len);
+ switch (record_type) {
+ case 0x80:
+ if (names) free_names(names);
+ names = mdb_read_props_list(mdb, buffer+pos+6, record_len - 6);
+ break;
+ case 0x00:
+ case 0x01:
+ if (!names) {
+ fprintf(stderr,"sequence error!\n");
+ break;
+ }
+ props = mdb_read_props(mdb, names, buffer+pos+6, record_len - 6);
+ g_array_append_val(result, props);
+ //mdb_dump_props(props, stderr, 1);
+ break;
+ default:
+ fprintf(stderr,"Unknown record type %d\n", record_type);
+ break;
+ }
+ pos += record_len;
+ }
+ if (names) free_names(names);
+ return result;
+}
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/sargs.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/sargs.c index 83499f7..cee28c0 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/sargs.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/sargs.c
@@ -12,9 +12,8 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
@@ -27,8 +26,9 @@
* datatype support is a bit weak at this point. To add more types create
* a mdb_test_[type]() function and invoke it from mdb_test_sarg()
*/
-#include "mdbtools.h"
+#include <time.h>
+#include "mdbtools.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
@@ -76,7 +76,7 @@ int mdb_test_int(MdbSargNode *node, gint32 i)
{
switch (node->op) {
case MDB_EQUAL:
-
+ //fprintf(stderr, "comparing %ld and %ld\n", i, node->value.i);
if (node->value.i == i) return 1;
break;
case MDB_GT:
@@ -97,8 +97,51 @@ int mdb_test_int(MdbSargNode *node, gint32 i)
}
return 0;
}
-#if 0
-#endif
+
+int
+mdb_test_date(MdbSargNode *node, double td)
+{
+ struct tm found;
+ /* TODO: you should figure out a way to pull mdb_date_to_string in here
+ * char date_tmp[MDB_BIND_SIZE];
+ */
+
+ time_t found_t;
+ time_t asked_t;
+
+ double diff;
+
+ mdb_date_to_tm(td, &found);
+
+ asked_t = node->value.i;
+ found_t = mktime(&found);
+
+ diff = difftime(asked_t, found_t);
+
+ switch (node->op) {
+ case MDB_EQUAL:
+ if (diff==0) return 1;
+ break;
+ case MDB_GT:
+ if (diff<0) return 1;
+ break;
+ case MDB_LT:
+ if (diff>0) return 1;
+ break;
+ case MDB_GTEQ:
+ if (diff<=0) return 1;
+ break;
+ case MDB_LTEQ:
+ if (diff>=0) return 1;
+ break;
+ default:
+ fprintf(stderr, "Calling mdb_test_sarg on unknown operator. Add code to \
mdb_test_date() for operator %d\n", node->op); + break;
+ }
+ return 0;
+}
+
+
int
mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
{
@@ -120,7 +163,7 @@ mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
* probably better off table scanning.
*/
if (mdb_is_relational_op(node->op) && node->col) {
-
+ //printf("op = %d value = %s\n", node->op, node->value.s);
sarg.op = node->op;
sarg.value = node->value;
mdb_add_sarg(node->col, &sarg);
@@ -155,6 +198,8 @@ mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, \
MdbField *field case MDB_TEXT:
mdb_unicode2ascii(mdb, field->value, field->siz, tmpbuf, 256);
return mdb_test_string(node, tmpbuf);
+ case MDB_DATETIME:
+ return mdb_test_date(node, mdb_get_double(field->value, 0));
default:
fprintf(stderr, "Calling mdb_test_sarg on unknown type. Add code to \
mdb_test_sarg() for type %d\n",col->col_type); break;
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/stats.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/stats.c new file mode 100644
index 0000000..3719826
--- /dev/null
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/stats.c
@@ -0,0 +1,77 @@
+/* MDB Tools - A library for reading MS Access database files
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mdbtools.h"
+
+#if !MDB_NO_STATS
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/**
+ * mdb_stats_on:
+ * @mdb: Handle to the (open) MDB file to collect stats on.
+ *
+ * Begins collection of statistics on an MDBHandle.
+ *
+ * Statistics in LibMDB will track the number of reads from the MDB file. The
+ * collection of statistics is started and stopped with the mdb_stats_on and
+ * mdb_stats_off functions. Collected statistics are accessed by reading the
+ * MdbStatistics structure or calling mdb_dump_stats.
+ *
+ */
+void
+mdb_stats_on(MdbHandle *mdb)
+{
+ if (!mdb->stats)
+ mdb->stats = g_malloc0(sizeof(MdbStatistics));
+
+ mdb->stats->collect = TRUE;
+}
+/**
+ * mdb_stats_off:
+ * @mdb: pointer to handle of MDB file with active stats collection.
+ *
+ * Turns off statistics collection.
+ *
+ * If mdb_stats_off is not called, statistics will be turned off when handle
+ * is freed using mdb_close.
+ **/
+void
+mdb_stats_off(MdbHandle *mdb)
+{
+ if (!mdb->stats) return;
+
+ mdb->stats->collect = FALSE;
+}
+/**
+ * mdb_dump_stats:
+ * @mdb: pointer to handle of MDB file with active stats collection.
+ *
+ * Dumps current statistics to stdout.
+ **/
+void
+mdb_dump_stats(MdbHandle *mdb)
+{
+ if (!mdb->stats) return;
+
+ fprintf(stdout, "Physical Page Reads: %lu\n", mdb->stats->pg_reads);
+}
+
+#endif /* !MDB_NO_STATS */
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/table.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/table.c index 1698e0f..89611c1 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/table.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/table.c
@@ -12,9 +12,8 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mdbtools.h"
@@ -76,15 +75,16 @@ MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
MdbTableDef *table;
MdbHandle *mdb = entry->mdb;
MdbFormatConstants *fmt = mdb->fmt;
- int len, row_start, pg_row;
+ int row_start, pg_row;
void *buf, *pg_buf = mdb->pg_buf;
+ guint i;
mdb_read_pg(mdb, entry->table_pg);
if (mdb_get_byte(pg_buf, 0) != 0x02) /* not a valid table def page */
return NULL;
table = mdb_alloc_tabledef(entry);
- len = mdb_get_int16(pg_buf, 8);
+ mdb_get_int16(pg_buf, 8); /* len */
table->num_rows = mdb_get_int32(pg_buf, fmt->tab_num_rows_offset);
table->num_var_cols = mdb_get_int16(pg_buf, fmt->tab_num_cols_offset-2);
@@ -97,7 +97,7 @@ MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->map_sz));
table->usage_map = g_memdup((char*)buf + row_start, table->map_sz);
if (mdb_get_option(MDB_DEBUG_USAGE))
- buffer_dump(buf, row_start, table->map_sz);
+ mdb_buffer_dump(buf, row_start, table->map_sz);
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);
@@ -110,6 +110,13 @@ MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
table->first_data_pg = mdb_get_int16(pg_buf, fmt->tab_first_dpg_offset);
+ if (entry->props)
+ for (i=0; i<entry->props->len; ++i) {
+ MdbProperties *props = g_array_index(entry->props, MdbProperties*, i);
+ if (!props->name)
+ table->props = props;
+ }
+
return table;
}
MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type)
@@ -161,7 +168,6 @@ read_pg_if_8(MdbHandle *mdb, int *cur_pos)
void *
read_pg_if_n(MdbHandle *mdb, void *buf, int *cur_pos, size_t len)
{
- char *buf_char = (char *)buf;
/* Advance to page which contains the first byte */
while (*cur_pos >= mdb->fmt->pg_size) {
mdb_read_pg(mdb, mdb_get_int32(mdb->pg_buf,4));
@@ -170,20 +176,20 @@ read_pg_if_n(MdbHandle *mdb, void *buf, int *cur_pos, size_t \
len) /* Copy pages into buffer */
while (*cur_pos + len >= mdb->fmt->pg_size) {
int piece_len = mdb->fmt->pg_size - *cur_pos;
- if (buf_char) {
- memcpy(buf_char, mdb->pg_buf + *cur_pos, piece_len);
- buf_char += piece_len;
+ if (buf) {
+ memcpy(buf, mdb->pg_buf + *cur_pos, piece_len);
+ buf += piece_len;
}
len -= piece_len;
mdb_read_pg(mdb, mdb_get_int32(mdb->pg_buf,4));
*cur_pos = 8;
}
/* Copy into buffer from final page */
- if (len && buf_char) {
- memcpy(buf_char, mdb->pg_buf + *cur_pos, len);
+ if (len && buf) {
+ memcpy(buf, mdb->pg_buf + *cur_pos, len);
}
*cur_pos += len;
- return buf_char;
+ return buf;
}
@@ -193,11 +199,20 @@ void mdb_append_column(GPtrArray *columns, MdbColumn *in_col)
}
void mdb_free_columns(GPtrArray *columns)
{
- unsigned int i;
+ unsigned int i, j;
+ MdbColumn *col;
if (!columns) return;
- for (i=0; i<columns->len; i++)
- g_free (g_ptr_array_index(columns, i));
+ for (i=0; i<columns->len; i++) {
+ col = (MdbColumn *) g_ptr_array_index(columns, i);
+ if (col->sargs) {
+ for (j=0; j<col->sargs->len; j++) {
+ g_free( g_ptr_array_index(col->sargs, j));
+ }
+ g_ptr_array_free(col->sargs, TRUE);
+ }
+ g_free(col);
+ }
g_ptr_array_free(columns, TRUE);
}
GPtrArray *mdb_read_columns(MdbTableDef *table)
@@ -206,9 +221,10 @@ GPtrArray *mdb_read_columns(MdbTableDef *table)
MdbFormatConstants *fmt = mdb->fmt;
MdbColumn *pcol;
unsigned char *col;
- unsigned int i;
+ unsigned int i, j;
int cur_pos;
size_t name_sz;
+ GArray *allprops;
table->columns = g_ptr_array_new();
@@ -225,24 +241,26 @@ GPtrArray *mdb_read_columns(MdbTableDef *table)
for (i=0;i<table->num_cols;i++) {
#ifdef MDB_DEBUG
/* printf("column %d\n", i);
- buffer_dump(mdb->pg_buf, cur_pos, fmt->tab_col_entry_size); */
+ mdb_buffer_dump(mdb->pg_buf, cur_pos, fmt->tab_col_entry_size); */
#endif
read_pg_if_n(mdb, col, &cur_pos, fmt->tab_col_entry_size);
pcol = (MdbColumn *) g_malloc0(sizeof(MdbColumn));
- pcol->col_type = col[0];
+ pcol->table = table;
+ pcol->col_type = col[0];
+ // col_num_offset == 1 or 5
pcol->col_num = col[fmt->col_num_offset];
-
-
+ //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);
-
-
+ // 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);
/* FIXME: can this be right in Jet3 and Jet4? */
if (pcol->col_type == MDB_NUMERIC) {
@@ -250,16 +268,18 @@ GPtrArray *mdb_read_columns(MdbTableDef *table)
pcol->col_scale = col[12];
}
+ // col_flags_offset == 13 or 15
+ pcol->is_fixed = col[fmt->col_flags_offset] & 0x01 ? 1 : 0;
+ pcol->is_long_auto = col[fmt->col_flags_offset] & 0x04 ? 1 : 0;
+ pcol->is_uuid_auto = col[fmt->col_flags_offset] & 0x40 ? 1 : 0;
- pcol->is_fixed = col[fmt->col_fixed_offset] & 0x01 ? 1 : 0;
-
-
+ // tab_col_offset_fixed == 14 or 21
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;
@@ -277,24 +297,34 @@ GPtrArray *mdb_read_columns(MdbTableDef *table)
char *tmp_buf;
pcol = g_ptr_array_index(table->columns, i);
- if (IS_JET4(mdb)) {
- name_sz = read_pg_if_16(mdb, &cur_pos);
- } else if (IS_JET3(mdb)) {
+ if (IS_JET3(mdb))
name_sz = read_pg_if_8(mdb, &cur_pos);
- } else {
- fprintf(stderr,"Unknown MDB version\n");
- continue;
- }
+ else
+ name_sz = read_pg_if_16(mdb, &cur_pos);
tmp_buf = (char *) g_malloc(name_sz);
read_pg_if_n(mdb, tmp_buf, &cur_pos, name_sz);
mdb_unicode2ascii(mdb, tmp_buf, name_sz, pcol->name, MDB_MAX_OBJ_NAME);
g_free(tmp_buf);
+
}
/* Sort the columns by col_num */
g_ptr_array_sort(table->columns, (GCompareFunc)mdb_col_comparer);
+ allprops = table->entry->props;
+ if (allprops)
+ for (i=0;i<table->num_cols;i++) {
+ pcol = g_ptr_array_index(table->columns, i);
+ for (j=0; j<allprops->len; ++j) {
+ MdbProperties *props = g_array_index(allprops, MdbProperties*, j);
+ if (props->name && pcol->name && !strcmp(props->name, pcol->name)) {
+ pcol->props = props;
+ break;
+ }
+
+ }
+ }
table->index_start = cur_pos;
return table->columns;
}
@@ -306,7 +336,6 @@ MdbTableDef *table;
MdbColumn *col;
int coln;
MdbIndex *idx;
-MdbHandle *mdb = entry->mdb;
unsigned int i, bitn;
guint32 pgnum;
@@ -316,6 +345,8 @@ guint32 pgnum;
fprintf(stdout,"number of columns = %d\n",table->num_cols);
fprintf(stdout,"number of indices = %d\n",table->num_real_idxs);
+ if (table->props)
+ mdb_dump_props(table->props, stdout, 0);
mdb_read_columns(table);
mdb_read_indices(table);
@@ -324,8 +355,10 @@ guint32 pgnum;
fprintf(stdout,"column %d Name: %-20s Type: %s(%d)\n",
i, col->name,
- mdb_get_coltype_string(mdb->default_backend, col->col_type),
+ mdb_get_colbacktype_string(col),
col->col_size);
+ if (col->props)
+ mdb_dump_props(col->props, stdout, 0);
}
for (i=0;i<table->num_idxs;i++) {
@@ -371,3 +404,17 @@ int mdb_is_system_table(MdbCatalogEntry *entry)
return ((entry->object_type == MDB_TABLE)
&& (entry->flags & 0x80000002)) ? 1 : 0;
}
+
+const char *
+mdb_table_get_prop(const MdbTableDef *table, const gchar *key) {
+ if (!table->props)
+ return NULL;
+ return g_hash_table_lookup(table->props->hash, key);
+}
+
+const char *
+mdb_col_get_prop(const MdbColumn *col, const gchar *key) {
+ if (!col->props)
+ return NULL;
+ return g_hash_table_lookup(col->props->hash, key);
+}
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/worktable.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/worktable.c index 09c064d..a398d98 \
100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/worktable.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/worktable.c
@@ -12,9 +12,8 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mdbtools.h"
@@ -74,6 +73,7 @@ mdb_create_temp_table(MdbHandle *mdb, char *name)
void
mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col)
{
+ col->table = table,
col->col_num = table->num_cols;
if (!col->is_fixed)
col->var_col_num = table->num_var_cols++;
diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/write.c \
b/src/migration/mdb/3rdparty/mdbtools/libmdb/write.c index 69da633..95b806e 100644
--- a/src/migration/mdb/3rdparty/mdbtools/libmdb/write.c
+++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/write.c
@@ -12,41 +12,65 @@
* 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <time.h>
+#include <math.h>
+#include <inttypes.h>
#include "mdbtools.h"
-#include "time.h"
-#include "math.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
-
+//static int mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage \
*ipg); static int mdb_add_row_to_leaf_pg(MdbTableDef *table, MdbIndex *idx, \
MdbIndexPage *ipg, MdbField *idx_fields, guint32 pgnum, guint16 rownum);
void
-_mdb_put_int16(void *buf, guint32 offset, guint32 value)
+mdb_put_int16(void *buf, guint32 offset, guint32 value)
{
value = GINT32_TO_LE(value);
memcpy((char*)buf + offset, &value, 2);
}
void
-_mdb_put_int32(void *buf, guint32 offset, guint32 value)
+_mdb_put_int16(void *buf, guint32 offset, guint32 value)
+#ifdef HAVE_ATTRIBUTE_ALIAS
+__attribute__((alias("mdb_put_int16")));
+#else
+{ mdb_put_int16((char*)buf, offset, value); }
+#endif
+
+void
+mdb_put_int32(void *buf, guint32 offset, guint32 value)
{
value = GINT32_TO_LE(value);
memcpy((char*)buf + offset, &value, 4);
}
void
-_mdb_put_int32_msb(void *buf, guint32 offset, guint32 value)
+_mdb_put_int32(void *buf, guint32 offset, guint32 value)
+#ifdef HAVE_ATTRIBUTE_ALIAS
+__attribute__((alias("mdb_put_int32")));
+#else
+{ mdb_put_int32((char*)buf, offset, value); }
+#endif
+
+void
+mdb_put_int32_msb(void *buf, guint32 offset, guint32 value)
{
value = GINT32_TO_BE(value);
memcpy((char*)buf + offset, &value, 4);
}
+void
+_mdb_put_int32_mdb(void *buf, guint32 offset, guint32 value)
+#ifdef HAVE_ATTRIBUTE_ALIAS
+__attribute__((alias("mdb_put_int32_msb")));
+#else
+{ mdb_put_int32_msb((char*)buf, offset, value); }
+#endif
+
ssize_t
mdb_write_pg(MdbHandle *mdb, unsigned long pg)
{
@@ -57,7 +81,7 @@ mdb_write_pg(MdbHandle *mdb, unsigned long pg)
fstat(mdb->f->fd, &status);
/* is page beyond current size + 1 ? */
if ((size_t)status.st_size < (offset + mdb->fmt->pg_size)) {
- fprintf(stderr,"offset %lu is beyond EOF\n",offset);
+ fprintf(stderr,"offset %jd is beyond EOF\n",(intmax_t)offset);
return 0;
}
lseek(mdb->f->fd, offset, SEEK_SET);
@@ -158,31 +182,31 @@ mdb_crack_row(MdbTableDef *table, int row_start, int row_end, \
MdbField *fields) unsigned int i;
if (mdb_get_option(MDB_DEBUG_ROW)) {
- buffer_dump(pg_buf, row_start, row_end - row_start + 1);
+ mdb_buffer_dump(pg_buf, row_start, row_end - row_start + 1);
}
- if (IS_JET4(mdb)) {
- row_cols = mdb_get_int16(pg_buf, row_start);
- col_count_size = 2;
- } else {
+ if (IS_JET3(mdb)) {
row_cols = mdb_get_byte(pg_buf, row_start);
col_count_size = 1;
+ } else {
+ row_cols = mdb_get_int16(pg_buf, row_start);
+ col_count_size = 2;
}
bitmask_sz = (row_cols + 7) / 8;
- nullmask = (unsigned char*)pg_buf + row_end - bitmask_sz + 1;
+ nullmask = (unsigned char *)pg_buf + row_end - bitmask_sz + 1;
/* read table of variable column locations */
- row_var_cols = IS_JET4(mdb) ?
- mdb_get_int16(pg_buf, row_end - bitmask_sz - 1) :
- mdb_get_byte(pg_buf, row_end - bitmask_sz);
- var_col_offsets = (unsigned int *)g_malloc((row_var_cols+1)*sizeof(int));
if (table->num_var_cols > 0) {
- if (IS_JET4(mdb)) {
- mdb_crack_row4(mdb, row_start, row_end, bitmask_sz,
+ row_var_cols = IS_JET3(mdb) ?
+ mdb_get_byte(pg_buf, row_end - bitmask_sz) :
+ mdb_get_int16(pg_buf, row_end - bitmask_sz - 1);
+ var_col_offsets = (unsigned int *)g_malloc((row_var_cols+1)*sizeof(int));
+ if (IS_JET3(mdb)) {
+ mdb_crack_row3(mdb, row_start, row_end, bitmask_sz,
row_var_cols, var_col_offsets);
} else {
- mdb_crack_row3(mdb, row_start, row_end, bitmask_sz,
+ mdb_crack_row4(mdb, row_start, row_end, bitmask_sz,
row_var_cols, var_col_offsets);
}
}
@@ -246,7 +270,7 @@ mdb_pack_null_mask(unsigned char *buffer, int num_fields, \
MdbField *fields) /* column is null if bit is clear (0) */
if (!fields[i].is_null) {
byte |= 1 << bit;
-
+ //printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
}
bit++;
if (bit==8) {
@@ -404,10 +428,10 @@ mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, int \
unsigned num_fie }
}
}
- if (IS_JET4(table->entry->mdb)) {
- return mdb_pack_row4(table, row_buffer, num_fields, fields);
- } else {
+ if (IS_JET3(table->entry->mdb)) {
return mdb_pack_row3(table, row_buffer, num_fields, fields);
+ } else {
+ return mdb_pack_row4(table, row_buffer, num_fields, fields);
}
}
int
@@ -428,8 +452,8 @@ mdb_new_leaf_pg(MdbCatalogEntry *entry)
MdbHandle *mdb = entry->mdb;
void *new_pg = g_malloc0(mdb->fmt->pg_size);
- _mdb_put_int16(new_pg, 2, 0x0104);
- _mdb_put_int32(new_pg, 4, entry->table_pg);
+ mdb_put_int16(new_pg, 0, 0x0104);
+ mdb_put_int32(new_pg, 4, entry->table_pg);
return new_pg;
}
@@ -439,13 +463,14 @@ mdb_new_data_pg(MdbCatalogEntry *entry)
MdbFormatConstants *fmt = entry->mdb->fmt;
void *new_pg = g_malloc0(fmt->pg_size);
- _mdb_put_int16(new_pg, 2, 0x0101);
- _mdb_put_int16(new_pg, 2, fmt->pg_size - fmt->row_count_offset - 2);
- _mdb_put_int32(new_pg, 4, entry->table_pg);
+ mdb_put_int16(new_pg, 0, 0x0101);
+ mdb_put_int16(new_pg, 2, fmt->pg_size - fmt->row_count_offset - 2);
+ mdb_put_int32(new_pg, 4, entry->table_pg);
return new_pg;
}
+/* could be static */
int
mdb_update_indexes(MdbTableDef *table, int num_fields, MdbField *fields, guint32 \
pgnum, guint16 rownum) {
@@ -476,25 +501,22 @@ mdb_init_index_chain(MdbTableDef *table, MdbIndex *idx)
return 1;
}
+/* could be static */
int
mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, \
MdbField *fields, guint32 pgnum, guint16 rownum) {
MdbCatalogEntry *entry = table->entry;
MdbHandle *mdb = entry->mdb;
- /*
- int idx_xref[16];
- */
+ /*int idx_xref[16];*/
unsigned int i, j;
MdbIndexChain *chain;
MdbField idx_fields[10];
for (i = 0; i < idx->num_keys; i++) {
for (j = 0; j < num_fields; j++) {
- /* key_col_num is 1 based, can't remember why though */
+ // key_col_num is 1 based, can't remember why though
if (fields[j].colnum == idx->key_col_num[i]-1) {
- /*
- idx_xref[i] = j;
- */
+ /* idx_xref[i] = j; */
idx_fields[i] = fields[j];
}
}
@@ -515,10 +537,10 @@ mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned \
int num_fields, Mdb chain = g_malloc0(sizeof(MdbIndexChain));
mdb_index_find_row(mdb, idx, chain, pgnum, rownum);
-
-
-
-
+ //printf("chain depth = %d\n", chain->cur_depth);
+ //printf("pg = %" G_GUINT32_FORMAT "\n",
+ //chain->pages[chain->cur_depth-1].pg);
+ //mdb_copy_index_pg(table, idx, &chain->pages[chain->cur_depth-1]);
mdb_add_row_to_leaf_pg(table, idx, &chain->pages[chain->cur_depth-1], idx_fields, \
pgnum, rownum);
return 1;
@@ -541,7 +563,7 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField \
*fields) }
new_row_size = mdb_pack_row(table, row_buffer, num_fields, fields);
if (mdb_get_option(MDB_DEBUG_WRITE)) {
- buffer_dump(row_buffer, 0, new_row_size);
+ mdb_buffer_dump(row_buffer, 0, new_row_size);
}
pgnum = mdb_map_find_next_freepage(table, new_row_size);
if (!pgnum) {
@@ -552,13 +574,13 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField \
*fields) rownum = mdb_add_row_to_pg(table, row_buffer, new_row_size);
if (mdb_get_option(MDB_DEBUG_WRITE)) {
- buffer_dump(mdb->pg_buf, 0, 40);
- buffer_dump(mdb->pg_buf, fmt->pg_size - 160, 160);
+ mdb_buffer_dump(mdb->pg_buf, 0, 40);
+ mdb_buffer_dump(mdb->pg_buf, fmt->pg_size - 160, 160);
}
mdb_debug(MDB_DEBUG_WRITE, "writing page %d", pgnum);
if (!mdb_write_pg(mdb, pgnum)) {
- fprintf(stderr, "write failed! exiting...\n");
- exit(1);
+ fprintf(stderr, "write failed!\n");
+ return 0;
}
mdb_update_indexes(table, num_fields, fields, pgnum, rownum);
@@ -606,7 +628,7 @@ mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, \
int new_row_siz mdb_find_row(mdb, i, &row_start, &row_size);
pos -= row_size;
memcpy((char*)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);
}
}
@@ -614,14 +636,14 @@ mdb_add_row_to_pg(MdbTableDef *table, unsigned char \
*row_buffer, int new_row_siz pos -= new_row_size;
memcpy((char*)new_pg + pos, row_buffer, new_row_size);
/* add row to the row offset table */
- _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (num_rows*2), pos);
+ mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (num_rows*2), pos);
/* update number rows on this page */
num_rows++;
- _mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
+ mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
/* update the freespace */
- _mdb_put_int16(new_pg,2,pos - fmt->row_count_offset - 2 - (num_rows*2));
+ mdb_put_int16(new_pg,2,pos - fmt->row_count_offset - 2 - (num_rows*2));
/* copy new page over old */
if (!table->is_temp_table) {
@@ -655,7 +677,7 @@ unsigned int num_fields;
mdb_debug(MDB_DEBUG_WRITE,"page %lu row %d start %d end %d", (unsigned long) \
table->cur_phys_pg, table->cur_row-1, row_start, row_end); if \
(mdb_get_option(MDB_DEBUG_LIKE))
- buffer_dump(mdb->pg_buf, row_start, old_row_size);
+ mdb_buffer_dump(mdb->pg_buf, row_start, old_row_size);
for (i=0;i<table->num_cols;i++) {
col = g_ptr_array_index(table->columns,i);
@@ -668,7 +690,7 @@ unsigned int num_fields;
if (mdb_get_option(MDB_DEBUG_WRITE)) {
for (i=0;i<num_fields;i++) {
-
+ //printf("col %d %d start %d siz %d fixed 5d\n", i, fields[i].colnum, \
fields[i].start, fields[i].siz, fields[i].is_fixed); }
}
for (i=0;i<table->num_cols;i++) {
@@ -681,15 +703,21 @@ unsigned int num_fields;
new_row_size = mdb_pack_row(table, row_buffer, num_fields, fields);
if (mdb_get_option(MDB_DEBUG_WRITE))
- buffer_dump(row_buffer, 0, new_row_size);
+ mdb_buffer_dump(row_buffer, 0, new_row_size);
if (new_row_size > (old_row_size + mdb_pg_get_freespace(mdb))) {
fprintf(stderr, "No space left on this page, update will not occur\n");
return 0;
}
/* do it! */
mdb_replace_row(table, table->cur_row-1, row_buffer, new_row_size);
- return 0;
+ return 0; /* FIXME */
}
+
+/* WARNING the return code is opposite to convention used elsewhere:
+ * returns 0 on success
+ * returns 1 on failure
+ * This might change on next ABI break.
+ */
int
mdb_replace_row(MdbTableDef *table, int row, void *new_row, int new_row_size)
{
@@ -704,14 +732,14 @@ guint16 num_rows;
int i, pos;
if (mdb_get_option(MDB_DEBUG_WRITE)) {
- buffer_dump(mdb->pg_buf, 0, 40);
- buffer_dump(mdb->pg_buf, pg_size - 160, 160);
+ mdb_buffer_dump(mdb->pg_buf, 0, 40);
+ mdb_buffer_dump(mdb->pg_buf, pg_size - 160, 160);
}
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);
num_rows = mdb_get_int16(mdb->pg_buf, rco);
- _mdb_put_int16(new_pg, rco, num_rows);
+ mdb_put_int16(new_pg, rco, num_rows);
pos = pg_size;
@@ -720,20 +748,20 @@ int i, pos;
mdb_find_row(mdb, i, &row_start, &row_size);
pos -= row_size;
memcpy((char*)new_pg + pos, mdb->pg_buf + row_start, row_size);
- _mdb_put_int16(new_pg, rco + 2 + i*2, pos);
+ mdb_put_int16(new_pg, rco + 2 + i*2, pos);
}
/* our row */
pos -= new_row_size;
memcpy((char*)new_pg + pos, new_row, new_row_size);
- _mdb_put_int16(new_pg, rco + 2 + row*2, pos);
+ mdb_put_int16(new_pg, rco + 2 + row*2, pos);
/* rows after */
for (i=row+1;i<num_rows;i++) {
mdb_find_row(mdb, i, &row_start, &row_size);
pos -= row_size;
memcpy((char*)new_pg + pos, mdb->pg_buf + row_start, row_size);
- _mdb_put_int16(new_pg, rco + 2 + i*2, pos);
+ mdb_put_int16(new_pg, rco + 2 + i*2, pos);
}
/* almost done, copy page over current */
@@ -741,15 +769,15 @@ int i, pos;
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)) {
- buffer_dump(mdb->pg_buf, 0, 40);
- buffer_dump(mdb->pg_buf, pg_size - 160, 160);
+ mdb_buffer_dump(mdb->pg_buf, 0, 40);
+ mdb_buffer_dump(mdb->pg_buf, pg_size - 160, 160);
}
/* drum roll, please */
if (!mdb_write_pg(mdb, table->cur_phys_pg)) {
- fprintf(stderr, "write failed! exiting...\n");
- exit(1);
+ fprintf(stderr, "write failed!\n");
+ return 1;
}
return 0;
}
@@ -796,16 +824,18 @@ mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, \
MdbIndexPage *ipg) }
pg_row = mdb_get_int32_msb(mdb->pg_buf, ipg->offset + ipg->len - 4);
+ /* guint32 pg = pg_row >> 8; */
row = pg_row & 0xff;
+ /* unsigned char iflag = mdb->pg_buf[ipg->offset]; */
/* turn the key hash back into a value */
mdb_index_swap_n(&mdb->pg_buf[ipg->offset + 1], col->col_size, key_hash);
key_hash[col->col_size - 1] &= 0x7f;
if (mdb_get_option(MDB_DEBUG_WRITE)) {
- buffer_dump(mdb->pg_buf, ipg->offset, ipg->len);
- buffer_dump(mdb->pg_buf, ipg->offset + 1, col->col_size);
- buffer_dump(key_hash, 0, col->col_size);
+ mdb_buffer_dump(mdb->pg_buf, ipg->offset, ipg->len);
+ mdb_buffer_dump(mdb->pg_buf, ipg->offset + 1, col->col_size);
+ mdb_buffer_dump(key_hash, 0, col->col_size);
}
memcpy((char*)new_pg + ipg->offset, mdb->pg_buf + ipg->offset, ipg->len);
@@ -815,31 +845,36 @@ mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, \
MdbIndexPage *ipg) row++;
}
+ if (!row) {
+ fprintf(stderr,"missing indexes not yet supported, aborting\n");
+ return 0;
+ }
+ //mdb_put_int16(new_pg, mdb->fmt->row_count_offset, row);
/* free space left */
- _mdb_put_int16(new_pg, 2, mdb->fmt->pg_size - ipg->offset);
-
+ mdb_put_int16(new_pg, 2, mdb->fmt->pg_size - ipg->offset);
+ //printf("offset = %d\n", ipg->offset);
mdb_index_swap_n(idx_fields[0].value, col->col_size, key_hash);
key_hash[0] |= 0x080;
if (mdb_get_option(MDB_DEBUG_WRITE)) {
printf("key_hash\n");
- buffer_dump(idx_fields[0].value, 0, col->col_size);
- buffer_dump(key_hash, 0, col->col_size);
+ mdb_buffer_dump(idx_fields[0].value, 0, col->col_size);
+ mdb_buffer_dump(key_hash, 0, col->col_size);
printf("--------\n");
}
((char *)new_pg)[ipg->offset] = 0x7f;
memcpy((char*)new_pg + ipg->offset + 1, key_hash, col->col_size);
pg_row = (pgnum << 8) | ((rownum-1) & 0xff);
- _mdb_put_int32_msb(new_pg, ipg->offset + 5, pg_row);
+ mdb_put_int32_msb(new_pg, ipg->offset + 5, pg_row);
ipg->idx_starts[row++] = ipg->offset + ipg->len;
-
+ //ipg->idx_starts[row] = ipg->offset + ipg->len;
if (mdb_get_option(MDB_DEBUG_WRITE)) {
- buffer_dump(mdb->pg_buf, 0, mdb->fmt->pg_size);
+ mdb_buffer_dump(mdb->pg_buf, 0, mdb->fmt->pg_size);
}
memcpy(mdb->pg_buf, new_pg, mdb->fmt->pg_size);
mdb_index_pack_bitmap(mdb, ipg);
if (mdb_get_option(MDB_DEBUG_WRITE)) {
- buffer_dump(mdb->pg_buf, 0, mdb->fmt->pg_size);
+ mdb_buffer_dump(mdb->pg_buf, 0, mdb->fmt->pg_size);
}
g_free(new_pg);
diff --git a/src/migration/mdb/3rdparty/mdbtools/update_diffs.sh \
b/src/migration/mdb/3rdparty/mdbtools/update_diffs.sh deleted file mode 100755
index fae35dc..0000000
--- a/src/migration/mdb/3rdparty/mdbtools/update_diffs.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-cd libmdb
-for i in `ls -1 *.c` ; do cd ..; diff -u ./libmdb.cvs/$i ./libmdb/$i > \
../diffs/`echo $i | sed -e 's/\.c/\.diff/g'` ; cd libmdb; done
-
-cd ..
-diff -u ./include.cvs/mdbtools.h ./include/mdbtools.h > ../diffs/mdbtools.diff
diff --git a/src/migration/mdb/ChangeLog b/src/migration/mdb/ChangeLog
index e7bf6b9..2db9229 100644
--- a/src/migration/mdb/ChangeLog
+++ b/src/migration/mdb/ChangeLog
@@ -1,3 +1,7 @@
+Mon Jun 24 21:04:51 CEST 2014
+ Update to mdbtools from June. This also fixes primary keys import.
+-- Jarosław Staniek <staniek@kde.org>
+
Mon Jun 4 14:49:44 CEST 2007
Ported to Qt4, imported into calligra/kexi/migration/ for Kexi 2.0.
-- Jarosław Staniek <staniek@kde.org>
diff --git a/src/migration/mdb/src/CMakeLists.txt \
b/src/migration/mdb/src/CMakeLists.txt index 34e0a52..bbd90ad 100644
--- a/src/migration/mdb/src/CMakeLists.txt
+++ b/src/migration/mdb/src/CMakeLists.txt
@@ -3,7 +3,10 @@ if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
add_definitions(-Wno-missing-format-attribute)
add_definitions(-Wno-sign-compare)
add_definitions(-Wno-unused-parameter)
-endif ()
+ add_definitions(-Wno-pointer-arith)
+ add_definitions(-std=c99)
+ add_definitions(-Wno-cast-qual)
+endif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
set(MDBTOOLS_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src/migration/mdb/3rdparty/mdbtools")
@@ -31,7 +34,9 @@ ${MDBTOOLS_SOURCE_DIR}/libmdb/map.c
${MDBTOOLS_SOURCE_DIR}/libmdb/mem.c
${MDBTOOLS_SOURCE_DIR}/libmdb/money.c
${MDBTOOLS_SOURCE_DIR}/libmdb/options.c
+${MDBTOOLS_SOURCE_DIR}/libmdb/props.c
${MDBTOOLS_SOURCE_DIR}/libmdb/sargs.c
+${MDBTOOLS_SOURCE_DIR}/libmdb/stats.c
${MDBTOOLS_SOURCE_DIR}/libmdb/table.c
${MDBTOOLS_SOURCE_DIR}/libmdb/worktable.c
${MDBTOOLS_SOURCE_DIR}/libmdb/write.c
diff --git a/src/migration/mdb/src/keximdb/mdbmigrate.cpp \
b/src/migration/mdb/src/keximdb/mdbmigrate.cpp index e0c45ba..21f7b29 100644
--- a/src/migration/mdb/src/keximdb/mdbmigrate.cpp
+++ b/src/migration/mdb/src/keximdb/mdbmigrate.cpp
@@ -1,6 +1,6 @@
/* This file is part of the KDE project
Copyright (C) 2005,2006 Martin Ellis <martin.ellis@kdemail.net>
- Copyright (C) 2005 Jarosław Staniek <staniek@kde.org>
+ Copyright (C) 2005-2014 Jarosław Staniek <staniek@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -50,18 +50,6 @@ MDBMigrate::MDBMigrate(QObject *parent, const QVariantList &args)
setPropertyValue(nonUnicodePropId, QString());
setPropertyCaption(nonUnicodePropId, xi18n("Source Database Non-Unicode \
Character Encoding"));
- initBackend();
-}
-
-MDBMigrate::~MDBMigrate()
-{
- releaseBackend();
-}
-
-void MDBMigrate::initBackend()
-{
- mdb_init();
-
// Date format associated with Qt::ISODate: YYYY-MM-DDTHH:MM:SS
// (where T is a literal). The following is equivalent to %FT%T, but
// backards compatible with old/Windows C libraries.
@@ -69,9 +57,8 @@ void MDBMigrate::initBackend()
mdb_set_date_fmt("%Y-%m-%dT%H:%M:%S");
}
-void MDBMigrate::releaseBackend()
+MDBMigrate::~MDBMigrate()
{
- mdb_exit();
}
QVariant MDBMigrate::propertyValue(const QByteArray& propName)
@@ -227,7 +214,7 @@ QVariant MDBMigrate::toQVariant(const char* data, unsigned int \
len, int type) case MDB_BOOL: //! @todo use &bool!
case MDB_BYTE:
return QString::fromUtf8(data, len).toShort();
- case MDB_SDATETIME:
+ case MDB_DATETIME:
return QDateTime::fromString(data, Qt::ISODate);
case MDB_INT:
case MDB_LONGINT:
@@ -350,7 +337,7 @@ KDbField::Type MDBMigrate::type(int type)
case MDB_DOUBLE:
kexiType = KDbField::Double;
break;
- case MDB_SDATETIME:
+ case MDB_DATETIME:
kexiType = KDbField::DateTime;
break;
case MDB_TEXT:
@@ -428,10 +415,10 @@ bool MDBMigrate::getPrimaryKey(KDbTableSchema* table, \
MdbTableDef* tableDef)
if (ok) {
//qDebug() << *p_idx;
-
+
// ... and add it to the table definition
// but only if the PK has only one field, so far :o(
-
+
KDbField *f;
if (idx->num_keys == 1 && (f = table->field(idx->key_col_num[0] - 1))) {
f->setPrimaryKey(true);
@@ -455,5 +442,3 @@ bool MDBMigrate::drv_getTableSize(const QString& table, quint64& \
size) mdb_free_tabledef(tableDef);
return true;
}
-
-
diff --git a/src/migration/mdb/src/keximdb/mdbmigrate.h \
b/src/migration/mdb/src/keximdb/mdbmigrate.h index c27b90e..d9669f9 100644
--- a/src/migration/mdb/src/keximdb/mdbmigrate.h
+++ b/src/migration/mdb/src/keximdb/mdbmigrate.h
@@ -1,6 +1,6 @@
/* This file is part of the KDE project
Copyright (C) 2005,2006 Martin Ellis <martin.ellis@kdemail.net>
- Copyright (C) 2005 Jarosław Staniek <staniek@kde.org>
+ Copyright (C) 2005-2014 Jarosław Staniek <staniek@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -35,7 +35,6 @@ namespace KexiMigration
class MDBMigrate : public KexiMigrate
{
- Q_OBJECT
KEXIMIGRATION_DRIVER
public:
@@ -86,8 +85,6 @@ protected:
virtual bool drv_getTableSize(const QString& table, quint64 *size);
private:
- void initBackend();
- void releaseBackend();
MdbHandle *m_mdb;
};
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic