@@ -0,0 +1,162 @@
1+{-# LANGUAGE RecordWildCards, BangPatterns #-}
2+
3+module Database.PostgreSQL.Simple.FromRow
4+ ( FromRow(..)
5+ , RowParser
6+ , field
7+ , numFieldsRemaining
8+ ) where
9+
10+import Control.Applicative (Applicative(..), (<$>))
11+import Control.Exception (SomeException(..), throw)
12+import Control.Monad (replicateM)
13+import Data.ByteString (ByteString)
14+import qualified Data.ByteString.Char8 as B
15+import Database.PostgreSQL.Simple.Internal
16+import Database.PostgreSQL.Simple.Result (ResultError(..), Result(..))
17+import Database.PostgreSQL.Simple.Types (Only(..))
18+import Database.PostgreSQL.Simple.Ok
19+import qualified Database.PostgreSQL.LibPQ as PQ
20+import Database.PostgreSQL.Simple.Internal
21+import Database.PostgreSQL.Simple.FromField
22+
23+import Control.Monad.Trans.State.Strict
24+import Control.Monad.Trans.Reader
25+import Control.Monad.Trans.Class
26+
27+import Data.Vector ((!))
28+
29+import System.IO.Unsafe ( unsafePerformIO )
30+
31+class FromRow a where
32+ fromRow :: RowParser a
33+
34+field :: FromField a => RowParser a
35+field = RP $ do
36+ Row{..} <- ask
37+ column <- lift get
38+ lift (put (column + 1))
39+ let typename = typenames ! (\(PQ.Col x) -> fromIntegral x) column
40+ result = rowresult
41+ field = Field{..}
42+ if (column > nfields rowresult) then lift (lift (Errors [])) else return ()
43+ lift (lift (fromField field (getvalue result row column)))
44+
45+numFieldsRemaining :: RowParser Int
46+numFieldsRemaining = RP $ do
47+ Row{..} <- ask
48+ column <- lift get
49+ return $! (\(PQ.Col x) -> fromIntegral x) (nfields rowresult - column)
50+
51+
52+instance (FromField a) => FromRow (Only a) where
53+ fromRow = do
54+ !a <- field
55+ return (Only a)
56+
57+instance (FromField a, FromField b) => FromRow (a,b) where
58+ fromRow = do
59+ !a <- field
60+ !b <- field
61+ return (a,b)
62+
63+instance (FromField a, FromField b, FromField c) => FromRow (a,b,c) where
64+ fromRow = do
65+ !a <- field
66+ !b <- field
67+ !c <- field
68+ return (a,b,c)
69+
70+instance (FromField a, FromField b, FromField c, FromField d) =>
71+ FromRow (a,b,c,d) where
72+ fromRow = do
73+ !a <- field
74+ !b <- field
75+ !c <- field
76+ !d <- field
77+ return (a,b,c,d)
78+
79+instance (FromField a, FromField b, FromField c, FromField d, FromField e) =>
80+ FromRow (a,b,c,d,e) where
81+ fromRow = do
82+ !a <- field
83+ !b <- field
84+ !c <- field
85+ !d <- field
86+ !e <- field
87+ return (a,b,c,d,e)
88+
89+instance (FromField a, FromField b, FromField c, FromField d, FromField e,
90+ FromField f) =>
91+ FromRow (a,b,c,d,e,f) where
92+ fromRow = do
93+ !a <- field
94+ !b <- field
95+ !c <- field
96+ !d <- field
97+ !e <- field
98+ !f <- field
99+ return (a,b,c,d,e,f)
100+
101+instance (FromField a, FromField b, FromField c, FromField d, FromField e,
102+ FromField f, FromField g) =>
103+ FromRow (a,b,c,d,e,f,g) where
104+ fromRow = do
105+ !a <- field
106+ !b <- field
107+ !c <- field
108+ !d <- field
109+ !e <- field
110+ !f <- field
111+ !g <- field
112+ return (a,b,c,d,e,f,g)
113+
114+instance (FromField a, FromField b, FromField c, FromField d, FromField e,
115+ FromField f, FromField g, FromField h) =>
116+ FromRow (a,b,c,d,e,f,g,h) where
117+ fromRow = do
118+ !a <- field
119+ !b <- field
120+ !c <- field
121+ !d <- field
122+ !e <- field
123+ !f <- field
124+ !g <- field
125+ !h <- field
126+ return (a,b,c,d,e,f,g,h)
127+
128+instance (FromField a, FromField b, FromField c, FromField d, FromField e,
129+ FromField f, FromField g, FromField h, FromField i) =>
130+ FromRow (a,b,c,d,e,f,g,h,i) where
131+ fromRow = do
132+ !a <- field
133+ !b <- field
134+ !c <- field
135+ !d <- field
136+ !e <- field
137+ !f <- field
138+ !g <- field
139+ !h <- field
140+ !i <- field
141+ return (a,b,c,d,e,f,g,h,i)
142+
143+instance (FromField a, FromField b, FromField c, FromField d, FromField e,
144+ FromField f, FromField g, FromField h, FromField i, FromField j) =>
145+ FromRow (a,b,c,d,e,f,g,h,i,j) where
146+ fromRow = do
147+ !a <- field
148+ !b <- field
149+ !c <- field
150+ !d <- field
151+ !e <- field
152+ !f <- field
153+ !g <- field
154+ !h <- field
155+ !i <- field
156+ !j <- field
157+ return (a,b,c,d,e,f,g,h,i,j)
158+
159+instance FromField a => FromRow [a] where
160+ fromRow = do
161+ n <- numFieldsRemaining
162+ replicateM n field