From 8bf9be5b83f80ac3dcf84d64f340c6f67f072358 Mon Sep 17 00:00:00 2001 From: avsdev-cw Date: Tue, 6 Oct 2020 15:51:38 +0100 Subject: [PATCH] Proper handling of MySQL timestamp format<->unix timestamps --- src/db_column.c | 5 +++-- src/db_value.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-- src/db_value.h | 3 +++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/db_column.c b/src/db_column.c index 160f17a..443bb2b 100644 --- a/src/db_column.c +++ b/src/db_column.c @@ -5,6 +5,7 @@ #include #include "db_column.h" +#include "db_value.h" #include "strext.h" @@ -41,7 +42,7 @@ size_t columnTypeToByteSize(e_column_type type) return sizeof(char *); case TYPE_TIMESTAMP: - return sizeof(uint32_t); + return sizeof(int64_t); case TYPE_ID: return sizeof(uint32_t); @@ -347,7 +348,7 @@ int setColumnValue(struct column_data_t *col, uint64_t row, const char *value, s case TYPE_TIMESTAMP: { - *(col->data.ptr_uint32 + row) = (uint32_t)strtoul(value, NULL, 10); + *(col->data.ptr_int64 + row) = db_timestampUnix(value); break; } diff --git a/src/db_value.c b/src/db_value.c index 59ca436..d037dfa 100644 --- a/src/db_value.c +++ b/src/db_value.c @@ -5,10 +5,12 @@ #include #include #include +#include #include "db_value.h" #include "strext.h" + char *db_value(char **str, size_t *len, e_column_type type, uint32_t n_args, ...) { va_list args; @@ -58,6 +60,14 @@ void db_value_sbva(str_builder *sb, e_column_type type, uint32_t n_args, va_list return; } + if (type == TYPE_TIMESTAMP) { + if (db_timestampString(va_arg(args, unsigned int), &tmp_str, &tmp_len) == 0) { + strbld_str(sb, tmp_str, tmp_len); + free(tmp_str); + } + return; + } + if (type == TYPE_STRING) { tmp_str = va_arg(args, char *); @@ -139,8 +149,6 @@ void db_value_sbva(str_builder *sb, e_column_type type, uint32_t n_args, va_list nchar = vsprintf(buf, "%"PRIi32, args); break; } - case TYPE_ID: - case TYPE_TIMESTAMP: case TYPE_UINT32: { nchar = vsprintf(buf, "%"PRIu32, args); @@ -169,6 +177,12 @@ void db_value_sbva(str_builder *sb, e_column_type type, uint32_t n_args, va_list break; } + case TYPE_ID: + { + nchar = vsprintf(buf, "%"PRIu32, args); + break; + } + default: { return; @@ -176,3 +190,40 @@ void db_value_sbva(str_builder *sb, e_column_type type, uint32_t n_args, va_list } strbld_str(sb, buf, (size_t)nchar); } + + +int64_t db_timestampUnix(const char *ts_str) +{ + struct tm tmval; + time_t tunix; + + memset(&tmval, 0, sizeof(struct tm)); + if (sscanf(ts_str, "%d-%d-%d %d:%d:%d", + &tmval.tm_year, &tmval.tm_mon, &tmval.tm_mday, + &tmval.tm_hour, &tmval.tm_min, &tmval.tm_sec) != 6) { + return 0; + } + + tmval.tm_mon -= 1; + tmval.tm_year -= 1900; + tmval.tm_isdst = -1; + + tunix = mktime(&tmval); + + return tunix; +} +char *db_timestampString(int64_t ts_unix, char **str, size_t *str_len) +{ + struct tm *tmval; + + *str = (char *)malloc(20); + if (*str == 0) { + return 0; + } + memset(*str, 0, 20); + + tmval = gmtime((time_t *)&ts_unix); + *str_len = strftime(*str, 20, "%Y-%m-%d %H:%M:%S", tmval); + + return *str; +} diff --git a/src/db_value.h b/src/db_value.h index 24746af..0fbdb03 100644 --- a/src/db_value.h +++ b/src/db_value.h @@ -13,4 +13,7 @@ char *db_value_va(char **str, size_t *len, e_column_type type, uint32_t n_args, void db_value_sb(str_builder *sb, e_column_type type, uint32_t n_args, ...); void db_value_sbva(str_builder *sb, e_column_type type, uint32_t n_args, va_list args); +int64_t db_timestampUnix(const char *ts); +char *db_timestampString(int64_t ts_unix, char **str, size_t *len); + #endif // H__DB_VALUE__