@@ -73,7 +73,9 @@ module Database.PostgreSQL.Simple.FromField
75 , typename
75 , typename
76− , typeinfo
76+ , TypeInfo(..)
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.
181typename :: Field -> Conversion ByteString
182typename :: Field -> Conversion ByteString
182−typename field = typname . typ <$> typeinfo field
183+typename field = typname <$> typeInfo field
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)
189+typeInfoByOid :: PQ.Oid -> Conversion TypeInfo
190+typeInfoByOid oid = Conversion $ \conn -> do
191+ Ok <$> (getTypeInfo conn oid)
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.
@@ -205,7 +210,7 @@ tableOid Field{..} = toMaybeOid (unsafeDupablePerformIO (PQ.ftable result column
205 else Just x
210 else Just x
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@.
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)
354instance (FromField a, Typeable a) => FromField (Vector a) where
359instance (FromField a, Typeable a) => FromField (Vector a) where
360+ fromField f mdat = do
365+ Nothing -> returnError UnexpectedNull f ""
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 ""
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
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
364newtype Compat = Compat Word64
382newtype Compat = Compat Word64