0 | module Postgres.Result
2 | import public Data.Vect
4 | import Postgres.FFI.Utility
5 | import Postgres.Data.ResultStatus
6 | import Postgres.Data.PostgresType
12 | data PGresult : Type
14 | %foreign libpq "PQclear"
16 | prim__dbClearResult : Ptr PGresult -> PrimIO ()
21 | data Result : Type where
22 | MkResult : Ptr PGresult -> Result
28 | interface ResultProducer source input where
29 | exec : source -> input -> IO (Ptr PGresult)
34 | withResult : ResultProducer source a => source -> a -> (Result -> IO b) -> IO b
35 | withResult src cmd f = do resPtr <- exec src cmd
36 | out <- f $
MkResult resPtr
37 | primIO $
prim__dbClearResult resPtr
45 | resultStatus : Int -> ResultStatus
60 | %foreign libpq "PQresultStatus"
61 | nLibpq "PQresultStatus"
62 | prim__dbResultStatus : Ptr PGresult -> Int
65 | pgResultStatus : Result -> ResultStatus
66 | pgResultStatus (MkResult res) = resultStatus $
prim__dbResultStatus res
69 | pgResultSuccess : Result -> Bool
70 | pgResultSuccess res with (pgResultStatus res)
71 | pgResultSuccess _ | EMPTY_QUERY = True
72 | pgResultSuccess _ | COMMAND_OK = True
73 | pgResultSuccess _ | TUPLES_OK = True
74 | pgResultSuccess _ | COPY_OUT = True
75 | pgResultSuccess _ | COPY_IN = True
76 | pgResultSuccess _ | COPY_BOTH = True
77 | pgResultSuccess _ | SINGLE_TUPLE = True
78 | pgResultSuccess _ | x = False
80 | %foreign libpq "PQresultErrorMessage"
81 | nLibpq "PQresultErrorMessage"
82 | prim__dbResultErrorMessage : Ptr PGresult -> String
87 | pgResultErrorMessage : Result -> Maybe String
88 | pgResultErrorMessage result@(MkResult res) = case pgResultSuccess result of
89 | False => Just $
prim__dbResultErrorMessage res
96 | %foreign libpq "PQntuples"
98 | prim__dbResultRowCount : Ptr PGresult -> Int
100 | %foreign libpq "PQnfields"
102 | prim__dbResultColCount : Ptr PGresult -> Int
107 | resultRowCount : Result -> Nat
108 | resultRowCount (MkResult res) = integerToNat $
cast $
prim__dbResultRowCount res
113 | resultColCount : Result -> Nat
114 | resultColCount (MkResult res) = integerToNat $
cast $
prim__dbResultColCount res
117 | data TupleResult : (rows: Nat) -> (cols: Nat) -> Type where
118 | MkTupleResult : (res : Result) -> TupleResult (resultRowCount res) (resultColCount res)
121 | tupleResult : (res: Result) -> Maybe (TupleResult (resultRowCount res) (resultColCount res))
122 | tupleResult res = case (pgResultStatus res) of
123 | TUPLES_OK => pure $
MkTupleResult res
130 | %foreign libpq "PQfname"
132 | prim__dbResultColName : Ptr PGresult -> (col : Int) -> String
134 | %foreign libpq "PQgetisnull"
135 | nLibpq "PQgetisnull"
136 | prim__dbResultValueIsNull : Ptr PGresult -> (row : Int) -> (col : Int) -> Int
138 | %foreign libpq "PQfformat"
140 | prim__dbResultColFormatCode : Ptr PGresult -> (col : Int) -> Int
144 | %foreign libpq "PQftype"
146 | prim__dbResultColType : Ptr PGresult -> (col : Int) -> Int
149 | resultColName : TupleResult r c -> (col : Fin c) -> String
150 | resultColName (MkTupleResult (MkResult res)) col = prim__dbResultColName res (cast $
finToInteger col)
153 | resultValueIsNull : TupleResult r c -> (row : Fin r) -> (col : Fin c) -> Bool
154 | resultValueIsNull (MkTupleResult (MkResult res)) row col =
155 | intToBool $
prim__dbResultValueIsNull res (cast $
finToInteger row) (cast $
finToInteger col)
160 | resultColType : {auto types : TypeDictionary} -> TupleResult r c -> (col : Fin c) -> PType
161 | resultColType (MkTupleResult (MkResult res)) col =
162 | let oid = prim__dbResultColType res (cast $
finToInteger col) in
163 | lookup (MkOid oid) types
165 | intToFormatCode : Int -> FormatCode
166 | intToFormatCode 0 = Text
167 | intToFormatCode 1 = Binary
168 | intToFormatCode _ = Text
170 | resultColFormatCode : TupleResult r c -> (col : Fin c) -> FormatCode
171 | resultColFormatCode (MkTupleResult (MkResult res)) col =
172 | intToFormatCode $
prim__dbResultColFormatCode res (cast $
finToInteger col)
176 | pgResultSize : {r: Nat} -> {c: Nat} -> TupleResult r c -> (Nat, Nat)
177 | pgResultSize res = (r, c)
179 | %foreign libpq "PQgetvalue"
180 | nLibpq "PQgetvalue"
181 | prim__dbResultValue : Ptr PGresult -> (row: Int) -> (col: Int) -> String
190 | pgResultStringValue : (res: TupleResult rows cols) -> (row: Fin rows) -> (col: Fin cols) -> String
191 | pgResultStringValue (MkTupleResult (MkResult res)) row col =
192 | let r = cast $
the Nat (cast row)
193 | c = cast $
the Nat (cast col) in
194 | prim__dbResultValue res r c
205 | pgResultNullableStringValue : (res: TupleResult rows cols) -> (row: Fin rows) -> (col: Fin cols) -> Maybe String
206 | pgResultNullableStringValue (MkTupleResult (MkResult res)) row col =
207 | let r = cast $
the Nat (cast row)
208 | c = cast $
the Nat (cast col) in
209 | case intToBool $
prim__dbResultValueIsNull res r c of
211 | False => Just $
prim__dbResultValue res r c
215 | record ColHeader where
216 | constructor MkHeader
221 | Show ColHeader where
222 | show (MkHeader name type) = name ++ " " ++ (show type)
228 | resultRow : {cols: Nat} -> (res : TupleResult rows cols) -> (row: Fin rows) -> (Vect cols (Lazy String))
229 | resultRow res row = valueAt <$> (range {len=cols}) where
230 | valueAt : Fin cols -> Lazy String
231 | valueAt col = pgResultStringValue res row col
233 | nullableResultRow : {cols: Nat} -> (res : TupleResult rows cols) -> (row: Fin rows) -> (Vect cols (Lazy (Maybe String)))
234 | nullableResultRow res row = valueAt <$> (range {len=cols}) where
235 | valueAt : Fin cols -> Lazy (Maybe String)
236 | valueAt col = pgResultNullableStringValue res row col
245 | pgStringResultset : {rows: Nat}
247 | -> (res : TupleResult rows cols)
248 | -> (Vect rows (Vect cols (Lazy String)))
249 | pgStringResultset res = valueAt <$> (range {len=rows}) where
250 | valueAt : Fin rows -> Vect cols (Lazy String)
251 | valueAt = resultRow res
254 | StringResultset : (header : Bool) -> Type
255 | StringResultset False = (
rows ** cols ** Vect rows (Vect cols (Maybe String)))
256 | StringResultset True = (
rows ** cols ** (Vect cols ColHeader, Vect rows (Vect cols (Maybe String))))
267 | pgNullableStringResultset : {rows: Nat}
269 | -> (res : TupleResult rows cols)
270 | -> (Vect rows (Vect cols (Lazy (Maybe String))))
271 | pgNullableStringResultset res = valueAt <$> (range {len=rows}) where
272 | valueAt : Fin rows -> Vect cols (Lazy (Maybe String))
273 | valueAt = nullableResultRow res
276 | pgResultsetColNames : {cols : Nat} -> (res : TupleResult rows cols) -> Vect cols String
277 | pgResultsetColNames res = resultColName res <$> (range {len=cols})
283 | pgResultsetColTypes : {auto types : TypeDictionary} -> {cols : Nat} -> (res : TupleResult rows cols) -> Vect cols PType
284 | pgResultsetColTypes res = resultColType res <$> (range {len=cols})