exception Sql of string
+ type value = string option
+
fun cerrmsg con = Int32.toString (F_PQstatus.f' (C.Ptr.ro' con)) ^ ": "
^ ZString.toML' (F_PQerrorMessage.f' (C.Ptr.ro' con))
end
end
+ fun makeValue v =
+ if C.Ptr.isNull' v then
+ NONE
+ else
+ SOME (ZString.toML' v)
+
fun fold c f b q =
let
val q = ZString.dupML' q
let
fun build (~1, acc) = acc
| build (j, acc) =
- build (j-1, ZString.toML' (F_PQgetvalue.f' (roRes, i, j)) :: acc)
+ build (j-1,
+ if F_PQgetisnull.f' (roRes, i, j) <> 0 then
+ NONE :: acc
+ else
+ makeValue (F_PQgetvalue.f' (roRes, i, j)) :: acc)
in
builder (i+1, f (build (nf-1, []), acc))
end
type timestamp = Time.time
exception Format of string
- fun isNull s = s = ""
+ fun valueOf v =
+ case v of
+ NONE => raise Sql "Trying to read NULL value"
+ | SOME v => v
+
+ fun isNull s =
+ case s of
+ NONE => true
+ | _ => false
fun intToSql n =
if n < 0 then
"-" ^ Int.toString(~n)
else
Int.toString n
- fun intFromSql "" = 0
- | intFromSql s =
+ fun intFromSql' "" = 0
+ | intFromSql' s =
(case Int.fromString s of
NONE => raise Format ("Bad integer: " ^ s)
| SOME n => n)
+ fun intFromSql v = intFromSql' (valueOf v)
fun stringToSql s =
let
| xch #"\r" = "\\r"
| xch c = str c
in
- foldl (fn (c, s) => s ^ xch c) "'" (String.explode s) ^ "'"
+ foldl (fn (c, s) => s ^ xch c) "E'" (String.explode s) ^ "'"
end
- fun stringFromSql s = s
+ val stringFromSql = valueOf
fun realToSql s =
if s < 0.0 then
"-" ^ Real.toString(~s)
else
Real.toString s
- fun realFromSql "" = 0.0
- | realFromSql s =
+ fun realFromSql' "" = 0.0
+ | realFromSql' s =
(case Real.fromString s of
NONE => raise Format ("Bad real: " ^ s)
| SOME r => r)
+ fun realFromSql v = realFromSql' (valueOf v)
fun realToString s = realToSql s
fun toMonth m =
".000000" ^ offsetStr (Date.offset d)
end
fun timestampToSql t = "'" ^ timestampToSqlUnquoted t ^ "'"
- fun timestampFromSql s =
+ fun timestampFromSql' s =
let
val tokens = String.tokens (fn ch => ch = #"-" orelse ch = #" " orelse ch = #":"
orelse ch = #"." orelse ch = #"+") s
in
case tokens of
[year, mon, day, hour, minute, second, _, offset] =>
- 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})
+ Date.toTime (Date.date {day = valOf (Int.fromString day), hour = valOf (Int.fromString hour), minute = valOf (Int.fromString minute),
+ month = toMonth (valOf (Int.fromString mon)),
+ offset = SOME (Time.fromSeconds (LargeInt.fromInt (valOf (Int.fromString offset) * 3600))),
+ second = valOf (Int.fromString second) div 1000, year = valOf (Int.fromString year)})
| [year, mon, day, hour, minute, second, _] =>
- Date.toTime (Date.date {day = intFromSql day, hour = intFromSql hour, minute = intFromSql minute,
- month = toMonth (intFromSql mon),
+ Date.toTime (Date.date {day = valOf (Int.fromString day), hour = valOf (Int.fromString hour), minute = valOf (Int.fromString minute),
+ month = toMonth (valOf (Int.fromString mon)),
offset = NONE,
- second = intFromSql second, year = intFromSql year})
+ second = valOf (Int.fromString second), year = valOf (Int.fromString year)})
| [year, mon, day, hour, minute, second] =>
- Date.toTime (Date.date {day = intFromSql day, hour = intFromSql hour, minute = intFromSql minute,
- month = toMonth (intFromSql mon),
+ Date.toTime (Date.date {day = valOf (Int.fromString day), hour = valOf (Int.fromString hour), minute = valOf (Int.fromString minute),
+ month = toMonth (valOf (Int.fromString mon)),
offset = NONE,
- second = intFromSql second div 1000, year = intFromSql year})
+ second = valOf (Int.fromString second) div 1000, year = valOf (Int.fromString year)})
| _ => raise Format ("Invalid timestamp " ^ s)
end
+ fun timestampFromSql v = timestampFromSql' (valueOf v)
fun boolToSql true = "TRUE"
| boolToSql false = "FALSE"
- fun boolFromSql "FALSE" = false
- | boolFromSql "f" = false
- | boolFromSql "false" = false
- | boolFromSql "n" = false
- | boolFromSql "no" = false
- | boolFromSql "0" = false
- | boolFromSql "" = false
- | boolFromSql _ = true
+ fun boolFromSql' "FALSE" = false
+ | boolFromSql' "f" = false
+ | boolFromSql' "false" = false
+ | boolFromSql' "n" = false
+ | boolFromSql' "no" = false
+ | boolFromSql' "0" = false
+ | boolFromSql' "" = false
+ | boolFromSql' _ = true
+
+ fun boolFromSql v = boolFromSql' (valueOf v)
end
-structure PgClient = SqlClient(PgDriver)
\ No newline at end of file
+structure PgClient = SqlClient(PgDriver)