mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-04-05 20:31:00 +08:00
Merge pull request #30 from nyalldawson/fix_28
ODBC requires dates formatted in ISO standards
This commit is contained in:
commit
c2087a95cc
@ -277,6 +277,9 @@ typedef struct {
|
|||||||
char *backend_name;
|
char *backend_name;
|
||||||
MdbFormatConstants *fmt;
|
MdbFormatConstants *fmt;
|
||||||
MdbStatistics *stats;
|
MdbStatistics *stats;
|
||||||
|
char date_fmt[64];
|
||||||
|
const char *boolean_false_value;
|
||||||
|
const char *boolean_true_value;
|
||||||
#ifdef HAVE_ICONV
|
#ifdef HAVE_ICONV
|
||||||
iconv_t iconv_in;
|
iconv_t iconv_in;
|
||||||
iconv_t iconv_out;
|
iconv_t iconv_out;
|
||||||
@ -506,8 +509,9 @@ int mdb_col_disp_size(MdbColumn *col);
|
|||||||
size_t mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr);
|
size_t mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr);
|
||||||
size_t mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, size_t chunk_size);
|
size_t mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, size_t chunk_size);
|
||||||
void* mdb_ole_read_full(MdbHandle *mdb, MdbColumn *col, size_t *size);
|
void* mdb_ole_read_full(MdbHandle *mdb, MdbColumn *col, size_t *size);
|
||||||
void mdb_set_date_fmt(const char *);
|
void mdb_set_date_fmt(MdbHandle *mdb, const char *);
|
||||||
void mdb_set_boolean_fmt_words(void);
|
void mdb_set_boolean_fmt_words(MdbHandle *mdb);
|
||||||
|
void mdb_set_boolean_fmt_numbers(MdbHandle *mdb);
|
||||||
int mdb_read_row(MdbTableDef *table, unsigned int row);
|
int mdb_read_row(MdbTableDef *table, unsigned int row);
|
||||||
|
|
||||||
/* dump.c */
|
/* dump.c */
|
||||||
|
@ -32,39 +32,39 @@ char *mdb_numeric_to_string(MdbHandle *mdb, int start, int prec, int scale);
|
|||||||
|
|
||||||
static int _mdb_attempt_bind(MdbHandle *mdb,
|
static int _mdb_attempt_bind(MdbHandle *mdb,
|
||||||
MdbColumn *col, unsigned char isnull, int offset, int len);
|
MdbColumn *col, unsigned char isnull, int offset, int len);
|
||||||
static char *mdb_date_to_string(void *buf, int start);
|
static char *mdb_date_to_string(MdbHandle *mdb, void *buf, int start);
|
||||||
#ifdef MDB_COPY_OLE
|
#ifdef MDB_COPY_OLE
|
||||||
static size_t mdb_copy_ole(MdbHandle *mdb, void *dest, int start, int size);
|
static size_t mdb_copy_ole(MdbHandle *mdb, void *dest, int start, int size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char date_fmt[64] = "%x %X";
|
static const int noleap_cal[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
|
||||||
static int noleap_cal[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
|
static const int leap_cal[] = {0,31,60,91,121,152,182,213,244,274,305,335,366};
|
||||||
static int leap_cal[] = {0,31,60,91,121,152,182,213,244,274,305,335,366};
|
|
||||||
|
|
||||||
|
|
||||||
void mdb_set_date_fmt(const char *fmt)
|
|
||||||
{
|
|
||||||
date_fmt[63] = 0;
|
|
||||||
strncpy(date_fmt, fmt, 63);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some databases (eg PostgreSQL) do not understand integer 0/1 values
|
/* Some databases (eg PostgreSQL) do not understand integer 0/1 values
|
||||||
* as TRUE/FALSE, so provide a means to override the values used to be
|
* as TRUE/FALSE, so provide a means to override the values used to be
|
||||||
* the SQL Standard TRUE/FALSE values.
|
* the SQL Standard TRUE/FALSE values.
|
||||||
*/
|
*/
|
||||||
static char boolean_false_number[] = "0";
|
static const char boolean_false_number[] = "0";
|
||||||
static char boolean_true_number[] = "1";
|
static const char boolean_true_number[] = "1";
|
||||||
|
|
||||||
static char boolean_false_word[] = "FALSE";
|
static const char boolean_false_word[] = "FALSE";
|
||||||
static char boolean_true_word[] = "TRUE";
|
static const char boolean_true_word[] = "TRUE";
|
||||||
|
|
||||||
static char *boolean_false_value = boolean_false_number;
|
void mdb_set_date_fmt(MdbHandle *mdb, const char *fmt)
|
||||||
static char *boolean_true_value = boolean_true_number;
|
|
||||||
|
|
||||||
void mdb_set_boolean_fmt_words()
|
|
||||||
{
|
{
|
||||||
boolean_false_value = boolean_false_word;
|
snprintf(mdb->date_fmt, sizeof(mdb->date_fmt), "%s", fmt);
|
||||||
boolean_true_value = boolean_true_word;
|
}
|
||||||
|
|
||||||
|
void mdb_set_boolean_fmt_numbers(MdbHandle *mdb)
|
||||||
|
{
|
||||||
|
mdb->boolean_false_value = boolean_false_number;
|
||||||
|
mdb->boolean_true_value = boolean_true_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mdb_set_boolean_fmt_words(MdbHandle *mdb)
|
||||||
|
{
|
||||||
|
mdb->boolean_false_value = boolean_false_word;
|
||||||
|
mdb->boolean_true_value = boolean_true_word;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr, int *len_ptr)
|
void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr, int *len_ptr)
|
||||||
@ -200,7 +200,7 @@ mdb_xfer_bound_bool(MdbHandle *mdb, MdbColumn *col, int value)
|
|||||||
col->cur_value_len = value;
|
col->cur_value_len = value;
|
||||||
if (col->bind_ptr) {
|
if (col->bind_ptr) {
|
||||||
strcpy(col->bind_ptr,
|
strcpy(col->bind_ptr,
|
||||||
value ? boolean_false_value : boolean_true_value);
|
value ? mdb->boolean_false_value : mdb->boolean_true_value);
|
||||||
}
|
}
|
||||||
if (col->len_ptr) {
|
if (col->len_ptr) {
|
||||||
*col->len_ptr = strlen(col->bind_ptr);
|
*col->len_ptr = strlen(col->bind_ptr);
|
||||||
@ -822,7 +822,7 @@ mdb_tm_to_date(struct tm *t, double *td)
|
|||||||
{
|
{
|
||||||
short yr = t->tm_year + 1900;
|
short yr = t->tm_year + 1900;
|
||||||
char leap = ((yr & 3) == 0) && ((yr % 100) != 0 || (yr % 400) == 0);
|
char leap = ((yr & 3) == 0) && ((yr % 100) != 0 || (yr % 400) == 0);
|
||||||
int *cal = leap ? leap_cal : noleap_cal;
|
const int *cal = leap ? leap_cal : noleap_cal;
|
||||||
long int time = (yr*365+(yr/4)-(yr/100)+(yr/400)+cal[t->tm_mon]+t->tm_mday)-693959;
|
long int time = (yr*365+(yr/4)-(yr/100)+(yr/400)+cal[t->tm_mon]+t->tm_mday)-693959;
|
||||||
|
|
||||||
*td = (((long)t->tm_hour * 3600)+((long)t->tm_min * 60)+((long)t->tm_sec)) / 86400.0;
|
*td = (((long)t->tm_hour * 3600)+((long)t->tm_min * 60)+((long)t->tm_sec)) / 86400.0;
|
||||||
@ -834,7 +834,7 @@ mdb_date_to_tm(double td, struct tm *t)
|
|||||||
{
|
{
|
||||||
long int day, time;
|
long int day, time;
|
||||||
int yr, q;
|
int yr, q;
|
||||||
int *cal;
|
const int *cal;
|
||||||
|
|
||||||
day = (long int)(td);
|
day = (long int)(td);
|
||||||
time = (long int)(fabs(td - day) * 86400.0 + 0.5);
|
time = (long int)(fabs(td - day) * 86400.0 + 0.5);
|
||||||
@ -876,7 +876,7 @@ mdb_date_to_tm(double td, struct tm *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
mdb_date_to_string(void *buf, int start)
|
mdb_date_to_string(MdbHandle *mdb, void *buf, int start)
|
||||||
{
|
{
|
||||||
struct tm t;
|
struct tm t;
|
||||||
char *text = (char *) g_malloc(MDB_BIND_SIZE);
|
char *text = (char *) g_malloc(MDB_BIND_SIZE);
|
||||||
@ -884,7 +884,7 @@ mdb_date_to_string(void *buf, int start)
|
|||||||
|
|
||||||
mdb_date_to_tm(td, &t);
|
mdb_date_to_tm(td, &t);
|
||||||
|
|
||||||
strftime(text, MDB_BIND_SIZE, date_fmt, &t);
|
strftime(text, MDB_BIND_SIZE, mdb->date_fmt, &t);
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
@ -984,7 +984,7 @@ char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int datatype, int
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MDB_DATETIME:
|
case MDB_DATETIME:
|
||||||
text = mdb_date_to_string(buf, start);
|
text = mdb_date_to_string(mdb, buf, start);
|
||||||
break;
|
break;
|
||||||
case MDB_MEMO:
|
case MDB_MEMO:
|
||||||
text = mdb_memo_to_string(mdb, start, size);
|
text = mdb_memo_to_string(mdb, start, size);
|
||||||
|
@ -179,6 +179,8 @@ MdbHandle *mdb_open(const char *filename, MdbFileFlags flags)
|
|||||||
|
|
||||||
mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle));
|
mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle));
|
||||||
mdb_set_default_backend(mdb, "access");
|
mdb_set_default_backend(mdb, "access");
|
||||||
|
mdb_set_date_fmt(mdb, "%x %X");
|
||||||
|
mdb_set_boolean_fmt_numbers(mdb);
|
||||||
#ifdef HAVE_ICONV
|
#ifdef HAVE_ICONV
|
||||||
mdb->iconv_in = (iconv_t)-1;
|
mdb->iconv_in = (iconv_t)-1;
|
||||||
mdb->iconv_out = (iconv_t)-1;
|
mdb->iconv_out = (iconv_t)-1;
|
||||||
|
@ -163,7 +163,12 @@ static SQLRETURN do_connect (
|
|||||||
struct _hdbc *dbc = (struct _hdbc *) hdbc;
|
struct _hdbc *dbc = (struct _hdbc *) hdbc;
|
||||||
|
|
||||||
if (mdb_sql_open(dbc->sqlconn, database))
|
if (mdb_sql_open(dbc->sqlconn, database))
|
||||||
|
{
|
||||||
|
// ODBC requires ISO format dates, see
|
||||||
|
// https://docs.microsoft.com/en-us/sql/relational-databases/native-client-odbc-date-time/datetime-data-type-conversions-odbc?view=sql-server-ver15
|
||||||
|
mdb_set_date_fmt( dbc->sqlconn->mdb, "%F %H:%M:%S" );
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -159,17 +159,11 @@ main(int argc, char **argv)
|
|||||||
if (insert_dialect)
|
if (insert_dialect)
|
||||||
header_row = 0;
|
header_row = 0;
|
||||||
|
|
||||||
if (date_fmt)
|
|
||||||
mdb_set_date_fmt(date_fmt);
|
|
||||||
|
|
||||||
if (null_text)
|
if (null_text)
|
||||||
null_text = escapes(null_text);
|
null_text = escapes(null_text);
|
||||||
else
|
else
|
||||||
null_text = g_strdup("");
|
null_text = g_strdup("");
|
||||||
|
|
||||||
if (boolean_words)
|
|
||||||
mdb_set_boolean_fmt_words();
|
|
||||||
|
|
||||||
if (str_bin_mode) {
|
if (str_bin_mode) {
|
||||||
if (!strcmp(str_bin_mode, "strip"))
|
if (!strcmp(str_bin_mode, "strip"))
|
||||||
bin_mode = MDB_BINEXPORT_STRIP;
|
bin_mode = MDB_BINEXPORT_STRIP;
|
||||||
@ -189,6 +183,12 @@ main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (date_fmt)
|
||||||
|
mdb_set_date_fmt(mdb, date_fmt);
|
||||||
|
|
||||||
|
if (boolean_words)
|
||||||
|
mdb_set_boolean_fmt_words(mdb);
|
||||||
|
|
||||||
if (insert_dialect)
|
if (insert_dialect)
|
||||||
if (!mdb_set_default_backend(mdb, insert_dialect)) {
|
if (!mdb_set_default_backend(mdb, insert_dialect)) {
|
||||||
fputs("Invalid backend type\n", stderr);
|
fputs("Invalid backend type\n", stderr);
|
||||||
|
Loading…
Reference in New Issue
Block a user