@@ -20,13 +20,15 @@ module Squeel.PostgreSQL.PQ where
2020
2121import Control.Exception.Lifted
2222import Control.Monad.Base
23−import Control.Monad.Trans
23+import Control.Monad.Except
24+import Control.Monad.Trans.Maybe
2425import Control.Monad.Trans.Control
2526import Data.ByteString (ByteString)
27+import Data.Maybe
2628import Data.Proxy (Proxy)
2729import Data.Text (Text)
2830import Generics.SOP
29−import GHC.Exts
31+import GHC.Exts hiding (fromList)
3032import GHC.TypeLits
3133
3234import qualified Database.PostgreSQL.LibPQ as LibPQ
@@ -205,19 +207,44 @@ colNum4 :: ColumnNumber (c0:c1:c2:c3:c4:cs) c4
205207colNum4 = colNum (proxy# :: Proxy# 4)
206208
207209newtype Value pgs m x = Value { runValue :: Result pgs -> m x }
210+ deriving (Functor)
211+instance Applicative m => Applicative (Value pgs m) where
212+ pure x = Value $ \ _result -> pure x
213+ mf <*> mx = Value $ \ result -> runValue mf result <*> runValue mx result
214+instance Monad m => Monad (Value pgs m) where
215+ return = pure
216+ mx >>= f = Value $ \ result -> do
217+ x <- runValue mx result
218+ runValue (f x) result
219+instance MonadTrans (Value pgs) where
220+ lift m = Value $ \ _result -> m
221+instance MonadBase b m => MonadBase b (Value pgs m) where
222+ liftBase = lift . liftBase
208223
209−-- getValue
210−-- :: (HasDecoding pg x, MonadBase IO io)
211−-- => RowNumber
212−-- -> ColumnNumber pgs pg
213−-- -> Value pgs (ExceptT Text (MaybeT io)) x
214−
215−getvalue
216− :: (HasDecoding x y, MonadBase IO io)
217− => Result xs
218− -> RowNumber
219− -> ColumnNumber xs x
220− -> io (Maybe (Either Text y))
221−getvalue (Result result) (RowNumber r) (ColumnNumber c :: ColumnNumber xs x) =
222− liftBase $ fmap (fmap (decodeValue (Proxy :: Proxy x)))
223− (LibPQ.getvalue' result r c)
224+getValue
225+ :: (HasDecoding pg x, MonadBase IO io)
226+ => RowNumber
227+ -> ColumnNumber pgs pg
228+ -> Value pgs (ExceptT Text (MaybeT io)) x
229+getValue (RowNumber r) (ColumnNumber c :: ColumnNumber pgs pg) =
230+ Value $ \ (Result result) -> do
231+ maybeBytestring <- liftBase $ LibPQ.getvalue result r c
232+ case maybeBytestring of
233+ Nothing -> mzero
234+ Just bytestring -> case decodeValue (Proxy :: Proxy pg) bytestring of
235+ Left err -> throwError err
236+ Right val -> return val
237+
238+getRow
239+ :: (AllZip HasDecoding pgs xs, MonadBase IO io)
240+ => RowNumber
241+ -> proxy pgs
242+ -> Value pgs (ExceptT Text (MaybeT io)) (NP I xs)
243+getRow (RowNumber r) (_ :: proxy pgs) = Value $ \ (Result result) -> do
244+ maybeBytestrings <- traverse (liftBase . LibPQ.getvalue result r)
245+ [1 .. fromIntegral (lengthSList (Proxy :: Proxy pgs))]
246+ case fromList (catMaybes maybeBytestrings) of
247+ Nothing -> mzero
248+ Just bytestrings -> case decodings (Proxy :: Proxy pgs) bytestrings of
249+ Left err -> throwError err
250+ Right row -> return row