mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-04-05 20:31:00 +08:00
Improved support for "Short Date" fields
* Separate -D (date only) and -T (date/time) format options in mdb-export and mdb-json * New public mdb_set_shortdate_fmt() function in libmdb * New private(ish) mdb_col_is_shortdate() function I'm calling it "shortdate" in order to preserve the existing API. See https://github.com/mdbtools/mdbtools/issues/12
This commit is contained in:
parent
0023e4efe4
commit
7f7761e884
@ -273,6 +273,7 @@ typedef struct {
|
||||
MdbFormatConstants *fmt;
|
||||
size_t bind_size;
|
||||
char date_fmt[64];
|
||||
char shortdate_fmt[64];
|
||||
const char *boolean_false_value;
|
||||
const char *boolean_true_value;
|
||||
unsigned int num_catalog;
|
||||
@ -498,6 +499,7 @@ int mdb_is_user_table(MdbCatalogEntry *entry);
|
||||
int mdb_is_system_table(MdbCatalogEntry *entry);
|
||||
const char *mdb_table_get_prop(const MdbTableDef *table, const gchar *key);
|
||||
const char *mdb_col_get_prop(const MdbColumn *col, const gchar *key);
|
||||
int mdb_col_is_shortdate(const MdbColumn *col);
|
||||
|
||||
/* data.c */
|
||||
int mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr, int *len_ptr);
|
||||
@ -520,6 +522,7 @@ size_t mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, size_t chunk_
|
||||
void* mdb_ole_read_full(MdbHandle *mdb, MdbColumn *col, size_t *size);
|
||||
void mdb_set_bind_size(MdbHandle *mdb, size_t bind_size);
|
||||
void mdb_set_date_fmt(MdbHandle *mdb, const char *);
|
||||
void mdb_set_shortdate_fmt(MdbHandle *mdb, const char *);
|
||||
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);
|
||||
|
@ -253,11 +253,6 @@ quote_with_squotes(const gchar* value)
|
||||
return quote_generic(value, '\'', '\'');
|
||||
}
|
||||
|
||||
static int mdb_col_is_shortdate(const MdbColumn *col) {
|
||||
const char *format = mdb_col_get_prop(col, "Format");
|
||||
return format && !strcmp(format, "Short Date");
|
||||
}
|
||||
|
||||
const MdbBackendType*
|
||||
mdb_get_colbacktype(const MdbColumn *col) {
|
||||
MdbBackend *backend = col->table->entry->mdb->default_backend;
|
||||
|
@ -29,7 +29,7 @@ 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_date_to_string(MdbHandle *mdb, void *buf, int start);
|
||||
static char *mdb_date_to_string(MdbHandle *mdb, const char *fmt, void *buf, int start);
|
||||
#ifdef MDB_COPY_OLE
|
||||
static size_t mdb_copy_ole(MdbHandle *mdb, void *dest, int start, int size);
|
||||
#endif
|
||||
@ -56,6 +56,11 @@ void mdb_set_date_fmt(MdbHandle *mdb, const char *fmt)
|
||||
snprintf(mdb->date_fmt, sizeof(mdb->date_fmt), "%s", fmt);
|
||||
}
|
||||
|
||||
void mdb_set_shortdate_fmt(MdbHandle *mdb, const char *fmt)
|
||||
{
|
||||
snprintf(mdb->shortdate_fmt, sizeof(mdb->shortdate_fmt), "%s", fmt);
|
||||
}
|
||||
|
||||
void mdb_set_boolean_fmt_numbers(MdbHandle *mdb)
|
||||
{
|
||||
mdb->boolean_false_value = boolean_false_number;
|
||||
@ -257,6 +262,12 @@ int ret;
|
||||
char *str;
|
||||
if (col->col_type == MDB_NUMERIC) {
|
||||
str = mdb_numeric_to_string(mdb, start, col->col_scale, col->col_prec);
|
||||
} else if (col->col_type == MDB_DATETIME) {
|
||||
if (mdb_col_is_shortdate(col)) {
|
||||
str = mdb_date_to_string(mdb, mdb->shortdate_fmt, mdb->pg_buf, start);
|
||||
} else {
|
||||
str = mdb_date_to_string(mdb, mdb->date_fmt, mdb->pg_buf, start);
|
||||
}
|
||||
} else {
|
||||
str = mdb_col_to_string(mdb, mdb->pg_buf, start, col->col_type, len);
|
||||
}
|
||||
@ -877,7 +888,7 @@ mdb_date_to_tm(double td, struct tm *t)
|
||||
}
|
||||
|
||||
static char *
|
||||
mdb_date_to_string(MdbHandle *mdb, void *buf, int start)
|
||||
mdb_date_to_string(MdbHandle *mdb, const char *fmt, void *buf, int start)
|
||||
{
|
||||
struct tm t;
|
||||
char *text = (char *) g_malloc(mdb->bind_size);
|
||||
@ -985,7 +996,7 @@ char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int datatype, int
|
||||
}
|
||||
break;
|
||||
case MDB_DATETIME:
|
||||
text = mdb_date_to_string(mdb, buf, start);
|
||||
text = mdb_date_to_string(mdb, mdb->date_fmt, buf, start);
|
||||
break;
|
||||
case MDB_MEMO:
|
||||
text = mdb_memo_to_string(mdb, start, size);
|
||||
|
@ -174,6 +174,7 @@ static MdbHandle *mdb_handle_from_stream(FILE *stream, MdbFileFlags flags) {
|
||||
MdbHandle *mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle));
|
||||
mdb_set_default_backend(mdb, "access");
|
||||
mdb_set_date_fmt(mdb, "%x %X");
|
||||
mdb_set_shortdate_fmt(mdb, "%x");
|
||||
mdb_set_bind_size(mdb, MDB_BIND_SIZE);
|
||||
mdb_set_boolean_fmt_numbers(mdb);
|
||||
#ifdef HAVE_ICONV
|
||||
|
@ -417,3 +417,8 @@ mdb_col_get_prop(const MdbColumn *col, const gchar *key) {
|
||||
return NULL;
|
||||
return g_hash_table_lookup(col->props->hash, key);
|
||||
}
|
||||
|
||||
int mdb_col_is_shortdate(const MdbColumn *col) {
|
||||
const char *format = mdb_col_get_prop(col, "Format");
|
||||
return format && !strcmp(format, "Short Date");
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ static SQLRETURN do_connect (
|
||||
// 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" );
|
||||
mdb_set_shortdate_fmt( dbc->sqlconn->mdb, "%F" );
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
else
|
||||
@ -1592,8 +1593,7 @@ SQLRETURN SQL_API SQLGetData(
|
||||
struct tm tmp_t;
|
||||
mdb_date_to_tm(mdb_get_double(mdb->pg_buf, col->cur_value_start), &tmp_t);
|
||||
|
||||
const char *format = mdb_col_get_prop(col, "Format");
|
||||
if (format && !strcmp(format, "Short Date")) {
|
||||
if (mdb_col_is_shortdate(col)) {
|
||||
DATE_STRUCT sql_dt;
|
||||
sql_dt.year = tmp_t.tm_year + 1900;
|
||||
sql_dt.month = tmp_t.tm_mon + 1;
|
||||
|
@ -43,6 +43,7 @@ main(int argc, char **argv)
|
||||
int boolean_words = 0;
|
||||
int batch_size = 1000;
|
||||
char *insert_dialect = NULL;
|
||||
char *shortdate_fmt = NULL;
|
||||
char *date_fmt = NULL;
|
||||
char *namespace = NULL;
|
||||
char *str_bin_mode = NULL;
|
||||
@ -58,7 +59,8 @@ main(int argc, char **argv)
|
||||
{"row-delimiter", 'R', 0, G_OPTION_ARG_STRING, &row_delimiter, "Specify a row delimiter", "char"},
|
||||
{"quote", 'q', 0, G_OPTION_ARG_STRING, "e_char, "Use <char> to wrap text-like fields. Default is double quote.", "char"},
|
||||
{"backend", 'I', 0, G_OPTION_ARG_STRING, &insert_dialect, "INSERT statements (instead of CSV)", "backend"},
|
||||
{"date-format", 'D', 0, G_OPTION_ARG_STRING, &date_fmt, "Set the date format (see strftime(3) for details)", "format"},
|
||||
{"date-format", 'D', 0, G_OPTION_ARG_STRING, &shortdate_fmt, "Set the date format (see strftime(3) for details)", "format"},
|
||||
{"datetime-format", 'T', 0, G_OPTION_ARG_STRING, &date_fmt, "Set the date/time format (see strftime(3) for details)", "format"},
|
||||
{"escape", 'X', 0, G_OPTION_ARG_STRING, &escape_char, "Use <char> to escape quoted characters within a field. Default is doubling.", "format"},
|
||||
{"namespace", 'N', 0, G_OPTION_ARG_STRING, &namespace, "Prefix identifiers with namespace", "namespace"},
|
||||
{"null", '0', 0, G_OPTION_ARG_STRING, &null_text, "Use <char> to represent a NULL value", "char"},
|
||||
@ -139,6 +141,9 @@ main(int argc, char **argv)
|
||||
if (date_fmt)
|
||||
mdb_set_date_fmt(mdb, date_fmt);
|
||||
|
||||
if (shortdate_fmt)
|
||||
mdb_set_shortdate_fmt(mdb, shortdate_fmt);
|
||||
|
||||
if (boolean_words)
|
||||
mdb_set_boolean_fmt_words(mdb);
|
||||
|
||||
|
@ -109,11 +109,13 @@ main(int argc, char **argv)
|
||||
int *bound_lens;
|
||||
FILE *outfile = stdout;
|
||||
char *date_fmt = NULL;
|
||||
char *shortdate_fmt = NULL;
|
||||
char *value;
|
||||
size_t length;
|
||||
|
||||
GOptionEntry entries[] = {
|
||||
{"date-format", 'D', 0, G_OPTION_ARG_STRING, &date_fmt, "Set the date format (see strftime(3) for details)", "format"},
|
||||
{"date-format", 'D', 0, G_OPTION_ARG_STRING, &shortdate_fmt, "Set the date format (see strftime(3) for details)", "format"},
|
||||
{"datetime-format", 'T', 0, G_OPTION_ARG_STRING, &date_fmt, "Set the date/time format (see strftime(3) for details)", "format"},
|
||||
{"no-unprintable", 'U', 0, G_OPTION_ARG_NONE, &drop_nonascii, "Change unprintable characters to spaces (otherwise escaped as \\u00XX)", NULL},
|
||||
{NULL}
|
||||
};
|
||||
@ -143,6 +145,9 @@ main(int argc, char **argv)
|
||||
if (date_fmt)
|
||||
mdb_set_date_fmt(mdb, date_fmt);
|
||||
|
||||
if (shortdate_fmt)
|
||||
mdb_set_shortdate_fmt(mdb, shortdate_fmt);
|
||||
|
||||
mdb_set_bind_size(mdb, EXPORT_BIND_SIZE);
|
||||
|
||||
table = mdb_read_table_by_name(mdb, argv[2], MDB_TABLE);
|
||||
|
Loading…
Reference in New Issue
Block a user