rel8-1.1.0.0: src/Rel8/Statement/Delete.hs
{-# language DuplicateRecordFields #-}
{-# language GADTs #-}
{-# language NamedFieldPuns #-}
{-# language RankNTypes #-}
{-# language RecordWildCards #-}
{-# language StandaloneKindSignatures #-}
{-# language StrictData #-}
module Rel8.Statement.Delete
( Delete(..)
, delete
, ppDelete
)
where
-- base
import Data.Kind ( Type )
import Prelude
-- hasql
import qualified Hasql.Encoders as Hasql
import qualified Hasql.Statement as Hasql
-- 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.Returning ( Returning, decodeReturning, ppReturning )
import Rel8.Statement.Using ( ppUsing )
import Rel8.Statement.Where ( ppWhere )
-- text
import qualified Data.Text as Text
import Data.Text.Encoding ( encodeUtf8 )
-- | 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
ppDelete :: Delete a -> Doc
ppDelete Delete {..} = case ppUsing using 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
-- | Run a 'Delete' statement.
delete :: Delete a -> Hasql.Statement () a
delete d@Delete {returning} = Hasql.Statement bytes params decode prepare
where
bytes = encodeUtf8 $ Text.pack sql
params = Hasql.noParams
decode = decodeReturning returning
prepare = False
sql = show doc
doc = ppDelete d