Mercurial > urweb
changeset 1352:703c2c94afd5
Use proper string time format for SQLite
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Mon, 20 Dec 2010 13:22:44 -0500 |
parents | 74d35d9a5d16 |
children | e9cf053108ed |
files | include/urweb.h src/c/urweb.c src/sqlite.sml tests/sqliteTime.ur tests/sqliteTime.urp tests/sqliteTime.urs |
diffstat | 6 files changed, 94 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/include/urweb.h Mon Dec 20 09:34:10 2010 -0500 +++ b/include/urweb.h Mon Dec 20 13:22:44 2010 -0500 @@ -295,4 +295,8 @@ failure_kind uw_runCallback(uw_context, void (*callback)(uw_context)); +uw_Basis_string uw_Basis_timeToStringf(uw_context, const char *fmt, uw_Basis_time); +uw_Basis_time uw_Basis_stringToTimef(uw_context, const char *fmt, uw_Basis_string); +uw_Basis_time uw_Basis_stringToTimef_error(uw_context, const char *fmt, uw_Basis_string); + #endif
--- a/src/c/urweb.c Mon Dec 20 09:34:10 2010 -0500 +++ b/src/c/urweb.c Mon Dec 20 13:22:44 2010 -0500 @@ -2055,6 +2055,7 @@ #define TIME_FMT "%x %X" #define TIME_FMT_PG "%Y-%m-%d %T" +#define TIME_FMT_PG "%Y-%m-%d %T" uw_Basis_string uw_Basis_htmlifyTime(uw_context ctx, uw_Basis_time t) { size_t len; @@ -2560,6 +2561,21 @@ return "<Invalid time>"; } +uw_Basis_string uw_Basis_timeToStringf(uw_context ctx, const char *fmt, uw_Basis_time t) { + size_t len; + char *r; + struct tm stm; + + if (localtime_r(&t, &stm)) { + uw_check_heap(ctx, TIMES_MAX); + r = ctx->heap.front; + len = strftime(r, TIMES_MAX, fmt, &stm); + ctx->heap.front += len+1; + return r; + } else + return "<Invalid time>"; +} + uw_Basis_int *uw_Basis_stringToInt(uw_context ctx, uw_Basis_string s) { char *endptr; uw_Basis_int n = strtoll(s, &endptr, 10); @@ -2643,6 +2659,19 @@ } } +uw_Basis_time *uw_Basis_stringToTimef(uw_context ctx, const char *fmt, uw_Basis_string s) { + char *end = strchr(s, 0); + struct tm stm; + + if (strptime(s, fmt, &stm) == end) { + uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time)); + *r = mktime(&stm); + return r; + } + else + return NULL; +} + uw_Basis_int uw_Basis_stringToInt_error(uw_context ctx, uw_Basis_string s) { char *endptr; uw_Basis_int n = strtoll(s, &endptr, 10); @@ -2704,6 +2733,31 @@ uw_error(ctx, FATAL, "Can't parse bool: %s", s); } +uw_Basis_time uw_Basis_unsqlTime(uw_context ctx, uw_Basis_string s) { + char *dot = strchr(s, '.'), *end = strchr(s, 0); + struct tm stm = {}; + + if (dot) { + *dot = 0; + if (strptime(s, TIME_FMT_PG, &stm)) { + *dot = '.'; + return mktime(&stm); + } + else { + *dot = '.'; + uw_error(ctx, FATAL, "Can't parse time: %s", s); + } + } + else { + if (strptime(s, TIME_FMT_PG, &stm) == end) { + return mktime(&stm); + } else if (strptime(s, TIME_FMT, &stm) == end) { + return mktime(&stm); + } else + uw_error(ctx, FATAL, "Can't parse time: %s", s); + } +} + uw_Basis_time uw_Basis_stringToTime_error(uw_context ctx, uw_Basis_string s) { char *dot = strchr(s, '.'), *end = strchr(s, 0); struct tm stm = {}; @@ -2729,29 +2783,14 @@ } } -uw_Basis_time uw_Basis_unsqlTime(uw_context ctx, uw_Basis_string s) { - char *dot = strchr(s, '.'), *end = strchr(s, 0); +uw_Basis_time uw_Basis_stringToTimef_error(uw_context ctx, const char *fmt, uw_Basis_string s) { + char *end = strchr(s, 0); struct tm stm = {}; - if (dot) { - *dot = 0; - if (strptime(s, TIME_FMT_PG, &stm)) { - *dot = '.'; - return mktime(&stm); - } - else { - *dot = '.'; - uw_error(ctx, FATAL, "Can't parse time: %s", s); - } - } - else { - if (strptime(s, TIME_FMT_PG, &stm) == end) { - return mktime(&stm); - } else if (strptime(s, TIME_FMT, &stm) == end) { - return mktime(&stm); - } else - uw_error(ctx, FATAL, "Can't parse time: %s", s); - } + if (strptime(s, fmt, &stm) == end) + return mktime(&stm); + else + uw_error(ctx, FATAL, "Can't parse time: %s", s); } uw_Basis_blob uw_Basis_stringToBlob_error(uw_context ctx, uw_Basis_string s, size_t len) {
--- a/src/sqlite.sml Mon Dec 20 09:34:10 2010 -0500 +++ b/src/sqlite.sml Mon Dec 20 13:22:44 2010 -0500 @@ -402,6 +402,8 @@ newline] end +val fmt = "\"%Y-%m-%d %H:%M:%S\"" + fun p_getcol {loc, wontLeakStrings, col = i, typ = t} = let fun p_unsql t = @@ -415,7 +417,11 @@ box [string "uw_strdup(ctx, (uw_Basis_string)sqlite3_column_text(stmt, ", string (Int.toString i), string "))"] | Char => box [string "sqlite3_column_text(stmt, ", string (Int.toString i), string ")[0]"] | Bool => box [string "(uw_Basis_bool)sqlite3_column_int(stmt, ", string (Int.toString i), string ")"] - | Time => box [string "uw_Basis_stringToTime_error(ctx, (uw_Basis_string)sqlite3_column_text(stmt, ", string (Int.toString i), string "))"] + | Time => box [string "uw_Basis_stringToTimef_error(ctx, ", + string fmt, + string ", (uw_Basis_string)sqlite3_column_text(stmt, ", + string (Int.toString i), + string "))"] | Blob => box [string "({", newline, string "char *data = (char *)sqlite3_column_blob(stmt, ", @@ -591,7 +597,9 @@ string ")"] | Time => box [string "sqlite3_bind_text(stmt, ", string (Int.toString (i + 1)), - string ", uw_Basis_attrifyTime(ctx, ", + string ", uw_Basis_timeToStringf(ctx, ", + string fmt, + string ", ", arg, string "), -1, SQLITE_TRANSIENT)"] | Blob => box [string "sqlite3_bind_blob(stmt, ",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/sqliteTime.ur Mon Dec 20 13:22:44 2010 -0500 @@ -0,0 +1,14 @@ +table dates : { Date : time } + +fun aform () = + let + val a : time = readError "01/02/03 04:06:07" + in + dml(INSERT INTO dates (Date) VALUES ({[a]})); + ds <- queryX (SELECT * FROM dates) + (fn r => <xml>{[r.Dates.Date]}<br/></xml>); + return <xml><body>{ds}</body></xml> + end + +fun main () = + return <xml><body><form><submit action={aform}/></form></body></xml>