module Database.PostgreSQL.Simple.QueryResults
(
QueryResults(..)
, convertError
) where
import Control.Exception (SomeException(..), throw)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B
import Data.Either()
import Database.PostgreSQL.Simple.Internal
import Database.PostgreSQL.Simple.Result (ResultError(..), Result(..))
import Database.PostgreSQL.Simple.Types (Only(..))
class QueryResults a where
convertResults :: [Field] -> [Maybe ByteString] -> Either SomeException a
instance (Result a) => QueryResults (Only a) where
convertResults [fa] [va] = do
!a <- convert fa va
return (Only a)
convertResults fs vs = convertError fs vs 1
instance (Result a, Result b) => QueryResults (a,b) where
convertResults [fa,fb] [va,vb] = do
!a <- convert fa va
!b <- convert fb vb
return (a,b)
convertResults fs vs = convertError fs vs 2
instance (Result a, Result b, Result c) => QueryResults (a,b,c) where
convertResults [fa,fb,fc] [va,vb,vc] = do
!a <- convert fa va
!b <- convert fb vb
!c <- convert fc vc
return (a,b,c)
convertResults fs vs = convertError fs vs 3
instance (Result a, Result b, Result c, Result d) =>
QueryResults (a,b,c,d) where
convertResults [fa,fb,fc,fd] [va,vb,vc,vd] = do
!a <- convert fa va
!b <- convert fb vb
!c <- convert fc vc
!d <- convert fd vd
return (a,b,c,d)
convertResults fs vs = convertError fs vs 4
instance (Result a, Result b, Result c, Result d, Result e) =>
QueryResults (a,b,c,d,e) where
convertResults [fa,fb,fc,fd,fe] [va,vb,vc,vd,ve] = do
!a <- convert fa va
!b <- convert fb vb
!c <- convert fc vc
!d <- convert fd vd
!e <- convert fe ve
return (a,b,c,d,e)
convertResults fs vs = convertError fs vs 5
instance (Result a, Result b, Result c, Result d, Result e, Result f) =>
QueryResults (a,b,c,d,e,f) where
convertResults [fa,fb,fc,fd,fe,ff] [va,vb,vc,vd,ve,vf] = do
!a <- convert fa va
!b <- convert fb vb
!c <- convert fc vc
!d <- convert fd vd
!e <- convert fe ve
!f <- convert ff vf
return (a,b,c,d,e,f)
convertResults fs vs = convertError fs vs 6
instance (Result a, Result b, Result c, Result d, Result e, Result f,
Result g) =>
QueryResults (a,b,c,d,e,f,g) where
convertResults [fa,fb,fc,fd,fe,ff,fg] [va,vb,vc,vd,ve,vf,vg] = do
!a <- convert fa va
!b <- convert fb vb
!c <- convert fc vc
!d <- convert fd vd
!e <- convert fe ve
!f <- convert ff vf
!g <- convert fg vg
return (a,b,c,d,e,f,g)
convertResults fs vs = convertError fs vs 7
instance (Result a, Result b, Result c, Result d, Result e, Result f,
Result g, Result h) =>
QueryResults (a,b,c,d,e,f,g,h) where
convertResults [fa,fb,fc,fd,fe,ff,fg,fh] [va,vb,vc,vd,ve,vf,vg,vh] = do
!a <- convert fa va
!b <- convert fb vb
!c <- convert fc vc
!d <- convert fd vd
!e <- convert fe ve
!f <- convert ff vf
!g <- convert fg vg
!h <- convert fh vh
return (a,b,c,d,e,f,g,h)
convertResults fs vs = convertError fs vs 8
instance (Result a, Result b, Result c, Result d, Result e, Result f,
Result g, Result h, Result i) =>
QueryResults (a,b,c,d,e,f,g,h,i) where
convertResults [fa,fb,fc,fd,fe,ff,fg,fh,fi] [va,vb,vc,vd,ve,vf,vg,vh,vi] =
do
!a <- convert fa va
!b <- convert fb vb
!c <- convert fc vc
!d <- convert fd vd
!e <- convert fe ve
!f <- convert ff vf
!g <- convert fg vg
!h <- convert fh vh
!i <- convert fi vi
return (a,b,c,d,e,f,g,h,i)
convertResults fs vs = convertError fs vs 9
instance (Result a, Result b, Result c, Result d, Result e, Result f,
Result g, Result h, Result i, Result j) =>
QueryResults (a,b,c,d,e,f,g,h,i,j) where
convertResults [fa,fb,fc,fd,fe,ff,fg,fh,fi,fj]
[va,vb,vc,vd,ve,vf,vg,vh,vi,vj] =
do
!a <- convert fa va
!b <- convert fb vb
!c <- convert fc vc
!d <- convert fd vd
!e <- convert fe ve
!f <- convert ff vf
!g <- convert fg vg
!h <- convert fh vh
!i <- convert fi vi
!j <- convert fj vj
return (a,b,c,d,e,f,g,h,i,j)
convertResults fs vs = convertError fs vs 10
convertError :: [Field]
-> [Maybe ByteString]
-> Int
-> Either SomeException a
convertError fs vs n = Left . SomeException $ ConversionFailed
(show (length fs) ++ " values: " ++ show (zip (map typename fs)
(map (fmap ellipsis) vs)))
(show n ++ " slots in target type")
"mismatch between number of columns to convert and number in target type"
ellipsis :: ByteString -> ByteString
ellipsis bs
| B.length bs > 15 = B.take 10 bs `B.append` "[...]"
| otherwise = bs