Compare commits

..

No commits in common. "dev" and "v1.0.0-beta6" have entirely different histories.

29 changed files with 233 additions and 477 deletions

View File

@ -1,25 +1,20 @@
name: build
on: [ push, pull_request ]
env:
TEST_DATA_URL: https://github.com/mdbtools/mdbtestdata/archive/refs/heads/master.tar.gz
jobs:
linux:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
compiler: [ clang, gcc, gcc-11, gcc-12 ]
compiler: [ clang, gcc, gcc-9, gcc-10 ]
iconv: [ enable-iconv, disable-iconv]
glib: [ enable-glib, disable-glib ]
steps:
- name: Install packages
run: sudo apt install gettext unixodbc gcc-11 gcc-12
run: sudo apt install gettext
- uses: actions/checkout@v2
- name: Fetch test data
run: |
rm -rf test
mkdir test
curl -sSLf "$TEST_DATA_URL" | tar xz --strip-components=1 -C test
run: git clone https://github.com/mdbtools/mdbtestdata.git test
- name: Autoconf
run: autoreconf -i -f
- name: Configure
@ -29,7 +24,7 @@ jobs:
- name: Make
run: make
- name: CLI tests
run: ./test_script.sh --github
run: bash -e -x ./test_script.sh
- name: SQL tests
run: bash -e -x ./test_sql.sh
- name: ODBC tests
@ -54,24 +49,21 @@ jobs:
glib: [ enable-glib, disable-glib ]
steps:
- name: Install packages
run: brew install bison gawk automake libtool unixodbc
run: brew install bison gawk automake
- uses: actions/checkout@v2
- name: Fetch test data
run: |
rm -rf test
mkdir test
curl -sSLf "$TEST_DATA_URL" | tar xz --strip-components=1 -C test
run: git clone https://github.com/mdbtools/mdbtestdata.git test
- name: Autoconf
run: autoreconf -i -f -I $(brew --prefix)/share/gettext/m4
run: autoreconf -i -f
- name: Configure
run: ./configure --disable-silent-rules --${{ matrix.glib }} --${{ matrix.iconv }} --with-unixodbc=/opt/homebrew/opt/unixodbc
run: ./configure --disable-silent-rules --${{ matrix.glib }} --${{ matrix.iconv }} --with-unixodbc=/usr/local/opt
env:
CC: ${{ matrix.compiler }}
YACC: /opt/homebrew/opt/bison/bin/bison
YACC: /usr/local/opt/bison/bin/bison
- name: Make
run: make
- name: CLI tests
run: ./test_script.sh --github
run: bash -e -x ./test_script.sh
- name: SQL tests
run: bash -e -x ./test_sql.sh
- name: ODBC tests
@ -94,23 +86,20 @@ jobs:
compiler: [ clang, gcc ]
glib: [ enable-glib, disable-glib ]
steps:
- name: Remove packages
run: brew unlink unixodbc
- name: Install packages
run: brew install bison gawk automake libtool libiodbc
- name: Add path
run: echo /opt/homebrew/opt/libiodbc/bin >> $GITHUB_PATH
run: brew install libiodbc bison gawk automake
- uses: actions/checkout@v2
- name: Fetch test data
run: |
rm -rf test
mkdir test
curl -sSLf "$TEST_DATA_URL" | tar xz --strip-components=1 -C test
run: git clone https://github.com/mdbtools/mdbtestdata.git test
- name: Autoconf
run: autoreconf -i -f -I $(brew --prefix)/share/gettext/m4
run: autoreconf -i -f
- name: Configure
run: ./configure --disable-silent-rules --${{ matrix.glib }} --with-iodbc=/opt/homebrew/opt/libiodbc
run: ./configure --disable-silent-rules --${{ matrix.glib }} --with-iodbc=/usr/local/opt
env:
CC: ${{ matrix.compiler }}
YACC: /opt/homebrew/opt/bison/bin/bison
YACC: /usr/local/opt/bison/bin/bison
- name: Make
run: make
- name: ODBC tests
@ -119,37 +108,19 @@ jobs:
MDBPATH: test/data
windows:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
iconv: [ enable-iconv, disable-iconv]
glib: [ enable-glib, disable-glib ]
defaults:
run:
shell: msys2 {0}
env:
MSYSTEM: MINGW64
steps:
- uses: msys2/setup-msys2@v2
with:
update: true
install: >-
autotools
base-devel
gcc
git
glib2-devel
- uses: actions/checkout@v2
- name: Fetch test data
run: |
rm -rf test
mkdir test
curl -sSLf "$TEST_DATA_URL" | tar xz --strip-components=1 -C test
- name: Check out test data
run: git clone https://github.com/mdbtools/mdbtestdata.git test
- name: Autoconf
run: autoreconf -i -f
run: C:\msys64\usr\bin\bash -c -l 'cd "$GITHUB_WORKSPACE" && autoreconf -i -f'
- name: Configure
run: ./configure --${{ matrix.glib }} --${{ matrix.iconv }}
run: C:\msys64\usr\bin\bash -c -l 'cd "$GITHUB_WORKSPACE" && ./configure'
- name: Make
run: make
run: C:\msys64\usr\bin\bash -c -l 'cd "$GITHUB_WORKSPACE" && make'
- name: Test
run: ./test_script.sh --github
run: C:\msys64\usr\bin\bash -c -l 'cd "$GITHUB_WORKSPACE" && bash -e -x ./test_script.sh'
- name: SQL Test
run: bash -e -x ./test_sql.sh
run: C:\msys64\usr\bin\bash -c -l 'cd "$GITHUB_WORKSPACE" && bash -e -x ./test_sql.sh'

8
.gitignore vendored
View File

@ -17,7 +17,6 @@ m4/
config.log
config.status
configure
/configure~
Makefile.in
Makefile
doc/*.1
@ -27,8 +26,6 @@ include/mdbtools.h
libmdb.pc
libmdbsql.pc
libtool
mdbtools-*.tar.gz
mdbtools-*.zip
src/extras/mdb-hexdump
src/odbc/unittest
src/sql/lexer.c
@ -55,10 +52,9 @@ src/util/prkkd
src/util/prole
src/util/prtable
src/util/updrow
/test/
/.vscode/
## apidocs docs related
public/
.sass-cache/
*.css.map
temp-man-pages/

View File

@ -259,7 +259,7 @@ offset_start of memo = (int16*) LVAL_page[offset_num_rows + (row_id * 2) + 2]
if (row_id = 0)
offset_stop of memo = 2048(jet3) or 4096(jet4)
else
offset_stop of memo = (int16*) LVAL_page[offset_num_row + (row_id * 2)] & offset_mask // offset_mask = 0x1fff
offset_stop of memo = (int16*) LVAL_page[offset_num_row + (row_id * 2)]
```
The length (partial if type 2) for the memo is:

113
NEWS
View File

@ -1,62 +1,101 @@
Version 1.0.0
Version 1.0.0 (Beta 6)
=============
MDB Tools 1.0 includes a number of new features compared to the 0.9 series. The
most significant change is that mdbtools.h is now generated at build time, and
its internal HAVE_ macros have been removed. This means that it is now safe for
clients to compile against mdbtools.h without needing to provide the same
HAVE_ICONV and HAVE_GLIB flags that were present when the library was first
compiled. For most users, MDB Tools 1.0 will be ABI and API compatible with the
0.9 series but see the notes in the "Install" section below.
libmdb:
The SQL engine has two new operators: ILIKE (case-insensitive pattern matching)
and <> (not equals).
* Improved support for pre-C11 compilers
Changes since 0.9.4:
ODBC:
Build:
* Generate platform-specific `mdbtools.h` at configure-time #316
* Ensure compiler supports thread-local storage
* Fix `AC_PROG_LEX` warning with autoconf 2.70
* Rely on autoconf to define appropriate values of `_XOPEN_SOURCE` and friends
* New `--disable-iconv` configure option (falls back to `wcstombs` where possible)
* Fix a build error when `./configure` detected iconv, but thought it was not working
* Generating the configure script now requires autoconf 2.64 or later
* Remove `SQLFetchW` (introduced in Beta 5) in favor of the `SQL_C_WCHAR` return type
* Fix an issue where Chinese characters were returned instead of ASCII using the Unicode driver on some platforms
* Add support for older iODBC installations lacking odbcinst.h
* Improved bounds checking
Install:
* Install `libmdbodbc.so` and `libmdbodbcW.so` into ${libdir}/odbc #315
* Do not install `mdb-sql` if SQL support was not built #276
* Do not install `libmdbsql.pc` if SQL support was not built
`pkg-config`:
* Simplify `--cflags` for libmdb
* Provide correct `--cflags` for libmdbsql
Version 1.0.0 (Beta 5)
=============
libmdb:
* Copy date formats when cloning handles #326
* Fix incorrect reading of double values #339 #342
* Fix accidental reads of non-index data #335 #343
* New `mdb_set_repid_fmt()` for setting the format of Rep IDs (UUIDs) #344
SQL:
* New case-insensitive, Unicode-aware `ILIKE` operator #244
* New `<>` (not equal) operator #329
* Improved support for comparing floating-point values to integers
* Improved support for floating point literals with no fractional digits (e.g. "3.")
* Add support for querying Rep IDs
ODBC:
* Format boolean values correctly as `SQL_C_CHAR` #327
* Add support for the `SQL_C_WCHAR` (UTF-16) return type #347 #348
* The Unicode driver (`libmdbodbcW.so`) no longer uses iconv #332 #333
* Add support for older iODBC installations lacking `odbcinst.h`
`mdb-export`:
* Implement `SQLFetchW` in the Unicode driver #347 #348
Version 1.0.0 (Beta 4)
=============
Build:
* New `--disable-iconv` configure option (falls back to `wcstombs` where possible)
* Fix a build error when `./configure` detected iconv, but thought it was not working
* Generating the configure script now requires autoconf 2.64 or later
ODBC:
* The Unicode driver (`libmdbodbcW.so`) no longer uses iconv #332 #333
SQL:
* New `<>` (not equal) operator #329
Version 1.0.0 (Beta 3)
=============
Build:
* Fix warning with autoconf 2.70
* Rely on autoconf to define appropriate values of `_XOPEN_SOURCE` and friends
* Simplify configure script
libmdb:
* Restore previous `MdbHandle` struct layout
* Simplify `pkg-config --cflags`
libmdbsql:
* Provide correct `pkg-config --cflags`
ODBC:
* Format boolean values correctly as SQL_C_CHAR #327
mdb-schema:
* Fix incorrect treatment of CREATE TABLE and DROP TABLE #328 (Bug introduced in Beta 2)
Version 1.0.0 (Beta 2)
=============
Build:
* Ensure compiler supports thread-local storage
libmdb:
* Copy date formats when cloning handles #326
* Restore previous `mdb_register_backend` API
* Restore previous `MdbBackend` struct layout
Version 1.0.0 (Beta 1)
=============
libmdb:
* Generate platform-specific `mdbtools.h` at configure-time #316
SQL:
* New case-insensitive, Unicode-aware `ILIKE` operator #244
* Do not install `mdb-sql` if SQL support was not built #276
* Do not install `libmdbsql.pc` if SQL support was not built
ODBC:
* Install libmdbodbc.so and libmdbodbcW.so into ${libdir}/odbc #315
mdb-export:
* Convert table names to lower case when exporting to PostgreSQL #322
* Use `CREATE IF NOT EXISTS` when exporting to PostgreSQL #321
* Fix issue where byte columns with values > 127 were exported as negative numbers (regression introduced in v0.9.3-beta1) #350
`mdb-hexdump`:
mdb-hexdump:
* Deprecate tool
Version 0.9.4

View File

@ -116,26 +116,19 @@ If you have cloned the Git repository, you will first need to generate the
`configure` file (skip this step if you have downloaded a formal release):
```bash
autoreconf -i -f
$ autoreconf -i -f
```
Then:
```bash
./configure
$ ./configure
```
OR with mingw32 (--disable-shared --enable-static are optional as you knew):
```bash
./configure --host=x86_64-w64-mingw32 --disable-shared --enable-static
```
OR for a complete install (requires bison, flex, and unixODBC):
```bash
./configure --with-unixodbc=/usr/local
$ ./configure --with-unixodbc=/usr/local
```
By default, MDB Tools is linked against the copy of
@ -159,10 +152,11 @@ mutually exclusive.
By default, the ODBC driver will be installed as /usr/local/lib/odbc/libmdbodbc.so,
with a Unicode-capable driver at /usr/local/lib/odbc/libmdbodbcW.so.
The command `configure --help` will give you the list of mdbtools specific options.
A list of general options is available in the [INSTALL](./INSTALL) file, and
`configure --help` will give you the list of mdbtools specific options.
```bash
make
$ make
```
Once MDB Tools has been compiled, libmdb.[so|a] will be in the src/libmdb
@ -171,14 +165,14 @@ directory and the utility programs will be in the src/util directory.
You can then install (to /usr/local by default) by running the following as root:
```bash
make install
$ make install
```
Some systems will also need the ld cache to be updated after installation;
You can do that running:
```bash
ldconfig
$ ldconfig
```
## Hacking

32
TODO.md
View File

@ -1,4 +1,34 @@
TODO
----
See the list of [open issues tagged "enhancement"](https://github.com/mdbtools/mdbtools/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement).
### file format:
- export VBA script
- re-examine KKD records for form design (OLE streams?)
- write support (understood, not coded)
### libmdb:
- Complete the list of datatypes
- Straighten out which functions in libmdb are meant to be used and which
ones should be static.
- Create an API reference for libmdb (maybe some man pages).
- Sargs need to support all datatypes
- Add support for index scanning when using sargs (partial)
- write support
### utils:
- need program to unpack VBA script to file (see prole)
- Access forms to glade converter ?
- need --version flag (done using -M flag on mdb-ver)
### SQL Engine:
- Joins
- insert/updates
- bogus column name in where clause not caught
### ODBC:
- many unimplemented funtions

7
api_docx/custom.css.map Normal file

File diff suppressed because one or more lines are too long

View File

@ -17,10 +17,8 @@ clone_folder: c:\projects\mdbtools
skip_tags: true
# Installing packages leads to the error:
# Can't locate threads.pm in @INC (you may need to install the threads module)
# So disable the SQL tests on this platform for now
build_script:
- C:\cygwin64\setup-x86_64.exe -q -P bison -P flex -P libiconv-devel
- C:\cygwin64\bin\sh -lc "cd /cygdrive/c/projects/mdbtools && git clone https://github.com/mdbtools/mdbtestdata.git test"
- C:\cygwin64\bin\sh -lc "cd /cygdrive/c/projects/mdbtools && autoreconf -i -f"
- C:\cygwin64\bin\sh -lc "cd /cygdrive/c/projects/mdbtools && ./configure --disable-man --disable-silent-rules"
@ -28,3 +26,4 @@ build_script:
test_script:
- C:\cygwin64\bin\sh -lc "cd /cygdrive/c/projects/mdbtools && ./test_script.sh"
- C:\cygwin64\bin\sh -lc "cd /cygdrive/c/projects/mdbtools && ./test_sql.sh"

View File

@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT([mdbtools],[1.0.1],[https://github.com/mdbtools/mdbtools/issues],[],[https://github.com/mdbtools/mdbtools])
AC_INIT([mdbtools],[1.0.0-beta6],[https://github.com/mdbtools/mdbtools/issues],[],[https://github.com/mdbtools/mdbtools])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_SRCDIR(src/extras/mdb-dump.c)
@ -7,11 +7,11 @@ AM_INIT_AUTOMAKE([foreign dist-zip])
MDBTOOLS_VERSION_MAJOR=1
MDBTOOLS_VERSION_MINOR=0
MDBTOOLS_VERSION_MICRO=1
MDBTOOLS_VERSION_MICRO=0
# Update these numbers with every release
# See https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
VERSION_INFO=4:1:1
VERSION_INFO=4:0:1
AC_SUBST(VERSION_INFO)
AM_MAINTAINER_MODE([enable])
@ -83,10 +83,10 @@ AM_CONDITIONAL(SQL, test x$sql = xtrue)
AC_SUBST(SQL)
AC_SUBST(LFLAGS)
CFLAGS="$CFLAGS -Wall"
CFLAGS="$CFLAGS -Wall -Werror"
LOCALE_T=locale_t
AS_CASE([$host],
[*mingw*], [LDFLAGS="$LDFLAGS -no-undefined" CFLAGS="$CFLAGS -D_spawnv=_spawnv"], [])
[*mingw*|*cygwin*], [LDFLAGS="$LDFLAGS -no-undefined" LOCALE_T=_locale_t], [])
AC_SUBST(LOCALE_T)
dnl See if iconv is present and wanted
@ -167,7 +167,7 @@ AC_ARG_WITH(unixodbc,
if test "$with_unixodbc"; then
HAVE_ODBC=true
ODBC_CFLAGS="-I$with_unixodbc/include"
ODBC_LIBS="-L$with_unixodbc/lib"
ODBC_LIBS="-L$with_unixodbc/$libdir"
dnl SIZEOF_LONG_INT and HAVE_LONG_LONG are required by some versions of unixODBC
dnl https://github.com/lurcher/unixODBC/issues/40
@ -226,9 +226,10 @@ AC_ARG_ENABLE(glib,
if test "$enable_glib" = "yes"; then
GLIB_PACKAGE=glib-2.0
PKG_CHECK_MODULES([GLIB], [$GLIB_PACKAGE >= 2.68], HAVE_GLIB=true, HAVE_GLIB=false)
PKG_CHECK_MODULES([GLIB], [$GLIB_PACKAGE], HAVE_GLIB=true, HAVE_GLIB=false)
if test "x$HAVE_GLIB" = "xtrue"; then
GLIB_CFLAGS="$GLIB_CFLAGS -DHAVE_GLIB=1"
AC_CHECK_LIB($GLIB_PACKAGE, g_memdup2, [GLIB_CFLAGS="$GLIB_CFLAGS -DHAVE_G_MEMDUP2=1"])
AC_SUBST(GLIB_PACKAGE)
else
enable_glib=no

View File

@ -1,5 +1,5 @@
SHELL = /bin/sh
TXT2MAN = $(srcdir)/txt2man
TXT2MAN = ./txt2man
PRODUCT = MDBTools
dist_man_MANS =

View File

@ -9,7 +9,7 @@ SYNOPSIS
DESCRIPTION
mdb-json is a utility program distributed with MDB Tools.
It produces JSON output for the given table. Such output is suitable for parsing in a variety of languages.
It produces a CSV (comma separated value) output for the given table. Such output is suitable for importation into databases or spreadsheets.
OPTIONS
-D, --date-format fmt Set the date format (see strftime(3) for details).

View File

@ -117,7 +117,6 @@ typedef struct GOptionContext {
#define g_malloc malloc
#define g_free free
#define g_realloc realloc
#define g_memdup2 g_memdup
#define G_STR_DELIMITERS "_-|> <."

View File

@ -26,6 +26,10 @@
* used within mdbtools so they won't be exported to calling programs.
*/
#ifndef HAVE_G_MEMDUP2
#define g_memdup2 g_memdup
#endif
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -21,6 +21,9 @@
#define MDBTOOLS_H_HAVE_ICONV_H @HAVE_ICONV_H@
#define MDBTOOLS_H_HAVE_XLOCALE_H @HAVE_XLOCALE_H@
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@ -45,10 +48,6 @@
#include <io.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** \addtogroup mdbtools
* @{
*/
@ -68,13 +67,6 @@
// M$VC see http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
#define MDB_DEPRECATED(type, funcname) type __attribute__((deprecated)) funcname
#ifdef __MINGW32__
#include <stdlib.h>
#ifndef locale_t
typedef _locale_t locale_t;
#endif
#endif
typedef @LOCALE_T@ mdb_locale_t;
enum {

View File

@ -111,7 +111,7 @@ static const MdbBackendType mdb_mysql_types[] = {
[MDB_LONGINT] = { .name = "int" },
[MDB_MONEY] = { .name = "float" },
[MDB_FLOAT] = { .name = "float" },
[MDB_DOUBLE] = { .name = "double" },
[MDB_DOUBLE] = { .name = "float" },
[MDB_DATETIME] = { .name = "datetime" },
[MDB_BINARY] = { .name = "blob" },
[MDB_TEXT] = { .name = "varchar", .needs_char_length = 1 },
@ -401,7 +401,7 @@ void mdb_init_backends(MdbHandle *mdb)
"COMMENT %s",
quote_schema_name_rquotes_merge);
mdb_register_backend(mdb, "sqlite",
MDB_SHEXP_DROPTABLE|MDB_SHEXP_DEFVALUES|MDB_SHEXP_BULK_INSERT|MDB_SHEXP_INDEXES|MDB_SHEXP_CST_NOTNULL,
MDB_SHEXP_DROPTABLE|MDB_SHEXP_DEFVALUES|MDB_SHEXP_BULK_INSERT,
mdb_sqlite_types, NULL, NULL,
"date('now')", "date('now')",
"%Y-%m-%d %H:%M:%S",
@ -571,47 +571,7 @@ mdb_get_index_name(int backend, MdbTableDef *table, MdbIndex *idx)
return index_name;
}
/**
* mdb_print_pk - print primary key constraint
* @output: Where to print the sql
* @table: Table to process
*/
static void
mdb_print_pk_if_sqlite(FILE *outfile, MdbTableDef *table)
{
unsigned int i, j;
MdbHandle *mdb = table->entry->mdb;
MdbIndex *idx;
MdbColumn *col;
char *quoted_name;
// this is only necessary for sqlite
if (strcmp(mdb->backend_name, "sqlite") != 0)
return;
if (table->indices==NULL)
mdb_read_indices(table);
for (i = 0; i < table->num_idxs; i++) {
idx = g_ptr_array_index(table->indices, i);
if (idx->index_type == 1) {
fprintf(outfile, "\t, PRIMARY KEY (");
for (j = 0; j < idx->num_keys; j++) {
if (j)
fprintf(outfile, ", ");
col = g_ptr_array_index(table->columns, idx->key_col_num[j] - 1);
quoted_name = mdb->default_backend->quote_schema_name(NULL, col->name);
quoted_name = mdb_normalise_and_replace(mdb, &quoted_name);
fprintf(outfile, "%s", quoted_name);
if (idx->index_type != 1 && idx->key_col_order[j])
/* no DESC for primary keys */
fprintf(outfile, " DESC");
g_free(quoted_name);
}
fprintf(outfile, ")\n");
}
}
}
/**
* mdb_print_indexes
* @output: Where to print the sql
@ -636,15 +596,12 @@ mdb_print_indexes(FILE* outfile, MdbTableDef *table, char *dbnamespace)
backend = MDB_BACKEND_MYSQL;
} else if (!strcmp(mdb->backend_name, "oracle")) {
backend = MDB_BACKEND_ORACLE;
} else if (!strcmp(mdb->backend_name, "sqlite")) {
backend = MDB_BACKEND_SQLITE;
} else {
fprintf(outfile, "-- Indexes are not implemented for %s\n\n", mdb->backend_name);
return;
}
/* read indexes */
if (table->indices==NULL)
mdb_read_indices(table);
fprintf (outfile, "-- CREATE INDEXES ...\n");
@ -656,9 +613,6 @@ mdb_print_indexes(FILE* outfile, MdbTableDef *table, char *dbnamespace)
idx = g_ptr_array_index (table->indices, i);
if (idx->index_type==2)
continue;
/* Sqlite3 primary keys have to be issued as a table constraint */
if (idx->index_type == 1 && backend == MDB_BACKEND_SQLITE)
continue;
index_name = mdb_get_index_name(backend, table, idx);
switch (backend) {
@ -676,10 +630,7 @@ mdb_print_indexes(FILE* outfile, MdbTableDef *table, char *dbnamespace)
}
quoted_name = mdb_normalise_and_replace(mdb, &quoted_name);
if (idx->num_keys == 0) {
fprintf(outfile, "-- WARNING: found no keys for index %s - ignored\n", quoted_name);
continue;
}
if (idx->index_type==1) {
switch (backend) {
case MDB_BACKEND_ORACLE:
@ -694,7 +645,6 @@ mdb_print_indexes(FILE* outfile, MdbTableDef *table, char *dbnamespace)
switch (backend) {
case MDB_BACKEND_ORACLE:
case MDB_BACKEND_POSTGRES:
case MDB_BACKEND_SQLITE:
fprintf(outfile, "CREATE");
if (idx->flags & MDB_IDX_UNIQUE)
fprintf (outfile, " UNIQUE");
@ -922,10 +872,6 @@ generate_table_schema(FILE *outfile, MdbCatalogEntry *entry, char *dbnamespace,
fprintf (outfile, " (\n");
table = mdb_read_table (entry);
if (!table) {
fprintf(stderr, "Error: Table %s does not exist\n", entry->object_name);
return;
}
/* get the columns */
mdb_read_columns(table);
@ -1018,11 +964,6 @@ generate_table_schema(FILE *outfile, MdbCatalogEntry *entry, char *dbnamespace,
fputs("\n", outfile);
} /* for */
if (export_options & MDB_SHEXP_INDEXES) {
// sqlite does not support ALTER TABLE PRIMARY KEY, so we need to place it directly into CREATE TABLE
mdb_print_pk_if_sqlite(outfile, table);
}
fputs(")", outfile);
if (mdb->default_backend->per_table_comment_statement && export_options & MDB_SHEXP_COMMENTS) {
prop_value = mdb_table_get_prop(table, "Description");

View File

@ -193,7 +193,7 @@ mdb_dump_catalog(MdbHandle *mdb, int obj_type)
entry = g_ptr_array_index(mdb->catalog,i);
if (obj_type==MDB_ANY || entry->object_type==obj_type) {
printf("Type: %-12s Name: %-48s Page: %06lx\n",
mdb_get_objtype_string(entry->object_type) ?: "Unknown",
mdb_get_objtype_string(entry->object_type),
entry->object_name,
entry->table_pg);
}

View File

@ -1009,7 +1009,7 @@ char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int datatype, int
switch (datatype) {
case MDB_BYTE:
text = g_strdup_printf("%hhu", mdb_get_byte(buf, start));
text = g_strdup_printf("%hhd", mdb_get_byte(buf, start));
break;
case MDB_INT:
text = g_strdup_printf("%hd",

View File

@ -255,8 +255,7 @@ gchar *g_locale_to_utf8(const gchar *opsysstring, size_t len,
mbstowcs(utf16, opsysstring, wlen+1);
gchar *utf8 = malloc(3*len+1);
gchar *dst = utf8;
size_t i;
for (i=0; i<len; i++) {
for (size_t i=0; i<len; i++) {
// u >= 0x10000 requires surrogate pairs, ignore
dst += g_unichar_to_utf8(utf16[i], dst);
}
@ -333,8 +332,7 @@ void g_hash_table_insert(GHashTable *table, void *key, void *value) {
gboolean g_hash_table_remove(GHashTable *table, gconstpointer key) {
int found = 0;
guint i;
for (i=0; i<table->array->len; i++) {
for (guint i=0; i<table->array->len; i++) {
MyNode *node = g_ptr_array_index(table->array, i);
if (found) {
table->array->pdata[i-1] = table->array->pdata[i];
@ -400,8 +398,7 @@ void g_ptr_array_add(GPtrArray *array, void *entry) {
gboolean g_ptr_array_remove(GPtrArray *array, gpointer data) {
int found = 0;
guint i;
for (i=0; i<array->len; i++) {
for (guint i=0; i<array->len; i++) {
if (found) {
array->pdata[i-1] = array->pdata[i];
} else if (!found && array->pdata[i] == data) {

View File

@ -381,7 +381,7 @@ static ssize_t _mdb_read_pg(MdbHandle *mdb, void *pg_buf, unsigned long pg)
*/
if (pg != 0 && mdb->f->db_key != 0)
{
uint32_t tmp_key_i = mdb->f->db_key ^ pg;
guint32 tmp_key_i = mdb->f->db_key ^ pg;
unsigned char tmp_key[4] = {
tmp_key_i & 0xFF, (tmp_key_i >> 8) & 0xFF,
(tmp_key_i >> 16) & 0xFF, (tmp_key_i >> 24) & 0xFF };
@ -414,7 +414,7 @@ unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset)
int mdb_get_int16(void *buf, int offset)
{
unsigned char *u8_buf = (unsigned char *)buf + offset;
return ((uint32_t)u8_buf[0] << 0) + ((uint32_t)u8_buf[1] << 8);
return u8_buf[0] + (u8_buf[1] << 8);
}
int mdb_pg_get_int16(MdbHandle *mdb, int offset)
{
@ -426,20 +426,12 @@ int mdb_pg_get_int16(MdbHandle *mdb, int offset)
long mdb_get_int32_msb(void *buf, int offset)
{
unsigned char *u8_buf = (unsigned char *)buf + offset;
return
((uint32_t)u8_buf[0] << 24) +
((uint32_t)u8_buf[1] << 16) +
((uint32_t)u8_buf[2] << 8) +
((uint32_t)u8_buf[3] << 0);
return (u8_buf[0] << 24) + (u8_buf[1] << 16) + (u8_buf[2] << 8) + u8_buf[3];
}
long mdb_get_int32(void *buf, int offset)
{
unsigned char *u8_buf = (unsigned char *)buf + offset;
return
((uint32_t)u8_buf[0] << 0) +
((uint32_t)u8_buf[1] << 8) +
((uint32_t)u8_buf[2] << 16) +
((uint32_t)u8_buf[3] << 24);
return u8_buf[0] + (u8_buf[1] << 8) + (u8_buf[2] << 16) + (u8_buf[3] << 24);
}
long mdb_pg_get_int32(MdbHandle *mdb, int offset)
{
@ -450,12 +442,9 @@ long mdb_pg_get_int32(MdbHandle *mdb, int offset)
float mdb_get_single(void *buf, int offset)
{
union {uint32_t g; float f;} f;
union {guint32 g; float f;} f;
unsigned char *u8_buf = (unsigned char *)buf + offset;
f.g = ((uint32_t)u8_buf[0] << 0) +
((uint32_t)u8_buf[1] << 8) +
((uint32_t)u8_buf[2] << 16) +
((uint32_t)u8_buf[3] << 24);
f.g = u8_buf[0] + (u8_buf[1] << 8) + (u8_buf[2] << 16) + (u8_buf[3] << 24);
return f.f;
}
float mdb_pg_get_single(MdbHandle *mdb, int offset)
@ -467,19 +456,18 @@ float mdb_pg_get_single(MdbHandle *mdb, int offset)
double mdb_get_double(void *buf, int offset)
{
union {uint64_t g; double d;} d;
union {guint64 g; double d;} d;
unsigned char *u8_buf = (unsigned char *)buf + offset;
d.g = ((uint64_t)u8_buf[0] << 0) +
((uint64_t)u8_buf[1] << 8) +
((uint64_t)u8_buf[2] << 16) +
((uint64_t)u8_buf[3] << 24) +
((uint64_t)u8_buf[4] << 32) +
((uint64_t)u8_buf[5] << 40) +
((uint64_t)u8_buf[6] << 48) +
((uint64_t)u8_buf[7] << 56);
d.g = ((guint64)u8_buf[0]) +
((guint64)u8_buf[1] << 8) +
((guint64)u8_buf[2] << 16) +
((guint64)u8_buf[3] << 24) +
((guint64)u8_buf[4] << 32) +
((guint64)u8_buf[5] << 40) +
((guint64)u8_buf[6] << 48) +
((guint64)u8_buf[7] << 56);
return d.d;
}
double mdb_pg_get_double(MdbHandle *mdb, int offset)
{
if (offset <0 || offset+8 > mdb->fmt->pg_size) return -1;
@ -487,6 +475,7 @@ double mdb_pg_get_double(MdbHandle *mdb, int offset)
return mdb_get_double(mdb->pg_buf, offset);
}
int
mdb_set_pos(MdbHandle *mdb, int pos)
{

View File

@ -275,8 +275,6 @@ static const char *mdb_iconv_name_from_code_page(int code_page) {
case 860: jet3_iconv_code="IBM860"; break;
case 861: jet3_iconv_code="IBM861"; break;
case 862: jet3_iconv_code="IBM862"; break;
case 863: jet3_iconv_code="IBM863"; break;
case 864: jet3_iconv_code="IBM864"; break;
case 865: jet3_iconv_code="IBM865"; break;
case 866: jet3_iconv_code="IBM866"; break;
case 869: jet3_iconv_code="IBM869"; break;

View File

@ -92,12 +92,6 @@ MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
mdb_free_tabledef(table);
return NULL;
}
/* First byte of usage_map is the map-type and must always be present */
if (table->map_sz < 1) {
fprintf(stderr, "mdb_read_table: invalid map-size: %zu\n", table->map_sz);
mdb_free_tabledef(table);
return NULL;
}
table->usage_map = g_memdup2((char*)buf + row_start, table->map_sz);
if (mdb_get_option(MDB_DEBUG_USAGE))
mdb_buffer_dump(buf, row_start, table->map_sz);
@ -361,9 +355,6 @@ unsigned int i, bitn;
guint32 pgnum;
table = mdb_read_table(entry);
if (!table)
return;
fprintf(stdout,"definition page = %lu\n",entry->table_pg);
fprintf(stdout,"number of datarows = %d\n",table->num_rows);
fprintf(stdout,"number of columns = %d\n",table->num_cols);

View File

@ -213,7 +213,7 @@ gchar* ExtractDSN (ConnectParams* params, const gchar* connectString)
/*
* Position ourselves to the beginning of "DSN"
*/
p = strcasestr (connectString, "DSN");
p = strstr (connectString, "DSN");
if (!p) return NULL;
/*
* Position ourselves to the "="
@ -243,9 +243,9 @@ gchar* ExtractDBQ (ConnectParams* params, const gchar* connectString)
if (!params)
return NULL;
/*
* Position ourselves to the beginning of "DBQ"
* Position ourselves to the beginning of "DSN"
*/
p = strcasestr (connectString, "DBQ");
p = strstr (connectString, "DBQ");
if (!p) return NULL;
/*
* Position ourselves to the "="

View File

@ -72,8 +72,8 @@ struct _hstmt {
struct _sql_bind_info {
int column_number;
int column_bindtype; /* type/conversion required */
SQLLEN column_bindlen; /* size of varaddr buffer */
SQLLEN *column_lenbind; /* where to store length of varaddr used */
int column_bindlen; /* size of varaddr buffer */
int *column_lenbind; /* where to store length of varaddr used */
char *varaddr;
struct _sql_bind_info *next;
};

View File

@ -513,7 +513,7 @@ SQLRETURN SQL_API SQLBindCol(
/* if this is a repeat */
if (cur) {
cur->column_bindtype = fCType;
cur->column_lenbind = pcbValue;
cur->column_lenbind = (int *)pcbValue;
cur->column_bindlen = cbValueMax;
cur->varaddr = (char *) rgbValue;
} else {
@ -522,7 +522,7 @@ SQLRETURN SQL_API SQLBindCol(
newitem->column_number = icol;
newitem->column_bindtype = fCType;
newitem->column_bindlen = cbValueMax;
newitem->column_lenbind = pcbValue;
newitem->column_lenbind = (int *)pcbValue;
newitem->varaddr = (char *) rgbValue;
/* if there's no head yet */
if (! stmt->bind_head) {
@ -1360,86 +1360,15 @@ SQLRETURN SQL_API SQLGetData(
break;
// case MDB_MONEY: TODO
case MDB_FLOAT:
switch (fCType) {
case SQL_C_FLOAT:
*(float*)rgbValue = mdb_get_single(mdb->pg_buf, col->cur_value_start);
if (pcbValue)
*pcbValue = sizeof(float);
break;
case SQL_C_DOUBLE:
*(double*)rgbValue = (double)mdb_get_single(mdb->pg_buf, col->cur_value_start);
if (pcbValue)
*pcbValue = sizeof(double);
break;
case SQL_C_CHAR:
case SQL_C_WCHAR:
case SQL_C_STINYINT:
case SQL_C_UTINYINT:
case SQL_C_TINYINT:
case SQL_C_SBIGINT:
case SQL_C_UBIGINT:
case SQL_C_SSHORT:
case SQL_C_USHORT:
case SQL_C_SHORT:
case SQL_C_SLONG:
case SQL_C_ULONG:
case SQL_C_LONG:
case SQL_C_NUMERIC:
// case SQL_C_FLOAT:
// case SQL_C_DOUBLE:
case SQL_C_BIT:
case SQL_C_BINARY:
case SQL_C_INTERVAL_YEAR_TO_MONTH:
case SQL_C_INTERVAL_DAY_TO_HOUR:
case SQL_C_INTERVAL_DAY_TO_MINUTE:
case SQL_C_INTERVAL_DAY_TO_SECOND:
case SQL_C_INTERVAL_HOUR_TO_MINUTE:
case SQL_C_INTERVAL_HOUR_TO_SECOND:
strcpy(stmt->sqlState, "HYC00"); // Not implemented
return SQL_ERROR;
default:
strcpy(stmt->sqlState, "07006"); // Not allowed
return SQL_ERROR;
}
break;
case MDB_DOUBLE:
switch (fCType) {
case SQL_C_DOUBLE:
*(double*)rgbValue = mdb_get_double(mdb->pg_buf, col->cur_value_start);
if (pcbValue)
*pcbValue = sizeof(double);
break;
case SQL_C_CHAR:
case SQL_C_WCHAR:
case SQL_C_STINYINT:
case SQL_C_UTINYINT:
case SQL_C_TINYINT:
case SQL_C_SBIGINT:
case SQL_C_UBIGINT:
case SQL_C_SSHORT:
case SQL_C_USHORT:
case SQL_C_SHORT:
case SQL_C_SLONG:
case SQL_C_ULONG:
case SQL_C_LONG:
case SQL_C_NUMERIC:
case SQL_C_FLOAT:
// case SQL_C_DOUBLE:
case SQL_C_BIT:
case SQL_C_BINARY:
case SQL_C_INTERVAL_YEAR_TO_MONTH:
case SQL_C_INTERVAL_DAY_TO_HOUR:
case SQL_C_INTERVAL_DAY_TO_MINUTE:
case SQL_C_INTERVAL_DAY_TO_SECOND:
case SQL_C_INTERVAL_HOUR_TO_MINUTE:
case SQL_C_INTERVAL_HOUR_TO_SECOND:
strcpy(stmt->sqlState, "HYC00"); // Not implemented
return SQL_ERROR;
default:
strcpy(stmt->sqlState, "07006"); // Not allowed
return SQL_ERROR;
}
break;
#if ODBCVER >= 0x0300
// returns text if old odbc
case MDB_DATETIME:
@ -2058,7 +1987,7 @@ static int _odbc_fix_literals(struct _hstmt *stmt)
char tmp[4096];
char *s, *d, *p;
int i, quoted = 0, find_end = 0;
char quote_char = '\0';
char quote_char;
s=stmt->query;
d=tmp;

View File

@ -1,7 +1,4 @@
if ENABLE_BASH_COMPLETION
bashcompletiondir = $(BASH_COMPLETION_DIR)
dist_bashcompletion_DATA = mdb-count mdb-export mdb-hexdump mdb-import mdb-json mdb-parsecsv mdb-prop mdb-queries mdb-schema mdb-tables mdb-ver
if SQL
dist_bashcompletion_DATA += mdb-sql
endif
dist_bashcompletion_DATA = mdb-count mdb-export mdb-hexdump mdb-import mdb-json mdb-parsecsv mdb-prop mdb-queries mdb-schema mdb-sql mdb-tables mdb-ver
endif

View File

@ -92,11 +92,6 @@ FILE *cfile;
entry->object_name, entry->object_name);
fprintf (cfile, "\tfprintf (stdout, \"**************** %s ****************\\n\");\n", entry->object_name);
table = mdb_read_table (entry);
if (!table) {
fprintf(stderr, "Error: Table %s does not exist in this database.\n", entry->object_name);
/* Don't bother clean up memory before exit */
exit(1);
}
/* get the columns */
mdb_read_columns (table);

View File

@ -97,9 +97,9 @@ main(int argc, char **argv)
g_free(buf);
mdb_free_tabledef(table);
g_free(table_name);
g_free(propColName);
mdb_close(mdb);
printf("Column %s not found in MSysObjects!\n", propColName);
g_free(propColName);
return 1;
}

View File

@ -304,7 +304,7 @@ find_sql_terminator(char *s)
}
sp = &s[len-1];
while (sp > s && isspace((int)*sp)) {
while (sp > s && isspace(*sp)) {
sp--;
}
@ -322,7 +322,7 @@ main(int argc, char **argv)
char prompt[20];
int line = 0;
char *mybuf;
size_t bufsz;
unsigned int bufsz;
MdbSQL *sql;
FILE *in = NULL, *out = NULL;
char *filename_in=NULL, *filename_out=NULL;
@ -408,7 +408,7 @@ main(int argc, char **argv)
/* give the buffer an initial size */
bufsz = 4096;
mybuf = malloc(bufsz);
mybuf = g_malloc(bufsz);
mybuf[0]='\0';
while (1) {
@ -420,7 +420,7 @@ main(int argc, char **argv)
if (in) {
s=calloc(bufsz, 1);
if (!fgets(s, (int)bufsz, in)) {
if (!fgets(s, bufsz, in)) {
// Backwards compatibility with older MDBTools
// Files read from the command line had an
// implicit "go" at the end
@ -464,7 +464,7 @@ main(int argc, char **argv)
if (in) {
fprintf(stderr, "Can not handle nested opens\n");
} else {
while (*fname && isspace((int)*fname))
while (*fname && isspace(*fname))
fname++;
if (!(in = fopen(fname, "r"))) {
fprintf(stderr,"Unable to open file %s\n", fname);
@ -478,7 +478,7 @@ main(int argc, char **argv)
while (strlen(mybuf) + strlen(s) > bufsz) {
bufsz *= 2;
mybuf = realloc(mybuf, bufsz);
mybuf = (char *) g_realloc(mybuf, bufsz);
}
#ifdef HAVE_READLINE_HISTORY
/* don't record blank lines, or lines read from files
@ -500,7 +500,7 @@ main(int argc, char **argv)
}
mdb_sql_exit(sql);
free(mybuf);
g_free(mybuf);
if (s) free(s);
if (out) fclose(out);
if ((in) && (in != stdin)) fclose(in);

View File

@ -1,131 +1,18 @@
#!/bin/sh
#!/bin/bash
# Simple test script; run after performing
# git clone https://github.com/mdbtools/mdbtestdata.git test
set -o errexit
set -o nounset
LANG=C.UTF-8
CDPATH= cd -- "$(dirname -- "$0")"
parseArgs() {
MT_OUTPUT_KIND=verbose
while :; do
if test $# -lt 1; then
break
fi
case "$1" in
-q | --quiet)
MT_OUTPUT_KIND=quiet
;;
-g | --github)
MT_OUTPUT_KIND=github
;;
-h | --help)
printf 'Syntax:\n%s [-q|--quiet|-g|--github] [-h|--help]\n' "$0"
exit 0
;;
*)
printf 'Unrecognized option: "%s"\n' "$1"
exit 1
;;
esac
shift
done
}
testCommand() {
testCommand_name="$1"
shift
case $MT_OUTPUT_KIND in
verbose)
printf '# Running %s (%s)\n' "$testCommand_name" "$*"
if "./src/util/$testCommand_name" "$@"; then
return 0
fi
return 1
;;
quiet)
printf 'Testing %s (%s)... ' "$testCommand_name" "$*"
if "./src/util/$testCommand_name" "$@" >/dev/null; then
printf 'passed.\n'
return 0
fi
return 1
;;
github)
testCommand_tempFile="$(mktemp)"
printf 'Testing %s (%s)... ' "$testCommand_name" "$*"
if "./src/util/$testCommand_name" "$@" 2>&1 >"$testCommand_tempFile"; then
printf 'passed.\n'
testCommand_rc=0
else
printf 'failed.\n'
testCommand_rc=1
fi
echo '::group::Output'
cat "$testCommand_tempFile"
echo '::endgroup::'
unlink "$testCommand_tempFile"
return $testCommand_rc
;;
*)
printf 'Unrecognized MT_OUTPUT_KIND (%s)\n' "$MT_OUTPUT_KIND"
exit 1
;;
esac
}
parseArgs "$@"
rc=0
if ! testCommand mdb-json test/data/ASampleDatabase.accdb "Asset Items"; then
rc=1
fi
if ! testCommand mdb-json test/data/nwind.mdb "Umsätze"; then
rc=1
fi
if ! testCommand mdb-count test/data/ASampleDatabase.accdb "Asset Items"; then
rc=1
fi
if ! testCommand mdb-count test/data/nwind.mdb "Umsätze"; then
rc=1
fi
if ! testCommand mdb-prop test/data/ASampleDatabase.accdb "Asset Items"; then
rc=1
fi
if ! testCommand mdb-prop test/data/nwind.mdb "Umsätze"; then
rc=1
fi
if ! testCommand mdb-schema test/data/ASampleDatabase.accdb; then
rc=1
fi
if ! testCommand mdb-schema test/data/nwind.mdb; then
rc=1
fi
if ! testCommand mdb-schema test/data/nwind.mdb -T "Umsätze" postgres; then
rc=1
fi
if ! testCommand mdb-tables test/data/ASampleDatabase.accdb; then
rc=1
fi
if ! testCommand mdb-tables test/data/nwind.mdb; then
rc=1
fi
if ! testCommand mdb-ver test/data/ASampleDatabase.accdb; then
rc=1
fi
if ! testCommand mdb-ver test/data/nwind.mdb; then
rc=1
fi
if ! testCommand mdb-queries test/data/ASampleDatabase.accdb qryCostsSummedByOwner; then
rc=1
fi
if [ $rc = 0 ]; then
printf -- '\n%s passed.\n' "$0"
else
printf -- '\n%s failed!\n' "$0"
fi
exit $rc
./src/util/mdb-json test/data/ASampleDatabase.accdb "Asset Items"
./src/util/mdb-json test/data/nwind.mdb "Umsätze"
./src/util/mdb-count test/data/ASampleDatabase.accdb "Asset Items"
./src/util/mdb-count test/data/nwind.mdb "Umsätze"
./src/util/mdb-prop test/data/ASampleDatabase.accdb "Asset Items"
./src/util/mdb-prop test/data/nwind.mdb "Umsätze"
./src/util/mdb-schema test/data/ASampleDatabase.accdb
./src/util/mdb-schema test/data/nwind.mdb
./src/util/mdb-schema test/data/nwind.mdb -T "Umsätze" postgres
./src/util/mdb-tables test/data/ASampleDatabase.accdb
./src/util/mdb-tables test/data/nwind.mdb
./src/util/mdb-ver test/data/ASampleDatabase.accdb
./src/util/mdb-ver test/data/nwind.mdb
./src/util/mdb-queries test/data/ASampleDatabase.accdb qryCostsSummedByOwner