summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adamc@hcoop.net>2008-10-30 14:57:15 -0400
committerGravatar Adam Chlipala <adamc@hcoop.net>2008-10-30 14:57:15 -0400
commit29212f13093acce8e7d10dbb135b2065893bc9fd (patch)
tree40d3f3abaf19f69f1039b4eb6e5fc2d4cb0744ff
parentc9187effa33aa0e68eda9bef752e3ec8a5a2e5d3 (diff)
Reading timestamps from SQL
-rw-r--r--src/c/urweb.c28
-rw-r--r--src/cjr_print.sml2
-rw-r--r--tests/time.ur10
-rw-r--r--tests/time.urp2
4 files changed, 34 insertions, 8 deletions
diff --git a/src/c/urweb.c b/src/c/urweb.c
index 7a160637..df3ce6e1 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -728,6 +728,7 @@ uw_unit uw_Basis_htmlifyBool_w(uw_context ctx, uw_Basis_bool b) {
}
#define TIME_FMT "%x %X"
+#define TIME_FMT_PG "%Y-%m-%d %T"
uw_Basis_string uw_Basis_htmlifyTime(uw_context ctx, uw_Basis_time t) {
size_t len;
@@ -950,10 +951,10 @@ uw_Basis_bool *uw_Basis_stringToBool(uw_context ctx, uw_Basis_string s) {
}
uw_Basis_time *uw_Basis_stringToTime(uw_context ctx, uw_Basis_string s) {
- char *end = strchr(s, 0);
+ char *dot = strchr(s, '.'), *end = strchr(s, 0);
struct tm stm;
- if (strptime(s, TIME_FMT, &stm) == end) {
+ if ((dot ? (*dot = 0, strptime(s, TIME_FMT_PG, &stm)) : strptime(s, TIME_FMT, &stm)) == end) {
uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
*r = mktime(&stm);
return r;
@@ -992,11 +993,24 @@ uw_Basis_bool uw_Basis_stringToBool_error(uw_context ctx, uw_Basis_string s) {
}
uw_Basis_time uw_Basis_stringToTime_error(uw_context ctx, uw_Basis_string s) {
- char *end = strchr(s, 0);
+ char *dot = strchr(s, '.'), *end = strchr(s, 0);
struct tm stm = {};
- if (strptime(s, TIME_FMT, &stm) == end)
- return mktime(&stm);
- else
- uw_error(ctx, FATAL, "Can't parse time: %s", s);
+ 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, &stm) == end)
+ return mktime(&stm);
+ else
+ uw_error(ctx, FATAL, "Can't parse time: %s", s);
+ }
}
diff --git a/src/cjr_print.sml b/src/cjr_print.sml
index 7c0fd73c..01d71872 100644
--- a/src/cjr_print.sml
+++ b/src/cjr_print.sml
@@ -403,6 +403,7 @@ fun p_unsql wontLeakStrings env (tAll as (t, loc)) e =
else
box [string "uw_Basis_strdup(ctx, ", e, string ")"]
| TFfi ("Basis", "bool") => box [string "uw_Basis_stringToBool_error(ctx, ", e, string ")"]
+ | TFfi ("Basis", "time") => box [string "uw_Basis_stringToTime_error(ctx, ", e, string ")"]
| _ => (ErrorMsg.errorAt loc "Don't know how to unmarshal type from SQL";
Print.eprefaces' [("Type", p_typ env tAll)];
string "ERROR")
@@ -1395,6 +1396,7 @@ fun p_sqltype' env (tAll as (t, loc)) =
| TFfi ("Basis", "float") => "float8"
| TFfi ("Basis", "string") => "text"
| TFfi ("Basis", "bool") => "bool"
+ | TFfi ("Basis", "time") => "timestamp"
| _ => (ErrorMsg.errorAt loc "Don't know SQL equivalent of type";
Print.eprefaces' [("Type", p_typ env tAll)];
"ERROR")
diff --git a/tests/time.ur b/tests/time.ur
index 7b8b93ef..f6093dd3 100644
--- a/tests/time.ur
+++ b/tests/time.ur
@@ -1,4 +1,12 @@
+table t : { Id : int, Time : time }
+
val now : time = readError "10/30/08 14:35:42"
val later : time = readError "10/30/08 14:37:42"
-fun main () = return <xml>{[now]}, {[now = now]}, {[now = later]}, {[later < now]}, {[now < later]}</xml>
+fun main () =
+ xml <- queryX (SELECT * FROM t)
+ (fn r => <xml>{[r.T.Id]}: {[r.T.Time]}<br/></xml>);
+ return <xml><body>
+ {xml}
+ {[now]}, {[now = now]}, {[now = later]}, {[later < now]}, {[now < later]}
+ </body></xml>
diff --git a/tests/time.urp b/tests/time.urp
index f48698e9..bfa87a0a 100644
--- a/tests/time.urp
+++ b/tests/time.urp
@@ -1,3 +1,5 @@
debug
+database dbname=time
+sql time.sql
time