git.iko.soy/typeable/postgresql-simple
on master help sign in
Support for Bytea results
commit1d5a62255b6e14545c2beea7b8a86377b2fcf24f authorLeon P Smith <leon@melding-monads.com> dateTue 27 Dec 2011, 23:44 (15 years ago) parent293b157
1 file changed+25−3
src/Database/PostgreSQL/Simple/Result.hs+25−3
src/Database/PostgreSQL/Simple/Result.hs+25−3
@@ -48,7 +48,9 @@ import Data.Word (Word64)
4848import Database.PostgreSQL.Simple.Internal
4949import Database.PostgreSQL.Simple.Field (Field(..), RawResult(..))
5050import Database.PostgreSQL.Simple.BuiltinTypes
51+import Database.PostgreSQL.Simple.Types (Binary(..))
5152import qualified Database.PostgreSQL.LibPQ as PQ
53+import System.IO.Unsafe (unsafePerformIO)
5254import System.Locale (defaultTimeLocale)
5355import qualified Data.ByteString as SB
5456import qualified Data.ByteString.Char8 as B8
@@ -135,8 +137,13 @@ instance Result (Ratio Integer) where
135137 where ok = mkCompats [Float,Double,Decimal,NewDecimal,Tiny,Short,Int24,
136138 Long,LongLong]
137139--}
140+
141+unBinary (Binary x) = x
142+
138143instance Result SB.ByteString where
139− convert f = doConvert f okText $ pure
144+ convert f dat = if typeOid f == builtin2oid Bytea
145+ then unBinary <$> convert f dat
146+ else doConvert f okText' pure dat
140147
141148instance Result PQ.Oid where
142149 convert f dat = PQ.Oid <$> atto (mkCompat Oid) decimal f dat
@@ -144,6 +151,19 @@ instance Result PQ.Oid where
144151instance Result LB.ByteString where
145152 convert f dat = LB.fromChunks . (:[]) <$> convert f dat
146153
154+unescapeBytea :: Field -> SB.ByteString
155+ -> Either SomeException (Binary SB.ByteString)
156+unescapeBytea f str = case unsafePerformIO (PQ.unescapeBytea str) of
157+ Nothing -> returnError ConversionFailed f "unescapeBytea failed"
158+ Just str -> pure (Binary str)
159+
160+instance Result (Binary SB.ByteString) where
161+ convert f dat = case format f of
162+ PQ.Text -> doConvert f okBinary (unescapeBytea f) dat
163+ PQ.Binary -> doConvert f okBinary (pure . Binary) dat
164+
165+instance Result (Binary LB.ByteString) where
166+ convert f dat = Binary . LB.fromChunks . (:[]) . unBinary <$> convert f dat
147167
148168instance Result ST.Text where
149169 convert f = doConvert f okText $ (either left Right . ST.decodeUtf8')
@@ -200,8 +220,10 @@ mkCompat = Compat . shiftL 1 . fromEnum
200220compat :: Compat -> Compat -> Bool
201221compat (Compat a) (Compat b) = a .&. b /= 0
202222
203−okText, ok16, ok32, ok64 :: Compat
204−okText = mkCompats [Name,Text,Char,Bpchar,Varchar]
223+okText, okText', ok16, ok32, ok64 :: Compat
224+okText = mkCompats [Name,Text,Char,Bpchar,Varchar]
225+okText' = mkCompats [Name,Text,Char,Bpchar,Varchar,Unknown]
226+okBinary = mkCompats [Bytea]
205227ok16 = mkCompats [Int2]
206228ok32 = mkCompats [Int2,Int4]
207229ok64 = mkCompats [Int2,Int4,Int8]