git.iko.soy/typeable/postgresql-simple
on master help sign in
Implement new TypeInfo system and fix array conversion
136a6f8Leon P Smith
postgresql-simple.cabal+2
@@ -35,6 +35,7 @@ Library
35 Database.PostgreSQL.Simple.ToRow
35 Database.PostgreSQL.Simple.ToRow
36 Database.PostgreSQL.Simple.Transaction
36 Database.PostgreSQL.Simple.Transaction
37 Database.PostgreSQL.Simple.TypeInfo
37 Database.PostgreSQL.Simple.TypeInfo
38+ Database.PostgreSQL.Simple.TypeInfo.Static
38 Database.PostgreSQL.Simple.Types
39 Database.PostgreSQL.Simple.Types
39 Database.PostgreSQL.Simple.Errors
40 Database.PostgreSQL.Simple.Errors
40-- Other-modules:
41-- Other-modules:
@@ -43,6 +44,7 @@ Library
43 Other-modules:
44 Other-modules:
44 Database.PostgreSQL.Simple.Compat
45 Database.PostgreSQL.Simple.Compat
45 Database.PostgreSQL.Simple.Time.Implementation
46 Database.PostgreSQL.Simple.Time.Implementation
47+ Database.PostgreSQL.Simple.TypeInfo.Types
46
48
47 Build-depends:
49 Build-depends:
48 attoparsec >= 0.8.5.3,
50 attoparsec >= 0.8.5.3,
src/Database/PostgreSQL/Simple/FromField.hs+33−15
@@ -73,7 +73,9 @@ module Database.PostgreSQL.Simple.FromField
73
73
74 , Field
74 , Field
75 , typename
75 , typename
76− , typeinfo
76+ , TypeInfo(..)
77+ , typeInfo
78+ , typeInfoByOid
77 , name
79 , name
78 , tableOid
80 , tableOid
79 , tableColumn
81 , tableColumn
@@ -94,7 +96,6 @@ import Data.ByteString (ByteString)
94import qualified Data.ByteString.Char8 as B
96import qualified Data.ByteString.Char8 as B
95import Data.Int (Int16, Int32, Int64)
97import Data.Int (Int16, Int32, Int64)
96import Data.List (foldl')
98import Data.List (foldl')
97−import Data.Maybe (fromMaybe)
98import Data.Ratio (Ratio)
99import Data.Ratio (Ratio)
99import Data.Time ( UTCTime, ZonedTime, LocalTime, Day, TimeOfDay )
100import Data.Time ( UTCTime, ZonedTime, LocalTime, Day, TimeOfDay )
100import Data.Typeable (Typeable, typeOf)
101import Data.Typeable (Typeable, typeOf)
@@ -106,9 +107,9 @@ import Database.PostgreSQL.Simple.BuiltinTypes
106import Database.PostgreSQL.Simple.Compat
107import Database.PostgreSQL.Simple.Compat
107import Database.PostgreSQL.Simple.Ok
108import Database.PostgreSQL.Simple.Ok
108import Database.PostgreSQL.Simple.Types (Binary(..), Null(..))
109import Database.PostgreSQL.Simple.Types (Binary(..), Null(..))
109−import Database.PostgreSQL.Simple.TypeInfo
110+import Database.PostgreSQL.Simple.TypeInfo as TypeInfo
110import Database.PostgreSQL.Simple.Time
111import Database.PostgreSQL.Simple.Time
111−import Database.PostgreSQL.Simple.Arrays
112+import Database.PostgreSQL.Simple.Arrays as Arrays
112import qualified Database.PostgreSQL.LibPQ as PQ
113import qualified Database.PostgreSQL.LibPQ as PQ
113import qualified Data.ByteString as SB
114import qualified Data.ByteString as SB
114import qualified Data.ByteString.Char8 as B8
115import qualified Data.ByteString.Char8 as B8
@@ -179,12 +180,16 @@ class FromField a where
179-- meta-schema.
180-- meta-schema.
180
181
181typename :: Field -> Conversion ByteString
182typename :: Field -> Conversion ByteString
182−typename field = typname . typ <$> typeinfo field
183+typename field = typname <$> typeInfo field
183
184
184−typeinfo :: Field -> Conversion TypeInfo
185+typeInfo :: Field -> Conversion TypeInfo
185−typeinfo Field{..} = Conversion $ \conn -> do
186+typeInfo Field{..} = Conversion $ \conn -> do
186 Ok <$> (getTypeInfo conn =<< PQ.ftype result column)
187 Ok <$> (getTypeInfo conn =<< PQ.ftype result column)
187
188
189+typeInfoByOid :: PQ.Oid -> Conversion TypeInfo
190+typeInfoByOid oid = Conversion $ \conn -> do
191+ Ok <$> (getTypeInfo conn oid)
192+
188-- | Returns the name of the column. This is often determined by a table
193-- | Returns the name of the column. This is often determined by a table
189-- definition, but it can be set using an @as@ clause.
194-- definition, but it can be set using an @as@ clause.
190
195
@@ -205,7 +210,7 @@ tableOid Field{..} = toMaybeOid (unsafeDupablePerformIO (PQ.ftable result column
205 else Just x
210 else Just x
206
211
207-- | If the column has a table associated with it, this returns the number
212-- | If the column has a table associated with it, this returns the number
208−-- of the associated table column. Numbering starts from 0. Analogous
213+-- off the associated table column. Numbering starts from 0. Analogous
209-- to libpq's @PQftablecol@.
214-- to libpq's @PQftablecol@.
210
215
211tableColumn :: Field -> Int
216tableColumn :: Field -> Int
@@ -352,14 +357,27 @@ instance (FromField a, FromField b) => FromField (Either a b) where
352 <|> (Left <$> fromField f dat)
357 <|> (Left <$> fromField f dat)
353
358
354instance (FromField a, Typeable a) => FromField (Vector a) where
359instance (FromField a, Typeable a) => FromField (Vector a) where
360+ fromField f mdat = do
361+ info <- typeInfo f
362+ case info of
363+ TypeInfo.Array{} ->
364+ case mdat of
365+ Nothing -> returnError UnexpectedNull f ""
366+ Just dat -> do
367+ case parseOnly (fromArray info f) dat of
355− fromField f dat = either (returnError ConversionFailed f)
368+ Left err -> returnError ConversionFailed f err
356− (V.fromList <$>)
369+ Right conv -> V.fromList <$> conv
357− (parseOnly (fromArray ',' f) (maybe "" id dat))
370+ _ -> returnError Incompatible f ""
358−
371+
359−fromArray :: (FromField a) => Char -> Field -> Parser (Conversion [a])
372+fromArray :: (FromField a)
373+ => TypeInfo -> Field -> Parser (Conversion [a])
360−fromArray delim f = sequence . (parseIt <$>) <$> array delim
374+fromArray typeInfo f = sequence . (parseIt <$>) <$> array delim
361 where
375 where
376+ delim = typdelim (typelem typeInfo)
377+ fElem = f{ typeOid = typoid (typelem typeInfo) }
362− parseIt item = (fromField f . Just . fmt delim) item
378+ parseIt item = (fromField f' . Just . fmt delim) item
379+ where f' | Arrays.Array _ <- item = f
380+ | otherwise = fElem
363
381
364newtype Compat = Compat Word64
382newtype Compat = Compat Word64
365
383
src/Database/PostgreSQL/Simple/FromRow.hs+1−1
@@ -79,7 +79,7 @@ getTypeInfoByCol Row{..} col =
79 Ok <$> getTypeInfo conn oid
79 Ok <$> getTypeInfo conn oid
80
80
81getTypenameByCol :: Row -> PQ.Column -> Conversion ByteString
81getTypenameByCol :: Row -> PQ.Column -> Conversion ByteString
82−getTypenameByCol row col = typname . typ <$> getTypeInfoByCol row col
82+getTypenameByCol row col = typname <$> getTypeInfoByCol row col
83
83
84fieldWith :: FieldParser a -> RowParser a
84fieldWith :: FieldParser a -> RowParser a
85fieldWith fieldP = RP $ do
85fieldWith fieldP = RP $ do
src/Database/PostgreSQL/Simple/FromRow.hs-boot+1
@@ -5,3 +5,4 @@ import {-# SOURCE #-} Database.PostgreSQL.Simple.FromField
5class FromRow a
5class FromRow a
6
6
7instance (FromField a, FromField b, FromField c, FromField d) => FromRow (a,b,c,d)
7instance (FromField a, FromField b, FromField c, FromField d) => FromRow (a,b,c,d)
8+instance (FromField a, FromField b, FromField c, FromField d, FromField e) => FromRow (a,b,c,d,e)
src/Database/PostgreSQL/Simple/Internal.hs+3−8
@@ -39,6 +39,7 @@ import qualified Database.PostgreSQL.LibPQ as PQ
39import Database.PostgreSQL.LibPQ(ExecStatus(..))
39import Database.PostgreSQL.LibPQ(ExecStatus(..))
40import Database.PostgreSQL.Simple.Ok
40import Database.PostgreSQL.Simple.Ok
41import Database.PostgreSQL.Simple.Types (Query(..))
41import Database.PostgreSQL.Simple.Types (Query(..))
42+import Database.PostgreSQL.Simple.TypeInfo.Types(TypeInfo)
42import Control.Monad.Trans.State.Strict
43import Control.Monad.Trans.State.Strict
43import Control.Monad.Trans.Reader
44import Control.Monad.Trans.Reader
44
45
@@ -56,17 +57,11 @@ data Field = Field {
56 -- to libpq's @PQftype@.
57 -- to libpq's @PQftype@.
57 }
58 }
58
59
59−data NamedOid = NamedOid { typoid :: !PQ.Oid
60+type TypeInfoCache = IntMap.IntMap TypeInfo
60− , typname :: !ByteString
61− } deriving Show
62−
63−data TypeInfo = TypeInfo { typ :: !NamedOid
64− , typelem :: !(Maybe NamedOid)
65− } deriving Show
66
61
67data Connection = Connection {
62data Connection = Connection {
68 connectionHandle :: {-# UNPACK #-} !(MVar PQ.Connection)
63 connectionHandle :: {-# UNPACK #-} !(MVar PQ.Connection)
69− , connectionObjects :: {-# UNPACK #-} !(MVar (IntMap.IntMap TypeInfo))
64+ , connectionObjects :: {-# UNPACK #-} !(MVar TypeInfoCache)
70 }
65 }
71
66
72data SqlError = SqlError {
67data SqlError = SqlError {
src/Database/PostgreSQL/Simple/TypeInfo.hs+35−28
@@ -12,10 +12,10 @@
12
12
13module Database.PostgreSQL.Simple.TypeInfo
13module Database.PostgreSQL.Simple.TypeInfo
14 ( getTypeInfo
14 ( getTypeInfo
15− , NamedOid(..)
16 , TypeInfo(..)
15 , TypeInfo(..)
17 ) where
16 ) where
18
17
18+import qualified Data.ByteString.Char8 as B8
19import qualified Data.IntMap as IntMap
19import qualified Data.IntMap as IntMap
20import Control.Concurrent.MVar
20import Control.Concurrent.MVar
21import Control.Exception (throw)
21import Control.Exception (throw)
@@ -24,33 +24,40 @@ import qualified Database.PostgreSQL.LibPQ as PQ
24import {-# SOURCE #-} Database.PostgreSQL.Simple
24import {-# SOURCE #-} Database.PostgreSQL.Simple
25import Database.PostgreSQL.Simple.Internal
25import Database.PostgreSQL.Simple.Internal
26import Database.PostgreSQL.Simple.Types
26import Database.PostgreSQL.Simple.Types
27−import Database.PostgreSQL.Simple.BuiltinTypes
27+import Database.PostgreSQL.Simple.TypeInfo.Types
28+import Database.PostgreSQL.Simple.TypeInfo.Static
28
29
29getTypeInfo :: Connection -> PQ.Oid -> IO TypeInfo
30getTypeInfo :: Connection -> PQ.Oid -> IO TypeInfo
30getTypeInfo conn@Connection{..} oid =
31getTypeInfo conn@Connection{..} oid =
31− case oid2typname oid of
32+ case staticTypeInfo oid of
32− Just name -> return $! TypeInfo { typ = NamedOid oid name
33+ Just name -> return name
33− , typelem = Nothing
34− }
35− Nothing -> modifyMVar connectionObjects $ \oidmap -> do
34+ Nothing -> modifyMVar connectionObjects $ getTypeInfo' conn oid
35+
36+getTypeInfo' :: Connection -> PQ.Oid -> TypeInfoCache
37+ -> IO (TypeInfoCache, TypeInfo)
38+getTypeInfo' conn oid oidmap =
36− case IntMap.lookup (oid2int oid) oidmap of
39+ case IntMap.lookup (oid2int oid) oidmap of
37− Just typeinfo -> return (oidmap, typeinfo)
40+ Just typeinfo -> return (oidmap, typeinfo)
38− Nothing -> do
41+ Nothing -> do
39− names <- query conn "SELECT p.oid, p.typname, c.oid, c.typname\
42+ names <- query conn "SELECT oid, typcategory, typdelim, typname, typelem\
40− \ FROM pg_type AS p LEFT OUTER JOIN pg_type AS c\
41− \ ON c.oid = p.typelem\
42− \ WHERE p.oid = ?"
43+ \ FROM pg_type WHERE oid = ?"
43− (Only oid)
44+ (Only oid)
45+ (oidmap', typeInfo) <-
44− typinf <- case names of
46+ case names of
45− [] -> return $ throw (fatalError "invalid type oid")
47+ [] -> return $ throw (fatalError "invalid type oid")
46− [(pOid, pTypName, mbCOid, mbCTypName)] ->
48+ [(typoid, typcategory_, typdelim_, typname, typelem_)] -> do
47− return $! TypeInfo { typ = NamedOid pOid pTypName
49+ let !typcategory = B8.index typcategory_ 0
48− , typelem = do
50+ !typdelim = B8.index typdelim_ 0
49− cOid <- mbCOid
51+ if typcategory == 'A'
50− cTypName <- mbCTypName
52+ then do
51− return $ NamedOid cOid cTypName
53+ (oidmap', typelem) <- getTypeInfo' conn typelem_ oidmap
52− }
54+ let !typeInfo = Array{..}
55+ return (oidmap', typeInfo)
56+ else do
57+ let !typeInfo = Basic{..}
58+ return (oidmap, typeInfo)
53− _ -> fail "typename query returned more than one result"
59+ _ -> fail "typename query returned more than one result"
54− -- oid is a primary key, so the query should
60+ -- oid is a primary key, so the query should
55− -- never return more than one result
61+ -- never return more than one result
56− return (IntMap.insert (oid2int oid) typinf oidmap, typinf)
62+ let !oidmap'' = IntMap.insert (oid2int oid) typeInfo oidmap'
63+ return $! (oidmap'', typeInfo)
src/Database/PostgreSQL/Simple/TypeInfo/Static.hs+50−101
@@ -6,6 +6,9 @@
6-- Maintainer: Leon P Smith <leon@melding-monads.com>
6-- Maintainer: Leon P Smith <leon@melding-monads.com>
7-- Stability: experimental
7-- Stability: experimental
8--
8--
9+-- Note that this module is semi-internal, and you probably want to use
10+-- Database.PostgreSQL.Simple.TypeInfo instead.
11+--
9------------------------------------------------------------------------------
12------------------------------------------------------------------------------
10
13
11-- Note that this file is generated by tools/GenTypeInfo.hs, and should
14-- Note that this file is generated by tools/GenTypeInfo.hs, and should
@@ -62,16 +65,8 @@ module Database.PostgreSQL.Simple.TypeInfo.Static
62 , uuid
65 , uuid
63 ) where
66 ) where
64
67
65−import Data.ByteString (ByteString)
66import Database.PostgreSQL.LibPQ (Oid(..))
68import Database.PostgreSQL.LibPQ (Oid(..))
67−
69+import Database.PostgreSQL.Simple.TypeInfo.Types
68−data TypeInfo = TypeInfo
69− { typoid :: {-# UNPACK #-} !Oid
70− , typcategory :: {-# UNPACK #-} !Char
71− , typdelim :: {-# UNPACK #-} !Char
72− , typelem :: !(Maybe TypeInfo)
73− , typname :: !ByteString
74− }
75
70
76staticTypeInfo :: Oid -> Maybe TypeInfo
71staticTypeInfo :: Oid -> Maybe TypeInfo
77staticTypeInfo (Oid x) = case x of
72staticTypeInfo (Oid x) = case x of
@@ -124,415 +119,369 @@ staticTypeInfo (Oid x) = case x of
124 _ -> Nothing
119 _ -> Nothing
125
120
126bool :: TypeInfo
121bool :: TypeInfo
127−bool = TypeInfo {
122+bool = Basic {
128 typoid = Oid 16,
123 typoid = Oid 16,
129 typcategory = 'B',
124 typcategory = 'B',
130 typdelim = ',',
125 typdelim = ',',
131− typelem = Nothing,
132 typname = "bool"
126 typname = "bool"
133 }
127 }
134
128
135bytea :: TypeInfo
129bytea :: TypeInfo
136−bytea = TypeInfo {
130+bytea = Basic {
137 typoid = Oid 17,
131 typoid = Oid 17,
138 typcategory = 'U',
132 typcategory = 'U',
139 typdelim = ',',
133 typdelim = ',',
140− typelem = Nothing,
141 typname = "bytea"
134 typname = "bytea"
142 }
135 }
143
136
144char :: TypeInfo
137char :: TypeInfo
145−char = TypeInfo {
138+char = Basic {
146 typoid = Oid 18,
139 typoid = Oid 18,
147 typcategory = 'S',
140 typcategory = 'S',
148 typdelim = ',',
141 typdelim = ',',
149− typelem = Nothing,
150 typname = "char"
142 typname = "char"
151 }
143 }
152
144
153name :: TypeInfo
145name :: TypeInfo
154−name = TypeInfo {
146+name = Basic {
155 typoid = Oid 19,
147 typoid = Oid 19,
156 typcategory = 'S',
148 typcategory = 'S',
157 typdelim = ',',
149 typdelim = ',',
158− typelem = Just char,
159 typname = "name"
150 typname = "name"
160 }
151 }
161
152
162int8 :: TypeInfo
153int8 :: TypeInfo
163−int8 = TypeInfo {
154+int8 = Basic {
164 typoid = Oid 20,
155 typoid = Oid 20,
165 typcategory = 'N',
156 typcategory = 'N',
166 typdelim = ',',
157 typdelim = ',',
167− typelem = Nothing,
168 typname = "int8"
158 typname = "int8"
169 }
159 }
170
160
171int2 :: TypeInfo
161int2 :: TypeInfo
172−int2 = TypeInfo {
162+int2 = Basic {
173 typoid = Oid 21,
163 typoid = Oid 21,
174 typcategory = 'N',
164 typcategory = 'N',
175 typdelim = ',',
165 typdelim = ',',
176− typelem = Nothing,
177 typname = "int2"
166 typname = "int2"
178 }
167 }
179
168
180int4 :: TypeInfo
169int4 :: TypeInfo
181−int4 = TypeInfo {
170+int4 = Basic {
182 typoid = Oid 23,
171 typoid = Oid 23,
183 typcategory = 'N',
172 typcategory = 'N',
184 typdelim = ',',
173 typdelim = ',',
185− typelem = Nothing,
186 typname = "int4"
174 typname = "int4"
187 }
175 }
188
176
189regproc :: TypeInfo
177regproc :: TypeInfo
190−regproc = TypeInfo {
178+regproc = Basic {
191 typoid = Oid 24,
179 typoid = Oid 24,
192 typcategory = 'N',
180 typcategory = 'N',
193 typdelim = ',',
181 typdelim = ',',
194− typelem = Nothing,
195 typname = "regproc"
182 typname = "regproc"
196 }
183 }
197
184
198text :: TypeInfo
185text :: TypeInfo
199−text = TypeInfo {
186+text = Basic {
200 typoid = Oid 25,
187 typoid = Oid 25,
201 typcategory = 'S',
188 typcategory = 'S',
202 typdelim = ',',
189 typdelim = ',',
203− typelem = Nothing,
204 typname = "text"
190 typname = "text"
205 }
191 }
206
192
207oid :: TypeInfo
193oid :: TypeInfo
208−oid = TypeInfo {
194+oid = Basic {
209 typoid = Oid 26,
195 typoid = Oid 26,
210 typcategory = 'N',
196 typcategory = 'N',
211 typdelim = ',',
197 typdelim = ',',
212− typelem = Nothing,
213 typname = "oid"
198 typname = "oid"
214 }
199 }
215
200
216tid :: TypeInfo
201tid :: TypeInfo
217−tid = TypeInfo {
202+tid = Basic {
218 typoid = Oid 27,
203 typoid = Oid 27,
219 typcategory = 'U',
204 typcategory = 'U',
220 typdelim = ',',
205 typdelim = ',',
221− typelem = Nothing,
222 typname = "tid"
206 typname = "tid"
223 }
207 }
224
208
225xid :: TypeInfo
209xid :: TypeInfo
226−xid = TypeInfo {
210+xid = Basic {
227 typoid = Oid 28,
211 typoid = Oid 28,
228 typcategory = 'U',
212 typcategory = 'U',
229 typdelim = ',',
213 typdelim = ',',
230− typelem = Nothing,
231 typname = "xid"
214 typname = "xid"
232 }
215 }
233
216
234cid :: TypeInfo
217cid :: TypeInfo
235−cid = TypeInfo {
218+cid = Basic {
236 typoid = Oid 29,
219 typoid = Oid 29,
237 typcategory = 'U',
220 typcategory = 'U',
238 typdelim = ',',
221 typdelim = ',',
239− typelem = Nothing,
240 typname = "cid"
222 typname = "cid"
241 }
223 }
242
224
243xml :: TypeInfo
225xml :: TypeInfo
244−xml = TypeInfo {
226+xml = Basic {
245 typoid = Oid 142,
227 typoid = Oid 142,
246 typcategory = 'U',
228 typcategory = 'U',
247 typdelim = ',',
229 typdelim = ',',
248− typelem = Nothing,
249 typname = "xml"
230 typname = "xml"
250 }
231 }
251
232
252point :: TypeInfo
233point :: TypeInfo
253−point = TypeInfo {
234+point = Basic {
254 typoid = Oid 600,
235 typoid = Oid 600,
255 typcategory = 'G',
236 typcategory = 'G',
256 typdelim = ',',
237 typdelim = ',',
257− typelem = Just float8,
258 typname = "point"
238 typname = "point"
259 }
239 }
260
240
261lseg :: TypeInfo
241lseg :: TypeInfo
262−lseg = TypeInfo {
242+lseg = Basic {
263 typoid = Oid 601,
243 typoid = Oid 601,
264 typcategory = 'G',
244 typcategory = 'G',
265 typdelim = ',',
245 typdelim = ',',
266− typelem = Just point,
267 typname = "lseg"
246 typname = "lseg"
268 }
247 }
269
248
270path :: TypeInfo
249path :: TypeInfo
271−path = TypeInfo {
250+path = Basic {
272 typoid = Oid 602,
251 typoid = Oid 602,
273 typcategory = 'G',
252 typcategory = 'G',
274 typdelim = ',',
253 typdelim = ',',
275− typelem = Nothing,
276 typname = "path"
254 typname = "path"
277 }
255 }
278
256
279box :: TypeInfo
257box :: TypeInfo
280−box = TypeInfo {
258+box = Basic {
281 typoid = Oid 603,
259 typoid = Oid 603,
282 typcategory = 'G',
260 typcategory = 'G',
283 typdelim = ';',
261 typdelim = ';',
284− typelem = Just point,
285 typname = "box"
262 typname = "box"
286 }
263 }
287
264
288polygon :: TypeInfo
265polygon :: TypeInfo
289−polygon = TypeInfo {
266+polygon = Basic {
290 typoid = Oid 604,
267 typoid = Oid 604,
291 typcategory = 'G',
268 typcategory = 'G',
292 typdelim = ',',
269 typdelim = ',',
293− typelem = Nothing,
294 typname = "polygon"
270 typname = "polygon"
295 }
271 }
296
272
297line :: TypeInfo
273line :: TypeInfo
298−line = TypeInfo {
274+line = Basic {
299 typoid = Oid 628,
275 typoid = Oid 628,
300 typcategory = 'G',
276 typcategory = 'G',
301 typdelim = ',',
277 typdelim = ',',
302− typelem = Just float8,
303 typname = "line"
278 typname = "line"
304 }
279 }
305
280
306cidr :: TypeInfo
281cidr :: TypeInfo
307−cidr = TypeInfo {
282+cidr = Basic {
308 typoid = Oid 650,
283 typoid = Oid 650,
309 typcategory = 'I',
284 typcategory = 'I',
310 typdelim = ',',
285 typdelim = ',',
311− typelem = Nothing,
312 typname = "cidr"
286 typname = "cidr"
313 }
287 }
314
288
315float4 :: TypeInfo
289float4 :: TypeInfo
316−float4 = TypeInfo {
290+float4 = Basic {
317 typoid = Oid 700,
291 typoid = Oid 700,
318 typcategory = 'N',
292 typcategory = 'N',
319 typdelim = ',',
293 typdelim = ',',
320− typelem = Nothing,
321 typname = "float4"
294 typname = "float4"
322 }
295 }
323
296
324float8 :: TypeInfo
297float8 :: TypeInfo
325−float8 = TypeInfo {
298+float8 = Basic {
326 typoid = Oid 701,
299 typoid = Oid 701,
327 typcategory = 'N',
300 typcategory = 'N',
328 typdelim = ',',
301 typdelim = ',',
329− typelem = Nothing,
330 typname = "float8"
302 typname = "float8"
331 }
303 }
332
304
333abstime :: TypeInfo
305abstime :: TypeInfo
334−abstime = TypeInfo {
306+abstime = Basic {
335 typoid = Oid 702,
307 typoid = Oid 702,
336 typcategory = 'D',
308 typcategory = 'D',
337 typdelim = ',',
309 typdelim = ',',
338− typelem = Nothing,
339 typname = "abstime"
310 typname = "abstime"
340 }
311 }
341
312
342reltime :: TypeInfo
313reltime :: TypeInfo
343−reltime = TypeInfo {
314+reltime = Basic {
344 typoid = Oid 703,
315 typoid = Oid 703,
345 typcategory = 'T',
316 typcategory = 'T',
346 typdelim = ',',
317 typdelim = ',',
347− typelem = Nothing,
348 typname = "reltime"
318 typname = "reltime"
349 }
319 }
350
320
351tinterval :: TypeInfo
321tinterval :: TypeInfo
352−tinterval = TypeInfo {
322+tinterval = Basic {
353 typoid = Oid 704,
323 typoid = Oid 704,
354 typcategory = 'T',
324 typcategory = 'T',
355 typdelim = ',',
325 typdelim = ',',
356− typelem = Nothing,
357 typname = "tinterval"
326 typname = "tinterval"
358 }
327 }
359
328
360unknown :: TypeInfo
329unknown :: TypeInfo
361−unknown = TypeInfo {
330+unknown = Basic {
362 typoid = Oid 705,
331 typoid = Oid 705,
363 typcategory = 'X',
332 typcategory = 'X',
364 typdelim = ',',
333 typdelim = ',',
365− typelem = Nothing,
366 typname = "unknown"
334 typname = "unknown"
367 }
335 }
368
336
369circle :: TypeInfo
337circle :: TypeInfo
370−circle = TypeInfo {
338+circle = Basic {
371 typoid = Oid 718,
339 typoid = Oid 718,
372 typcategory = 'G',
340 typcategory = 'G',
373 typdelim = ',',
341 typdelim = ',',
374− typelem = Nothing,
375 typname = "circle"
342 typname = "circle"
376 }
343 }
377
344
378money :: TypeInfo
345money :: TypeInfo
379−money = TypeInfo {
346+money = Basic {
380 typoid = Oid 790,
347 typoid = Oid 790,
381 typcategory = 'N',
348 typcategory = 'N',
382 typdelim = ',',
349 typdelim = ',',
383− typelem = Nothing,
384 typname = "money"
350 typname = "money"
385 }
351 }
386
352
387macaddr :: TypeInfo
353macaddr :: TypeInfo
388−macaddr = TypeInfo {
354+macaddr = Basic {
389 typoid = Oid 829,
355 typoid = Oid 829,
390 typcategory = 'U',
356 typcategory = 'U',
391 typdelim = ',',
357 typdelim = ',',
392− typelem = Nothing,
393 typname = "macaddr"
358 typname = "macaddr"
394 }
359 }
395
360
396inet :: TypeInfo
361inet :: TypeInfo
397−inet = TypeInfo {
362+inet = Basic {
398 typoid = Oid 869,
363 typoid = Oid 869,
399 typcategory = 'I',
364 typcategory = 'I',
400 typdelim = ',',
365 typdelim = ',',
401− typelem = Nothing,
402 typname = "inet"
366 typname = "inet"
403 }
367 }
404
368
405bpchar :: TypeInfo
369bpchar :: TypeInfo
406−bpchar = TypeInfo {
370+bpchar = Basic {
407 typoid = Oid 1042,
371 typoid = Oid 1042,
408 typcategory = 'S',
372 typcategory = 'S',
409 typdelim = ',',
373 typdelim = ',',
410− typelem = Nothing,
411 typname = "bpchar"
374 typname = "bpchar"
412 }
375 }
413
376
414varchar :: TypeInfo
377varchar :: TypeInfo
415−varchar = TypeInfo {
378+varchar = Basic {
416 typoid = Oid 1043,
379 typoid = Oid 1043,
417 typcategory = 'S',
380 typcategory = 'S',
418 typdelim = ',',
381 typdelim = ',',
419− typelem = Nothing,
420 typname = "varchar"
382 typname = "varchar"
421 }
383 }
422
384
423date :: TypeInfo
385date :: TypeInfo
424−date = TypeInfo {
386+date = Basic {
425 typoid = Oid 1082,
387 typoid = Oid 1082,
426 typcategory = 'D',
388 typcategory = 'D',
427 typdelim = ',',
389 typdelim = ',',
428− typelem = Nothing,
429 typname = "date"
390 typname = "date"
430 }
391 }
431
392
432time :: TypeInfo
393time :: TypeInfo
433−time = TypeInfo {
394+time = Basic {
434 typoid = Oid 1083,
395 typoid = Oid 1083,
435 typcategory = 'D',
396 typcategory = 'D',
436 typdelim = ',',
397 typdelim = ',',
437− typelem = Nothing,
438 typname = "time"
398 typname = "time"
439 }
399 }
440
400
441timestamp :: TypeInfo
401timestamp :: TypeInfo
442−timestamp = TypeInfo {
402+timestamp = Basic {
443 typoid = Oid 1114,
403 typoid = Oid 1114,
444 typcategory = 'D',
404 typcategory = 'D',
445 typdelim = ',',
405 typdelim = ',',
446− typelem = Nothing,
447 typname = "timestamp"
406 typname = "timestamp"
448 }
407 }
449
408
450timestamptz :: TypeInfo
409timestamptz :: TypeInfo
451−timestamptz = TypeInfo {
410+timestamptz = Basic {
452 typoid = Oid 1184,
411 typoid = Oid 1184,
453 typcategory = 'D',
412 typcategory = 'D',
454 typdelim = ',',
413 typdelim = ',',
455− typelem = Nothing,
456 typname = "timestamptz"
414 typname = "timestamptz"
457 }
415 }
458
416
459interval :: TypeInfo
417interval :: TypeInfo
460−interval = TypeInfo {
418+interval = Basic {
461 typoid = Oid 1186,
419 typoid = Oid 1186,
462 typcategory = 'T',
420 typcategory = 'T',
463 typdelim = ',',
421 typdelim = ',',
464− typelem = Nothing,
465 typname = "interval"
422 typname = "interval"
466 }
423 }
467
424
468timetz :: TypeInfo
425timetz :: TypeInfo
469−timetz = TypeInfo {
426+timetz = Basic {
470 typoid = Oid 1266,
427 typoid = Oid 1266,
471 typcategory = 'D',
428 typcategory = 'D',
472 typdelim = ',',
429 typdelim = ',',
473− typelem = Nothing,
474 typname = "timetz"
430 typname = "timetz"
475 }
431 }
476
432
477bit :: TypeInfo
433bit :: TypeInfo
478−bit = TypeInfo {
434+bit = Basic {
479 typoid = Oid 1560,
435 typoid = Oid 1560,
480 typcategory = 'V',
436 typcategory = 'V',
481 typdelim = ',',
437 typdelim = ',',
482− typelem = Nothing,
483 typname = "bit"
438 typname = "bit"
484 }
439 }
485
440
486varbit :: TypeInfo
441varbit :: TypeInfo
487−varbit = TypeInfo {
442+varbit = Basic {
488 typoid = Oid 1562,
443 typoid = Oid 1562,
489 typcategory = 'V',
444 typcategory = 'V',
490 typdelim = ',',
445 typdelim = ',',
491− typelem = Nothing,
492 typname = "varbit"
446 typname = "varbit"
493 }
447 }
494
448
495numeric :: TypeInfo
449numeric :: TypeInfo
496−numeric = TypeInfo {
450+numeric = Basic {
497 typoid = Oid 1700,
451 typoid = Oid 1700,
498 typcategory = 'N',
452 typcategory = 'N',
499 typdelim = ',',
453 typdelim = ',',
500− typelem = Nothing,
501 typname = "numeric"
454 typname = "numeric"
502 }
455 }
503
456
504refcursor :: TypeInfo
457refcursor :: TypeInfo
505−refcursor = TypeInfo {
458+refcursor = Basic {
506 typoid = Oid 1790,
459 typoid = Oid 1790,
507 typcategory = 'U',
460 typcategory = 'U',
508 typdelim = ',',
461 typdelim = ',',
509− typelem = Nothing,
510 typname = "refcursor"
462 typname = "refcursor"
511 }
463 }
512
464
513record :: TypeInfo
465record :: TypeInfo
514−record = TypeInfo {
466+record = Basic {
515 typoid = Oid 2249,
467 typoid = Oid 2249,
516 typcategory = 'P',
468 typcategory = 'P',
517 typdelim = ',',
469 typdelim = ',',
518− typelem = Nothing,
519 typname = "record"
470 typname = "record"
520 }
471 }
521
472
522void :: TypeInfo
473void :: TypeInfo
523−void = TypeInfo {
474+void = Basic {
524 typoid = Oid 2278,
475 typoid = Oid 2278,
525 typcategory = 'P',
476 typcategory = 'P',
526 typdelim = ',',
477 typdelim = ',',
527− typelem = Nothing,
528 typname = "void"
478 typname = "void"
529 }
479 }
530
480
531uuid :: TypeInfo
481uuid :: TypeInfo
532−uuid = TypeInfo {
482+uuid = Basic {
533 typoid = Oid 2950,
483 typoid = Oid 2950,
534 typcategory = 'U',
484 typcategory = 'U',
535 typdelim = ',',
485 typdelim = ',',
536− typelem = Nothing,
537 typname = "uuid"
486 typname = "uuid"
538 }
487 }
src/Database/PostgreSQL/Simple/TypeInfo/Types.hsnew file+30
@@ -0,0 +1,30 @@
1+------------------------------------------------------------------------------
2+-- |
3+-- Module: Database.PostgreSQL.Simple.TypeInfo.Types
4+-- Copyright: (c) 2013 Leon P Smith
5+-- License: BSD3
6+-- Maintainer: Leon P Smith <leon@melding-monads.com>
7+-- Stability: experimental
8+--
9+------------------------------------------------------------------------------
10+
11+module Database.PostgreSQL.Simple.TypeInfo.Types where
12+
13+import Data.ByteString(ByteString)
14+import Database.PostgreSQL.LibPQ(Oid)
15+
16+data TypeInfo
17+
18+ = Basic { typoid :: {-# UNPACK #-} !Oid
19+ , typcategory :: {-# UNPACK #-} !Char
20+ , typdelim :: {-# UNPACK #-} !Char
21+ , typname :: !ByteString
22+ }
23+
24+ | Array { typoid :: {-# UNPACK #-} !Oid
25+ , typcategory :: {-# UNPACK #-} !Char
26+ , typdelim :: {-# UNPACK #-} !Char
27+ , typname :: !ByteString
28+ , typelem :: !TypeInfo
29+ }
30+ deriving (Show)
tools/GenTypeInfo.hs+6−12
@@ -209,6 +209,9 @@ renderFile byOid byName names = ([longstring|
209-- Maintainer: Leon P Smith <leon@melding-monads.com>
209-- Maintainer: Leon P Smith <leon@melding-monads.com>
210-- Stability: experimental
210-- Stability: experimental
211--
211--
212+-- Note that this module is semi-internal, and you probably want to use
213+-- Database.PostgreSQL.Simple.TypeInfo instead.
214+--
212------------------------------------------------------------------------------
215------------------------------------------------------------------------------
213
216
214-- Note that this file is generated by tools/GenTypeInfo.hs, and should
217-- Note that this file is generated by tools/GenTypeInfo.hs, and should
@@ -217,20 +220,12 @@ renderFile byOid byName names = ([longstring|
217module Database.PostgreSQL.Simple.TypeInfo.Static
220module Database.PostgreSQL.Simple.TypeInfo.Static
218 ( TypeInfo(..)
221 ( TypeInfo(..)
219 , staticTypeInfo
222 , staticTypeInfo
220−|] ++ concat [ " , " ++ bs (hs name) ++ "\n"
223+|] ++ concat [ " , " ++ bs (hs name) ++ "\n"
221 | name <- names ] ++ [longstring|
224 | name <- names ] ++ [longstring|
222 ) where
225 ) where
223
226
224−import Data.ByteString (ByteString)
225import Database.PostgreSQL.LibPQ (Oid(..))
227import Database.PostgreSQL.LibPQ (Oid(..))
226−
228+import Database.PostgreSQL.Simple.TypeInfo.Types
227−data TypeInfo = TypeInfo
228− { typoid :: {-# UNPACK #-} !Oid
229− , typcategory :: {-# UNPACK #-} !Char
230− , typdelim :: {-# UNPACK #-} !Char
231− , typelem :: !(Maybe TypeInfo)
232− , typname :: !ByteString
233− }
234
229
235staticTypeInfo :: Oid -> Maybe TypeInfo
230staticTypeInfo :: Oid -> Maybe TypeInfo
236staticTypeInfo (Oid x) = case x of
231staticTypeInfo (Oid x) = case x of
@@ -244,11 +239,10 @@ staticTypeInfo (Oid x) = case x of
244 ++ concat [concat
239 ++ concat [concat
245 [ "\n"
240 [ "\n"
246 , bs (hs name), " :: TypeInfo\n"
241 , bs (hs name), " :: TypeInfo\n"
247− , bs (hs name), " = TypeInfo {\n"
242+ , bs (hs name), " = Basic {\n"
248 , " typoid = ", fromString (show typoid), ",\n"
243 , " typoid = ", fromString (show typoid), ",\n"
249 , " typcategory = '", Blaze.fromChar typcategory, "',\n"
244 , " typcategory = '", Blaze.fromChar typcategory, "',\n"
250 , " typdelim = '", Blaze.fromChar typdelim, "',\n"
245 , " typdelim = '", Blaze.fromChar typdelim, "',\n"
251− , " typelem = ", renderElem byOid typelem, ",\n"
252 , " typname = \"", bs typname, "\"\n"
246 , " typname = \"", bs typname, "\"\n"
253 , " }\n"
247 , " }\n"
254 ]
248 ]