Build scripts & automatic generation of FFI files
[hcoop/smlsql.git] / libpq / pg.sml
index 928bf98..63d2720 100644 (file)
@@ -117,6 +117,8 @@ struct
     type timestamp = Time.time
     exception Format of string
 
+    fun isNull s = s = ""
+
     fun intToSql n =
        if n < 0 then
            "-" ^ Int.toString(~n)
@@ -192,12 +194,17 @@ struct
 
     fun pad' (s, 0) = s
       | pad' (s, n) = pad' ("0" ^ s, n-1)
-    fun pad (n, i) = pad' (Int.toString n, i)
+    fun pad (n, i) =
+       let
+           val base = Int.toString n
+       in
+           pad' (base, Int.max (i - size base, 0))
+       end
 
     fun offsetStr NONE = "+00"
       | offsetStr (SOME n) =
        let
-           val n = Int32.toInt (Time.toSeconds n) div 3600
+           val n = LargeInt.toInt (Time.toSeconds n) div 3600
        in
            if n < 0 then
                "-" ^ pad (~n, 2)
@@ -205,14 +212,15 @@ struct
                "+" ^ pad (n, 2)
        end
 
-    fun timestampToSql t =
+    fun timestampToSqlUnquoted t =
        let
            val d = Date.fromTimeLocal t
        in
-           "'" ^ pad (Date.year d, 4) ^ "-" ^ pad (fromMonth (Date.month d), 2) ^ "-" ^ pad (Date.day d, 2) ^
+           pad (Date.year d, 4) ^ "-" ^ pad (fromMonth (Date.month d), 2) ^ "-" ^ pad (Date.day d, 2) ^
            " " ^ pad (Date.hour d, 2) ^ ":" ^ pad (Date.minute d, 2) ^ ":" ^ pad (Date.second d, 2) ^
-           ".000000+" ^ offsetStr (Date.offset d) ^ "'"
+           ".000000" ^ offsetStr (Date.offset d)
        end
+    fun timestampToSql t = "'" ^ timestampToSqlUnquoted t ^ "'"
     fun timestampFromSql s =
        let
            val tokens = String.tokens (fn ch => ch = #"-" orelse ch = #" " orelse ch = #":"
@@ -220,11 +228,21 @@ struct
        in
            case tokens of
                [year, mon, day, hour, minute, second, _, offset] =>
-               Date.toTime (Date.date {day = intFromSql day, hour = intFromSql mon, minute = intFromSql minute,
+               Date.toTime (Date.date {day = intFromSql day, hour = intFromSql hour, minute = intFromSql minute,
+                                       month = toMonth (intFromSql mon),
+                                       offset = SOME (Time.fromSeconds (LargeInt.fromInt (intFromSql offset * 3600))),
+                                       second = intFromSql second div 1000, year = intFromSql year})
+             | [year, mon, day, hour, minute, second, _] =>
+               Date.toTime (Date.date {day = intFromSql day, hour = intFromSql hour, minute = intFromSql minute,
+                                       month = toMonth (intFromSql mon),
+                                       offset = NONE,
+                                       second = intFromSql second, year = intFromSql year})
+             | [year, mon, day, hour, minute, second] =>
+               Date.toTime (Date.date {day = intFromSql day, hour = intFromSql hour, minute = intFromSql minute,
                                        month = toMonth (intFromSql mon),
-                                       offset = SOME (Time.fromSeconds (Int32.fromInt (intFromSql offset * 3600))),
+                                       offset = NONE,
                                        second = intFromSql second div 1000, year = intFromSql year})
-             | _ => raise Format "Invalid timestamp"
+             | _ => raise Format ("Invalid timestamp " ^ s)
        end