{-# LANGUAGE UndecidableInstances #-}

-- | File-mode @COPY@: the data lives on the database server's filesystem.
--
-- For the variant that streams data through the client connection instead, see
-- "Database.Beam.Backend.SQL.BeamExtensions.Copy.Stream".
module Database.Beam.Backend.SQL.BeamExtensions.Copy.File
  ( -- * Building a COPY statement
    copyTableTo,
    copySelectTo,
    SqlCopyTo (..),
    copyTableFrom,
    SqlCopyFrom (..),

    -- * Source-syntax classes (shared with streaming COPY)
    IsSqlCopyToSourceSyntax (..),
    IsSqlCopyFromSourceSyntax (..),

    -- * File-mode statement-level syntax classes
    IsSqlCopyToSyntax (..),
    IsSqlCopyFromSyntax (..),
    BeamSqlBackendCopyToSyntax,
    BeamSqlBackendCopyFromSyntax,

    -- * Runner classes
    MonadBeamCopyTo (..),
    MonadBeamCopyFrom (..),

    -- * Internal — exposed for use by sibling modules
    projection,
  )
where

import Control.Monad.Cont (ContT)
import Control.Monad.Except (ExceptT)
import qualified Control.Monad.RWS.Lazy as Lazy
import qualified Control.Monad.RWS.Strict as Strict
import Control.Monad.Reader (ReaderT)
import qualified Control.Monad.State.Lazy as Lazy
import qualified Control.Monad.State.Strict as Strict
import Control.Monad.Trans (lift)
import qualified Control.Monad.Writer.Lazy as Lazy
import qualified Control.Monad.Writer.Strict as Strict
import Data.Data (Proxy (..))
import Data.Kind (Type)
import Data.List.NonEmpty (NonEmpty, nonEmpty)
import Data.Text (Text)
import Database.Beam.Backend.SQL (BeamSqlBackendSelectSyntax, MonadBeam (..))
import Database.Beam.Query (QField, SqlSelect (..))
import Database.Beam.Query.Internal (AnyType, ProjectibleWithPredicate, QField (..), project')
import Database.Beam.Schema (TableEntity)
import Database.Beam.Schema.Tables
  ( Beamable,
    Columnar' (..),
    DatabaseEntity (..),
    DatabaseEntityDescriptor (DatabaseTable, dbTableSettings),
    IsDatabaseEntity (dbEntityName, dbEntitySchema),
    changeBeamRep,
    fieldName,
  )
import Lens.Micro ((^.))

-- | This class allows to express the source of a `COPY ... TO` statement.
-- The options are either from a table (with a possible projection),
-- or from the result of a select query.
--
-- Reused by both file-mode and streaming COPY: the source shape (a table or
-- a @SELECT@) is the same regardless of where the data ends up.
class IsSqlCopyToSourceSyntax syntax where
  -- | Expected to be equal to `BeamSqlBackendSelectSyntax be`
  type SqlCopyToSourceSelectSyntax syntax :: Type

  -- Copy an entire table, perhaps with some column projections
  copyTableToSyntax ::
    Maybe Text -> -- schema (Nothing = default search path)
    Text -> -- table name
    Maybe (NonEmpty Text) -> -- column list; `Nothing` means "all columns"
    syntax

  -- Copy the result of a select statement
  copySelectToSyntax ::
    SqlCopyToSourceSelectSyntax syntax ->
    syntax

-- | This class allows to express the source of a `COPY ... FROM` statement.
-- Reused by both file-mode and streaming COPY.
class IsSqlCopyFromSourceSyntax syntax where
  -- Copy data into a table, perhaps with some column projections
  copyTableFromSyntax ::
    Maybe Text -> -- schema (Nothing = default search path)
    Text -> -- table name
    Maybe (NonEmpty Text) -> -- column list; `Nothing` means "all columns"
    syntax

-- | Statement-level syntax for backends that support @COPY ... TO@ file.
class (IsSqlCopyToSourceSyntax (SqlCopyToSourceSyntax cmd)) => IsSqlCopyToSyntax cmd where
  -- | The syntax for the source of the copy. For example, in Postgres,
  --  this can be either a table (and optional projection), or a select statement.
  type SqlCopyToSourceSyntax cmd :: Type

  -- | All backend-specific options which determine HOW the copy is performed,
  --  including the destination of the data (e.g. a filepath).
  type SqlCopyToParams cmd :: Type

  -- | Combine a source and a parameters value into a complete
  -- @COPY ... TO ...@ statement.
  copyToStmt ::
    SqlCopyToSourceSyntax cmd ->
    SqlCopyToParams cmd ->
    cmd

-- | Statement-level syntax for backends that support file-mode @COPY ... FROM@ file.
--
-- Symmetric to 'IsSqlCopyToSyntax', but the data flows in the opposite
-- direction: the params value supplies the source path and any
-- format-specific options.
class (IsSqlCopyFromSourceSyntax (SqlCopyFromSourceSyntax cmd)) => IsSqlCopyFromSyntax cmd where
  -- | The syntax for the destination table of the copy.
  type SqlCopyFromSourceSyntax cmd :: Type

  -- | All backend-specific options which determine HOW the copy is performed,
  --  including the source of the data (e.g. a filepath).
  type SqlCopyFromParams cmd :: Type

  -- | Combine a destination and a parameters value into a complete
  -- @COPY ... FROM ...@ statement.
  copyFromStmt ::
    SqlCopyFromSourceSyntax cmd ->
    SqlCopyFromParams cmd ->
    cmd

-- | Type-family selector for the backend's file-mode @COPY ... TO@ syntax.
-- A backend instance binds this to the concrete syntax type that implements
-- 'IsSqlCopyToSyntax'.
type family BeamSqlBackendCopyToSyntax be :: Type

-- | Type-family selector for the backend's file-mode @COPY ... FROM@ syntax.
-- See 'BeamSqlBackendCopyToSyntax'.
type family BeamSqlBackendCopyFromSyntax be :: Type

-- | A built file-mode @COPY ... TO@ statement, ready to be executed by
-- 'runCopyTo'. Construct via 'copyTableTo' or 'copySelectTo'; the @table@
-- and @proj@ phantom parameters track which table the statement applies to
-- and which columns it projects.
data SqlCopyTo be a
  = SqlCopyTo !(BeamSqlBackendCopyToSyntax be)
  | -- | A projection covering zero columns. 'runCopyTo' should treat this as a
    --    no-op rather than emit an empty @COPY tbl () TO ...@ statement.
    SqlCopyToNoColumns

-- | A built file-mode @COPY ... FROM@ statement, ready to be executed by
-- 'runCopyFrom'. Construct via 'copyTableFrom'.
data SqlCopyFrom be a
  = SqlCopyFrom !(BeamSqlBackendCopyFromSyntax be)
  | -- | A projection covering zero columns. 'runCopyFrom' should treat this as
    --    a no-op rather than emit an empty @COPY tbl () FROM ...@ statement.
    SqlCopyFromNoColumns

-- | Express the copy from a table, to a destination (typically a file).
--
-- To copy the result of a @SELECT@ query instead, see `copySelectTo`.
--
-- @since 0.11.1.0
copyTableTo ::
  ( IsSqlCopyToSyntax (BeamSqlBackendCopyToSyntax be),
    ProjectibleWithPredicate AnyType () Text proj
  ) =>
  DatabaseEntity be db (TableEntity table) ->
  -- | Projection from table to columns. If you want
  --  to copy the entire table, use 'id'.
  (table (QField s) -> proj) ->
  -- | Backend-specific options. The output is also determined by this value
  SqlCopyToParams (BeamSqlBackendCopyToSyntax be) ->
  SqlCopyTo be proj
copyTableTo :: forall be proj (db :: (* -> *) -> *) (table :: (* -> *) -> *) s.
(IsSqlCopyToSyntax (BeamSqlBackendCopyToSyntax be),
 ProjectibleWithPredicate AnyType () Text proj) =>
DatabaseEntity be db (TableEntity table)
-> (table (QField s) -> proj)
-> SqlCopyToParams (BeamSqlBackendCopyToSyntax be)
-> SqlCopyTo be proj
copyTableTo (DatabaseEntity dt :: DatabaseEntityDescriptor be (TableEntity table)
dt@(DatabaseTable {})) table (QField s) -> proj
mkProj SqlCopyToParams (BeamSqlBackendCopyToSyntax be)
options =
  case [Text] -> Maybe (NonEmpty Text)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty (DatabaseEntityDescriptor be (TableEntity table)
-> (table (QField s) -> proj) -> [Text]
forall proj (table :: (* -> *) -> *) be s.
(ProjectibleWithPredicate AnyType () Text proj, Beamable table) =>
DatabaseEntityDescriptor be (TableEntity table)
-> (table (QField s) -> proj) -> [Text]
projection DatabaseEntityDescriptor be (TableEntity table)
dt table (QField s) -> proj
mkProj) of
    Maybe (NonEmpty Text)
Nothing -> SqlCopyTo be proj
forall be a. SqlCopyTo be a
SqlCopyToNoColumns
    Just NonEmpty Text
cols ->
      let source :: SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be)
source = Maybe Text
-> Text
-> Maybe (NonEmpty Text)
-> SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be)
forall syntax.
IsSqlCopyToSourceSyntax syntax =>
Maybe Text -> Text -> Maybe (NonEmpty Text) -> syntax
copyTableToSyntax (DatabaseEntityDescriptor be (TableEntity table)
dt DatabaseEntityDescriptor be (TableEntity table)
-> Getting
     (Maybe Text)
     (DatabaseEntityDescriptor be (TableEntity table))
     (Maybe Text)
-> Maybe Text
forall s a. s -> Getting a s a -> a
^. Getting
  (Maybe Text)
  (DatabaseEntityDescriptor be (TableEntity table))
  (Maybe Text)
forall be entityType.
IsDatabaseEntity be entityType =>
Traversal' (DatabaseEntityDescriptor be entityType) (Maybe Text)
Traversal'
  (DatabaseEntityDescriptor be (TableEntity table)) (Maybe Text)
dbEntitySchema) (DatabaseEntityDescriptor be (TableEntity table)
dt DatabaseEntityDescriptor be (TableEntity table)
-> Getting
     Text (DatabaseEntityDescriptor be (TableEntity table)) Text
-> Text
forall s a. s -> Getting a s a -> a
^. Getting Text (DatabaseEntityDescriptor be (TableEntity table)) Text
forall be entityType.
IsDatabaseEntity be entityType =>
Lens' (DatabaseEntityDescriptor be entityType) Text
Lens' (DatabaseEntityDescriptor be (TableEntity table)) Text
dbEntityName) (NonEmpty Text -> Maybe (NonEmpty Text)
forall a. a -> Maybe a
Just NonEmpty Text
cols)
       in BeamSqlBackendCopyToSyntax be -> SqlCopyTo be proj
forall be a. BeamSqlBackendCopyToSyntax be -> SqlCopyTo be a
SqlCopyTo
            (SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be)
-> SqlCopyToParams (BeamSqlBackendCopyToSyntax be)
-> BeamSqlBackendCopyToSyntax be
forall cmd.
IsSqlCopyToSyntax cmd =>
SqlCopyToSourceSyntax cmd -> SqlCopyToParams cmd -> cmd
copyToStmt SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be)
source SqlCopyToParams (BeamSqlBackendCopyToSyntax be)
options)

-- | Express the copy from the result of a @SELECT@ statement to a destination
-- (typically a file). Use this when the source rows are produced by a query
-- rather than read directly from a table.
--
-- To copy a table, or a subset of columns, see `copyTableTo`.
--
-- @since 0.11.1.0
copySelectTo ::
  ( IsSqlCopyToSyntax (BeamSqlBackendCopyToSyntax be),
    SqlCopyToSourceSelectSyntax (SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be))
      ~ BeamSqlBackendSelectSyntax be
  ) =>
  SqlSelect be a ->
  -- | Backend-specific options. The format is pinned by this value
  SqlCopyToParams (BeamSqlBackendCopyToSyntax be) ->
  SqlCopyTo be a
copySelectTo :: forall be a.
(IsSqlCopyToSyntax (BeamSqlBackendCopyToSyntax be),
 SqlCopyToSourceSelectSyntax
   (SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be))
 ~ BeamSqlBackendSelectSyntax be) =>
SqlSelect be a
-> SqlCopyToParams (BeamSqlBackendCopyToSyntax be)
-> SqlCopyTo be a
copySelectTo (SqlSelect BeamSqlBackendSelectSyntax be
selectSyntax) SqlCopyToParams (BeamSqlBackendCopyToSyntax be)
options =
  let source :: SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be)
source = SqlCopyToSourceSelectSyntax
  (SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be))
-> SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be)
forall syntax.
IsSqlCopyToSourceSyntax syntax =>
SqlCopyToSourceSelectSyntax syntax -> syntax
copySelectToSyntax BeamSqlBackendSelectSyntax be
SqlCopyToSourceSelectSyntax
  (SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be))
selectSyntax
   in BeamSqlBackendCopyToSyntax be -> SqlCopyTo be a
forall be a. BeamSqlBackendCopyToSyntax be -> SqlCopyTo be a
SqlCopyTo (SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be)
-> SqlCopyToParams (BeamSqlBackendCopyToSyntax be)
-> BeamSqlBackendCopyToSyntax be
forall cmd.
IsSqlCopyToSyntax cmd =>
SqlCopyToSourceSyntax cmd -> SqlCopyToParams cmd -> cmd
copyToStmt SqlCopyToSourceSyntax (BeamSqlBackendCopyToSyntax be)
source SqlCopyToParams (BeamSqlBackendCopyToSyntax be)
options)

-- | Express the copy to a table, from an external source (typically a file).
--
-- @since 0.11.1.0
copyTableFrom ::
  ( IsSqlCopyFromSyntax (BeamSqlBackendCopyFromSyntax be),
    ProjectibleWithPredicate AnyType () Text proj
  ) =>
  DatabaseEntity be db (TableEntity table) ->
  -- | Projection from table to columns. If you want
  --  to copy into the entire table, use 'id'.
  (table (QField s) -> proj) ->
  -- | Backend-specific options. The format is pinned by this value
  SqlCopyFromParams (BeamSqlBackendCopyFromSyntax be) ->
  SqlCopyFrom be proj
copyTableFrom :: forall be proj (db :: (* -> *) -> *) (table :: (* -> *) -> *) s.
(IsSqlCopyFromSyntax (BeamSqlBackendCopyFromSyntax be),
 ProjectibleWithPredicate AnyType () Text proj) =>
DatabaseEntity be db (TableEntity table)
-> (table (QField s) -> proj)
-> SqlCopyFromParams (BeamSqlBackendCopyFromSyntax be)
-> SqlCopyFrom be proj
copyTableFrom (DatabaseEntity dt :: DatabaseEntityDescriptor be (TableEntity table)
dt@(DatabaseTable {})) table (QField s) -> proj
mkProj SqlCopyFromParams (BeamSqlBackendCopyFromSyntax be)
options =
  case [Text] -> Maybe (NonEmpty Text)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty (DatabaseEntityDescriptor be (TableEntity table)
-> (table (QField s) -> proj) -> [Text]
forall proj (table :: (* -> *) -> *) be s.
(ProjectibleWithPredicate AnyType () Text proj, Beamable table) =>
DatabaseEntityDescriptor be (TableEntity table)
-> (table (QField s) -> proj) -> [Text]
projection DatabaseEntityDescriptor be (TableEntity table)
dt table (QField s) -> proj
mkProj) of
    Maybe (NonEmpty Text)
Nothing -> SqlCopyFrom be proj
forall be a. SqlCopyFrom be a
SqlCopyFromNoColumns
    Just NonEmpty Text
cols ->
      let source :: SqlCopyFromSourceSyntax (BeamSqlBackendCopyFromSyntax be)
source = Maybe Text
-> Text
-> Maybe (NonEmpty Text)
-> SqlCopyFromSourceSyntax (BeamSqlBackendCopyFromSyntax be)
forall syntax.
IsSqlCopyFromSourceSyntax syntax =>
Maybe Text -> Text -> Maybe (NonEmpty Text) -> syntax
copyTableFromSyntax (DatabaseEntityDescriptor be (TableEntity table)
dt DatabaseEntityDescriptor be (TableEntity table)
-> Getting
     (Maybe Text)
     (DatabaseEntityDescriptor be (TableEntity table))
     (Maybe Text)
-> Maybe Text
forall s a. s -> Getting a s a -> a
^. Getting
  (Maybe Text)
  (DatabaseEntityDescriptor be (TableEntity table))
  (Maybe Text)
forall be entityType.
IsDatabaseEntity be entityType =>
Traversal' (DatabaseEntityDescriptor be entityType) (Maybe Text)
Traversal'
  (DatabaseEntityDescriptor be (TableEntity table)) (Maybe Text)
dbEntitySchema) (DatabaseEntityDescriptor be (TableEntity table)
dt DatabaseEntityDescriptor be (TableEntity table)
-> Getting
     Text (DatabaseEntityDescriptor be (TableEntity table)) Text
-> Text
forall s a. s -> Getting a s a -> a
^. Getting Text (DatabaseEntityDescriptor be (TableEntity table)) Text
forall be entityType.
IsDatabaseEntity be entityType =>
Lens' (DatabaseEntityDescriptor be entityType) Text
Lens' (DatabaseEntityDescriptor be (TableEntity table)) Text
dbEntityName) (NonEmpty Text -> Maybe (NonEmpty Text)
forall a. a -> Maybe a
Just NonEmpty Text
cols)
       in BeamSqlBackendCopyFromSyntax be -> SqlCopyFrom be proj
forall be a. BeamSqlBackendCopyFromSyntax be -> SqlCopyFrom be a
SqlCopyFrom
            (SqlCopyFromSourceSyntax (BeamSqlBackendCopyFromSyntax be)
-> SqlCopyFromParams (BeamSqlBackendCopyFromSyntax be)
-> BeamSqlBackendCopyFromSyntax be
forall cmd.
IsSqlCopyFromSyntax cmd =>
SqlCopyFromSourceSyntax cmd -> SqlCopyFromParams cmd -> cmd
copyFromStmt SqlCopyFromSourceSyntax (BeamSqlBackendCopyFromSyntax be)
source SqlCopyFromParams (BeamSqlBackendCopyFromSyntax be)
options)

-- | Walk a projection and collect the names of the columns it touches.
--
-- This is the building block 'copyTableTo' / 'copyTableFrom' (and their
-- streaming counterparts) use to derive the column list for the emitted
-- @COPY@ statement. Exposed here so that the streaming submodule can reuse
-- the same logic without duplication.
projection ::
  (ProjectibleWithPredicate AnyType () Text proj, Beamable table) =>
  DatabaseEntityDescriptor be (TableEntity table) ->
  (table (QField s) -> proj) ->
  [Text]
projection :: forall proj (table :: (* -> *) -> *) be s.
(ProjectibleWithPredicate AnyType () Text proj, Beamable table) =>
DatabaseEntityDescriptor be (TableEntity table)
-> (table (QField s) -> proj) -> [Text]
projection DatabaseEntityDescriptor be (TableEntity table)
dt table (QField s) -> proj
mkProj =
  Writer [Text] proj -> [Text]
forall w a. Writer w a -> w
Strict.execWriter
    ( Proxy AnyType
-> Proxy ((), Text)
-> (forall context.
    AnyType context =>
    Proxy context -> Proxy () -> Text -> WriterT [Text] Identity Text)
-> proj
-> Writer [Text] proj
forall (m :: * -> *).
Monad m =>
Proxy AnyType
-> Proxy ((), Text)
-> (forall context.
    AnyType context =>
    Proxy context -> Proxy () -> Text -> m Text)
-> proj
-> m proj
forall (contextPredicate :: * -> Constraint) be res a
       (m :: * -> *).
(ProjectibleWithPredicate contextPredicate be res a, Monad m) =>
Proxy contextPredicate
-> Proxy (be, res)
-> (forall context.
    contextPredicate context =>
    Proxy context -> Proxy be -> res -> m res)
-> a
-> m a
project'
        (forall {k} (t :: k). Proxy t
forall (t :: * -> Constraint). Proxy t
Proxy @AnyType)
        (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @((), Text))
        (\Proxy context
_ Proxy ()
_ Text
f -> [Text] -> WriterT [Text] Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
Strict.tell [Text
f] WriterT [Text] Identity ()
-> WriterT [Text] Identity Text -> WriterT [Text] Identity Text
forall a b.
WriterT [Text] Identity a
-> WriterT [Text] Identity b -> WriterT [Text] Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> WriterT [Text] Identity Text
forall a. a -> WriterT [Text] Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
f)
        (table (QField s) -> proj
mkProj table (QField s)
tblFields)
    )
  where
    tblFields :: table (QField s)
tblFields =
      (forall a.
 Columnar' (TableField table) a -> Columnar' (QField s) a)
-> table (TableField table) -> table (QField s)
forall (table :: (* -> *) -> *) (f :: * -> *) (g :: * -> *).
Beamable table =>
(forall a. Columnar' f a -> Columnar' g a) -> table f -> table g
changeBeamRep
        (\(Columnar' Columnar (TableField table) a
fd) -> Columnar (QField s) a -> Columnar' (QField s) a
forall (f :: * -> *) a. Columnar f a -> Columnar' f a
Columnar' (Bool -> Text -> Text -> QField s a
forall s ty. Bool -> Text -> Text -> QField s ty
QField Bool
False (DatabaseEntityDescriptor be (TableEntity table)
dt DatabaseEntityDescriptor be (TableEntity table)
-> Getting
     Text (DatabaseEntityDescriptor be (TableEntity table)) Text
-> Text
forall s a. s -> Getting a s a -> a
^. Getting Text (DatabaseEntityDescriptor be (TableEntity table)) Text
forall be entityType.
IsDatabaseEntity be entityType =>
Lens' (DatabaseEntityDescriptor be entityType) Text
Lens' (DatabaseEntityDescriptor be (TableEntity table)) Text
dbEntityName) (TableField table a
Columnar (TableField table) a
fd TableField table a
-> Getting Text (TableField table a) Text -> Text
forall s a. s -> Getting a s a -> a
^. Getting Text (TableField table a) Text
forall (table :: (* -> *) -> *) ty (f :: * -> *).
Functor f =>
(Text -> f Text) -> TableField table ty -> f (TableField table ty)
fieldName)))
        (DatabaseEntityDescriptor be (TableEntity table)
-> table (TableField table)
forall (tbl :: (* -> *) -> *) be.
DatabaseEntityDescriptor be (TableEntity tbl) -> TableSettings tbl
dbTableSettings DatabaseEntityDescriptor be (TableEntity table)
dt)

-- | 'MonadBeam's that support copying data out of a database, to some other location.
--
-- See 'MonadBeamCopyFrom' for the inverse operation.
--
-- @since 0.11.1.0
class (MonadBeam be m) => MonadBeamCopyTo be m | m -> be where
  -- | Execute a built @COPY ... TO@ file statement.
  runCopyTo :: SqlCopyTo be res -> m ()

instance (MonadBeamCopyTo be m) => MonadBeamCopyTo be (ExceptT e m) where
  runCopyTo :: forall res. SqlCopyTo be res -> ExceptT e m ()
runCopyTo = m () -> ExceptT e m ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT e m ())
-> (SqlCopyTo be res -> m ()) -> SqlCopyTo be res -> ExceptT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

instance (MonadBeamCopyTo be m) => MonadBeamCopyTo be (ContT r m) where
  runCopyTo :: forall res. SqlCopyTo be res -> ContT r m ()
runCopyTo = m () -> ContT r m ()
forall (m :: * -> *) a. Monad m => m a -> ContT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ContT r m ())
-> (SqlCopyTo be res -> m ()) -> SqlCopyTo be res -> ContT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

instance (MonadBeamCopyTo be m) => MonadBeamCopyTo be (ReaderT r m) where
  runCopyTo :: forall res. SqlCopyTo be res -> ReaderT r m ()
runCopyTo = m () -> ReaderT r m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> (SqlCopyTo be res -> m ()) -> SqlCopyTo be res -> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

instance (MonadBeamCopyTo be m) => MonadBeamCopyTo be (Lazy.StateT r m) where
  runCopyTo :: forall res. SqlCopyTo be res -> StateT r m ()
runCopyTo = m () -> StateT r m ()
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT r m ())
-> (SqlCopyTo be res -> m ()) -> SqlCopyTo be res -> StateT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

instance (MonadBeamCopyTo be m) => MonadBeamCopyTo be (Strict.StateT r m) where
  runCopyTo :: forall res. SqlCopyTo be res -> StateT r m ()
runCopyTo = m () -> StateT r m ()
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT r m ())
-> (SqlCopyTo be res -> m ()) -> SqlCopyTo be res -> StateT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

instance (MonadBeamCopyTo be m, Monoid r) => MonadBeamCopyTo be (Lazy.WriterT r m) where
  runCopyTo :: forall res. SqlCopyTo be res -> WriterT r m ()
runCopyTo = m () -> WriterT r m ()
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT r m ())
-> (SqlCopyTo be res -> m ()) -> SqlCopyTo be res -> WriterT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

instance (MonadBeamCopyTo be m, Monoid r) => MonadBeamCopyTo be (Strict.WriterT r m) where
  runCopyTo :: forall res. SqlCopyTo be res -> WriterT r m ()
runCopyTo = m () -> WriterT r m ()
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT r m ())
-> (SqlCopyTo be res -> m ()) -> SqlCopyTo be res -> WriterT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

instance (MonadBeamCopyTo be m, Monoid w) => MonadBeamCopyTo be (Lazy.RWST r w s m) where
  runCopyTo :: forall res. SqlCopyTo be res -> RWST r w s m ()
runCopyTo = m () -> RWST r w s m ()
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (SqlCopyTo be res -> m ())
-> SqlCopyTo be res
-> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

instance (MonadBeamCopyTo be m, Monoid w) => MonadBeamCopyTo be (Strict.RWST r w s m) where
  runCopyTo :: forall res. SqlCopyTo be res -> RWST r w s m ()
runCopyTo = m () -> RWST r w s m ()
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (SqlCopyTo be res -> m ())
-> SqlCopyTo be res
-> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyTo be res -> m ()
forall res. SqlCopyTo be res -> m ()
forall be (m :: * -> *) res.
MonadBeamCopyTo be m =>
SqlCopyTo be res -> m ()
runCopyTo

-- | 'MonadBeam's that support copying data into database, from other location.
--
-- See 'MonadBeamCopyTo' for the inverse operation.
--
-- @since 0.11.1.0
class (MonadBeam be m) => MonadBeamCopyFrom be m | m -> be where
  -- | Execute a built @COPY ... FROM@ file statement.
  runCopyFrom :: SqlCopyFrom be proj -> m ()

instance (MonadBeamCopyFrom be m) => MonadBeamCopyFrom be (ExceptT e m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> ExceptT e m ()
runCopyFrom = m () -> ExceptT e m ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT e m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> ExceptT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom

instance (MonadBeamCopyFrom be m) => MonadBeamCopyFrom be (ContT r m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> ContT r m ()
runCopyFrom = m () -> ContT r m ()
forall (m :: * -> *) a. Monad m => m a -> ContT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ContT r m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> ContT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom

instance (MonadBeamCopyFrom be m) => MonadBeamCopyFrom be (ReaderT r m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> ReaderT r m ()
runCopyFrom = m () -> ReaderT r m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom

instance (MonadBeamCopyFrom be m) => MonadBeamCopyFrom be (Lazy.StateT r m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> StateT r m ()
runCopyFrom = m () -> StateT r m ()
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT r m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> StateT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom

instance (MonadBeamCopyFrom be m) => MonadBeamCopyFrom be (Strict.StateT r m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> StateT r m ()
runCopyFrom = m () -> StateT r m ()
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT r m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> StateT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom

instance (MonadBeamCopyFrom be m, Monoid r) => MonadBeamCopyFrom be (Lazy.WriterT r m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> WriterT r m ()
runCopyFrom = m () -> WriterT r m ()
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT r m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> WriterT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom

instance (MonadBeamCopyFrom be m, Monoid r) => MonadBeamCopyFrom be (Strict.WriterT r m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> WriterT r m ()
runCopyFrom = m () -> WriterT r m ()
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT r m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> WriterT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom

instance (MonadBeamCopyFrom be m, Monoid w) => MonadBeamCopyFrom be (Lazy.RWST r w s m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> RWST r w s m ()
runCopyFrom = m () -> RWST r w s m ()
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom

instance (MonadBeamCopyFrom be m, Monoid w) => MonadBeamCopyFrom be (Strict.RWST r w s m) where
  runCopyFrom :: forall proj. SqlCopyFrom be proj -> RWST r w s m ()
runCopyFrom = m () -> RWST r w s m ()
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (SqlCopyFrom be proj -> m ())
-> SqlCopyFrom be proj
-> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlCopyFrom be proj -> m ()
forall proj. SqlCopyFrom be proj -> m ()
forall be (m :: * -> *) proj.
MonadBeamCopyFrom be m =>
SqlCopyFrom be proj -> m ()
runCopyFrom