{-# LANGUAGE FlexibleContexts #-}

module Opaleye.Internal.RunQueryExternal
                 (module Opaleye.Internal.RunQueryExternal,
                         -- * Datatypes
                         IRQ.Cursor,
                         IRQ.FromFields,
                         IRQ.FromField,
                         QueryRunner,
                         IRQ.QueryRunnerColumn,
                         IRQ.QueryRunnerColumnDefault,
                         -- * Creating new 'QueryRunnerColumn's
                         IRQ.fieldQueryRunnerColumn,
                         IRQ.fieldParserQueryRunnerColumn) where

import           Control.Applicative (pure, (<$>))
import qualified Database.PostgreSQL.Simple as PGS
import qualified Database.PostgreSQL.Simple.Cursor  as PGSC

import           Opaleye.Column (Column)
import qualified Opaleye.Select as S
import           Opaleye.Internal.RunQuery (QueryRunner, prepareQuery)
import qualified Opaleye.Internal.RunQuery as IRQ

import qualified Data.Profunctor as P
import qualified Data.Profunctor.Product.Default as D

-- * Running 'S.Select's

{-# DEPRECATED runQuery "Use 'Opaleye.RunSelect.runSelect' instead.  @runQuery@ will be removed in 0.8." #-}
runQuery :: D.Default IRQ.FromFields fields haskells
         => PGS.Connection
         -> S.Select fields
         -> IO [haskells]
runQuery :: Connection -> Select fields -> IO [haskells]
runQuery = FromFields fields haskells
-> Connection -> Select fields -> IO [haskells]
forall fields haskells.
FromFields fields haskells
-> Connection -> Select fields -> IO [haskells]
runQueryExplicit FromFields fields haskells
forall (p :: * -> * -> *) a b. Default p a b => p a b
D.def

{-# DEPRECATED runQueryFold "Use 'Opaleye.RunSelect.runSelectFold' instead.  @runQueryFold@ will be removed in 0.8." #-}
runQueryFold
  :: D.Default IRQ.FromFields fields haskells
  => PGS.Connection
  -> S.Select fields
  -> b
  -> (b -> haskells -> IO b)
  -> IO b
runQueryFold :: Connection -> Select fields -> b -> (b -> haskells -> IO b) -> IO b
runQueryFold = FromFields fields haskells
-> Connection
-> Select fields
-> b
-> (b -> haskells -> IO b)
-> IO b
forall fields haskells b.
FromFields fields haskells
-> Connection
-> Select fields
-> b
-> (b -> haskells -> IO b)
-> IO b
runQueryFoldExplicit FromFields fields haskells
forall (p :: * -> * -> *) a b. Default p a b => p a b
D.def

-- * Creating new 'QueryRunnerColumn's

{-# DEPRECATED queryRunnerColumn "Use 'Opaleye.RunSelect.unsafeFromField' instead. @queryRunnerColumn@ will be removed in 0.8." #-}
queryRunnerColumn :: (Column a' -> Column a) -> (b -> b')
                  -> IRQ.FromField a b -> IRQ.FromField a' b'
queryRunnerColumn :: (Column a' -> Column a)
-> (b -> b') -> FromField a b -> FromField a' b'
queryRunnerColumn Column a' -> Column a
colF b -> b'
haskellF FromField a b
qrc = Unpackspec (Column a') () -> FieldParser b' -> FromField a' b'
forall pgType haskellType.
Unpackspec (Column pgType) ()
-> FieldParser haskellType -> FromField pgType haskellType
IRQ.QueryRunnerColumn ((Column a' -> Column a)
-> Unpackspec (Column a) () -> Unpackspec (Column a') ()
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
P.lmap Column a' -> Column a
colF Unpackspec (Column a) ()
u)
                                                            ((b -> b')
-> (Field -> Maybe ByteString -> Conversion b) -> FieldParser b'
forall a b.
(a -> b)
-> (Field -> Maybe ByteString -> Conversion a)
-> Field
-> Maybe ByteString
-> Conversion b
fmapFP b -> b'
haskellF Field -> Maybe ByteString -> Conversion b
fp)
  where IRQ.QueryRunnerColumn Unpackspec (Column a) ()
u Field -> Maybe ByteString -> Conversion b
fp = FromField a b
qrc
        fmapFP :: (a -> b)
-> (Field -> Maybe ByteString -> Conversion a)
-> Field
-> Maybe ByteString
-> Conversion b
fmapFP = ((Maybe ByteString -> Conversion a)
 -> Maybe ByteString -> Conversion b)
-> (Field -> Maybe ByteString -> Conversion a)
-> Field
-> Maybe ByteString
-> Conversion b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Maybe ByteString -> Conversion a)
  -> Maybe ByteString -> Conversion b)
 -> (Field -> Maybe ByteString -> Conversion a)
 -> Field
 -> Maybe ByteString
 -> Conversion b)
-> ((a -> b)
    -> (Maybe ByteString -> Conversion a)
    -> Maybe ByteString
    -> Conversion b)
-> (a -> b)
-> (Field -> Maybe ByteString -> Conversion a)
-> Field
-> Maybe ByteString
-> Conversion b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Conversion a -> Conversion b)
-> (Maybe ByteString -> Conversion a)
-> Maybe ByteString
-> Conversion b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Conversion a -> Conversion b)
 -> (Maybe ByteString -> Conversion a)
 -> Maybe ByteString
 -> Conversion b)
-> ((a -> b) -> Conversion a -> Conversion b)
-> (a -> b)
-> (Maybe ByteString -> Conversion a)
-> Maybe ByteString
-> Conversion b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> Conversion a -> Conversion b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

-- * Explicit versions

{-# DEPRECATED runQueryExplicit "Use 'Opaleye.RunSelect.runSelectExplict' instead.  Will be removed in 0.8." #-}
runQueryExplicit :: IRQ.FromFields fields haskells
                 -> PGS.Connection
                 -> S.Select fields
                 -> IO [haskells]
runQueryExplicit :: FromFields fields haskells
-> Connection -> Select fields -> IO [haskells]
runQueryExplicit FromFields fields haskells
qr Connection
conn Select fields
q = IO [haskells]
-> (Query -> IO [haskells]) -> Maybe Query -> IO [haskells]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([haskells] -> IO [haskells]
forall (m :: * -> *) a. Monad m => a -> m a
return []) (RowParser haskells -> Connection -> Query -> IO [haskells]
forall r. RowParser r -> Connection -> Query -> IO [r]
PGS.queryWith_ RowParser haskells
parser Connection
conn) Maybe Query
sql
  where (Maybe Query
sql, RowParser haskells
parser) = FromFields fields haskells
-> Select fields -> (Maybe Query, RowParser haskells)
forall fields haskells.
FromFields fields haskells
-> Select fields -> (Maybe Query, RowParser haskells)
IRQ.prepareQuery FromFields fields haskells
qr Select fields
q

{-# DEPRECATED runQueryFoldExplicit "Use 'Opaleye.RunSelect.runSelectFoldExplict' instead.  Will be deprecated in 0.8." #-}
runQueryFoldExplicit
  :: IRQ.FromFields fields haskells
  -> PGS.Connection
  -> S.Select fields
  -> b
  -> (b -> haskells -> IO b)
  -> IO b
runQueryFoldExplicit :: FromFields fields haskells
-> Connection
-> Select fields
-> b
-> (b -> haskells -> IO b)
-> IO b
runQueryFoldExplicit FromFields fields haskells
qr Connection
conn Select fields
q b
z b -> haskells -> IO b
f = case Maybe Query
sql of
  Maybe Query
Nothing   -> b -> IO b
forall (m :: * -> *) a. Monad m => a -> m a
return b
z
  Just Query
sql' -> RowParser haskells
-> Connection -> Query -> b -> (b -> haskells -> IO b) -> IO b
forall r a.
RowParser r -> Connection -> Query -> a -> (a -> r -> IO a) -> IO a
PGS.foldWith_ RowParser haskells
parser Connection
conn Query
sql' b
z b -> haskells -> IO b
f
  where (Maybe Query
sql, RowParser haskells
parser) = FromFields fields haskells
-> Select fields -> (Maybe Query, RowParser haskells)
forall fields haskells.
FromFields fields haskells
-> Select fields -> (Maybe Query, RowParser haskells)
prepareQuery FromFields fields haskells
qr Select fields
q

-- * Cursor interface

{-# DEPRECATED declareCursor "Use 'Opaleye.RunSelect.declareCursor' instead.  Will be removed in 0.8." #-}
declareCursor
    :: D.Default IRQ.FromFields fields haskells
    => PGS.Connection
    -> S.Select fields
    -> IO (IRQ.Cursor haskells)
declareCursor :: Connection -> Select fields -> IO (Cursor haskells)
declareCursor = FromFields fields haskells
-> Connection -> Select fields -> IO (Cursor haskells)
forall fields haskells.
FromFields fields haskells
-> Connection -> Select fields -> IO (Cursor haskells)
declareCursorExplicit FromFields fields haskells
forall (p :: * -> * -> *) a b. Default p a b => p a b
D.def

{-# DEPRECATED declareCursorExplicit "Use 'Opaleye.RunSelect.declareCursorExplicit' instead.  Will be removed in 0.8." #-}
declareCursorExplicit
    :: IRQ.FromFields fields haskells
    -> PGS.Connection
    -> S.Select fields
    -> IO (IRQ.Cursor haskells)
declareCursorExplicit :: FromFields fields haskells
-> Connection -> Select fields -> IO (Cursor haskells)
declareCursorExplicit FromFields fields haskells
qr Connection
conn Select fields
q =
    case Maybe Query
mbQuery of
      Maybe Query
Nothing    -> Cursor haskells -> IO (Cursor haskells)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Cursor haskells
forall haskells. Cursor haskells
IRQ.EmptyCursor
      Just Query
query -> RowParser haskells -> Cursor -> Cursor haskells
forall haskells. RowParser haskells -> Cursor -> Cursor haskells
IRQ.Cursor RowParser haskells
rowParser (Cursor -> Cursor haskells) -> IO Cursor -> IO (Cursor haskells)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Connection -> Query -> IO Cursor
PGSC.declareCursor Connection
conn Query
query
  where
    (Maybe Query
mbQuery, RowParser haskells
rowParser) = FromFields fields haskells
-> Select fields -> (Maybe Query, RowParser haskells)
forall fields haskells.
FromFields fields haskells
-> Select fields -> (Maybe Query, RowParser haskells)
prepareQuery FromFields fields haskells
qr Select fields
q

{-# DEPRECATED closeCursor "Use 'Opaleye.RunSelect.closeCursor' instead.  Will be removed in 0.8." #-}
closeCursor :: IRQ.Cursor fields -> IO ()
closeCursor :: Cursor fields -> IO ()
closeCursor Cursor fields
IRQ.EmptyCursor       = () -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
closeCursor (IRQ.Cursor RowParser fields
_ Cursor
cursor) = Cursor -> IO ()
PGSC.closeCursor Cursor
cursor

{-# DEPRECATED foldForward "Use 'Opaleye.RunSelect.foldForward' instead.  Will be removed in 0.8." #-}
foldForward
    :: IRQ.Cursor haskells
    -> Int
    -> (a -> haskells -> IO a)
    -> a
    -> IO (Either a a)
foldForward :: Cursor haskells
-> Int -> (a -> haskells -> IO a) -> a -> IO (Either a a)
foldForward Cursor haskells
IRQ.EmptyCursor              Int
_chunkSize a -> haskells -> IO a
_f a
z = Either a a -> IO (Either a a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either a a -> IO (Either a a)) -> Either a a -> IO (Either a a)
forall a b. (a -> b) -> a -> b
$ a -> Either a a
forall a b. a -> Either a b
Left a
z
foldForward (IRQ.Cursor RowParser haskells
rowParser Cursor
cursor) Int
chunkSize  a -> haskells -> IO a
f a
z =
    Cursor
-> RowParser haskells
-> Int
-> (a -> haskells -> IO a)
-> a
-> IO (Either a a)
forall r a.
Cursor
-> RowParser r -> Int -> (a -> r -> IO a) -> a -> IO (Either a a)
PGSC.foldForwardWithParser Cursor
cursor RowParser haskells
rowParser Int
chunkSize a -> haskells -> IO a
f a
z