rel8-1.7.0.0: src/Rel8/Statement/Delete.hs
{-# language DuplicateRecordFields #-}
{-# language FlexibleContexts #-}
{-# language GADTs #-}
{-# language NamedFieldPuns #-}
{-# language RecordWildCards #-}
{-# language StandaloneKindSignatures #-}
{-# language StrictData #-}
module Rel8.Statement.Delete
( Delete(..)
, delete
, ppDelete
)
where
-- base
import Data.Kind ( Type )
import Prelude
-- opaleye
import qualified Opaleye.Internal.Tag as Opaleye
-- pretty
import Text.PrettyPrint ( Doc, (<+>), ($$), text )
-- rel8
import Rel8.Expr ( Expr )
import Rel8.Query ( Query )
import Rel8.Schema.Name ( Selects )
import Rel8.Schema.Table ( TableSchema, ppTable )
import Rel8.Statement (Statement)
import Rel8.Statement.Returning (Returning, ppReturning, runReturning)
import Rel8.Statement.Using ( ppUsing )
import Rel8.Statement.Where ( ppWhere )
-- transformers
import Control.Monad.Trans.State.Strict (State)
-- | The constituent parts of a @DELETE@ statement.
type Delete :: Type -> Type
data Delete a where
Delete :: Selects names exprs =>
{ from :: TableSchema names
-- ^ Which table to delete from.
, using :: Query using
-- ^ @USING@ clause — this can be used to join against other tables,
-- and its results can be referenced in the @WHERE@ clause
, deleteWhere :: using -> exprs -> Expr Bool
-- ^ Which rows should be selected for deletion.
, returning :: Returning names a
-- ^ What to return from the @DELETE@ statement.
}
-> Delete a
-- | Build a @DELETE@ 'Statement'.
delete :: Delete a -> Statement a
delete statement@Delete {returning} =
runReturning (ppDelete statement) returning
ppDelete :: Delete a -> State Opaleye.Tag Doc
ppDelete Delete {..} = do
musing <- ppUsing using
pure $ case musing of
Nothing ->
text "DELETE FROM" <+> ppTable from $$
text "WHERE false"
Just (usingDoc, i) ->
text "DELETE FROM" <+> ppTable from $$
usingDoc $$
ppWhere from (deleteWhere i) $$
ppReturning from returning