0 | module Postgres.LoadTypes
2 | import Postgres.Data.PostgresType
3 | import Postgres.Data.Conn
4 | import Postgres.Query
5 | import Postgres.Result
6 | import Decidable.Equality
9 | import Data.Vect.Elem
13 | integerTypeStrings : List String
14 | integerTypeStrings = [
20 | doubleTypeStrings : List String
21 | doubleTypeStrings = [
27 | charTypeStrings : List String
28 | charTypeStrings = ["char"]
30 | booleanTypeStrings : List String
31 | booleanTypeStrings = ["bool"]
33 | dateTypeStrings : List String
34 | dateTypeStrings = ["date"]
36 | timeTypeStrings : List String
42 | datetimeTypeStrings : List String
43 | datetimeTypeStrings = [
48 | stringTypeStrings : List String
49 | stringTypeStrings = [
56 | jsonTypeStrings : List String
62 | uuidTypeStrings : List String
63 | uuidTypeStrings = ["uuid"]
65 | oidTypeStrings : List String
66 | oidTypeStrings = ["oid"]
68 | quote : String -> String
69 | quote str = (strCons '\'' str) ++ "'"
72 | typeQuery = "SELECT oid, typname from pg_type where typname in (" ++ queryTypes ++ ")"
74 | supportedTypes : List String
75 | supportedTypes = integerTypeStrings
76 | ++ doubleTypeStrings
78 | ++ booleanTypeStrings
81 | ++ datetimeTypeStrings
82 | ++ stringTypeStrings
91 | queryTypes = joinBy "," $
quote <$> (((strCons '_') <$> supportedTypes) ++ supportedTypes)
93 | parseOid : Maybe String -> Either String Oid
94 | parseOid oid = do str <- maybeToEither "Found null when looking for Oid" oid
95 | maybeToEither "Found non-integer Oid" $
96 | MkOid <$> parseInteger str
98 | arrayOrNot : (isArray : Bool) -> PType -> PType
99 | arrayOrNot True ty = PArray ty
100 | arrayOrNot False ty = ty
104 | parseType : String -> PType
105 | parseType type = case isElem True typeSearch of
106 | (No _) => POther type
107 | (Yes e) => case elemToFin e of
108 | 0 => arrayOrNot (fst typeSpec) PInteger
109 | 1 => arrayOrNot (fst typeSpec) PDouble
110 | 2 => arrayOrNot (fst typeSpec) PChar
111 | 3 => arrayOrNot (fst typeSpec) PBoolean
112 | 4 => arrayOrNot (fst typeSpec) PDate
113 | 5 => arrayOrNot (fst typeSpec) PTime
114 | 6 => arrayOrNot (fst typeSpec) PDatetime
115 | 7 => arrayOrNot (fst typeSpec) PString
116 | 8 => arrayOrNot (fst typeSpec) PJson
117 | 9 => arrayOrNot (fst typeSpec) PUuid
118 | 10 => arrayOrNot (fst typeSpec) POid
125 | typeSpec : (Bool, String)
126 | typeSpec = case (strM type) of
127 | (StrCons '_' type') => (True, type')
130 | typeSearch : Vect ?
Bool
131 | typeSearch = elem (snd typeSpec) <$>
132 | [integerTypeStrings
133 | , doubleTypeStrings
135 | , booleanTypeStrings
138 | , datetimeTypeStrings
139 | , stringTypeStrings
144 | typeResult : Vect 2 (Maybe String) -> Either String (Oid, PType)
145 | typeResult [oid, type] = [(o, parseType t) | o <- parseOid oid, t <- (maybeToEither "Found null when looking for type" type)]
150 | pgLoadTypes : HasIO io => Conn -> io (Either String TypeDictionary)
152 | do Right (
r ** 2 ** resultset)
<- liftIO $
pgStringResultsQuery {types=empty} False typeQuery conn
153 | | Right (
_ ** c ** _)
=> pure $
Left $
"ERROR: expected 2 columns but got " ++ (show c)
154 | | Left err => pure $
Left $
"ERROR: " ++ err
156 | Right types <- pure $
traverse typeResult resultset
157 | | Left err => pure $
Left $
"ERROR: " ++ err
158 | pure $
Right $
typeDictionary $
toList types