{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{- |
Copyright : Flipstone Technology Partners 2023
License   : MIT
Stability : Stable

Provides a type representing SQL DELETE and construction of that type.

@since 1.0.0.0
-}
module Orville.PostgreSQL.Expr.Delete
  ( DeleteExpr
  , deleteExpr
  )
where

import Data.Maybe (catMaybes)

import Orville.PostgreSQL.Expr.Name (Qualified, TableName)
import Orville.PostgreSQL.Expr.ReturningExpr (ReturningExpr)
import Orville.PostgreSQL.Expr.WhereClause (WhereClause)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql

{- |
Type to represent a SQL delete statement. E.G.

> DELETE FROM foo WHERE id < 10

'DeleteExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.

@since 1.0.0.0
-}
newtype DeleteExpr
  = DeleteExpr RawSql.RawSql
  deriving
    ( -- | @since 1.0.0.0
      RawSql -> DeleteExpr
DeleteExpr -> RawSql
(DeleteExpr -> RawSql)
-> (RawSql -> DeleteExpr) -> SqlExpression DeleteExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: DeleteExpr -> RawSql
toRawSql :: DeleteExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> DeleteExpr
unsafeFromRawSql :: RawSql -> DeleteExpr
RawSql.SqlExpression
    )

{- |

Construct a SQL DELETE from a table, optionally limiting with a 'WhereClause' and optionally
returning a 'ReturningExpr'.

@since 1.0.0.0
-}
deleteExpr ::
  Qualified TableName ->
  Maybe WhereClause ->
  Maybe ReturningExpr ->
  DeleteExpr
deleteExpr :: Qualified TableName
-> Maybe WhereClause -> Maybe ReturningExpr -> DeleteExpr
deleteExpr Qualified TableName
tableName Maybe WhereClause
maybeWhereClause Maybe ReturningExpr
maybeReturningExpr =
  RawSql -> DeleteExpr
DeleteExpr (RawSql -> DeleteExpr) -> RawSql -> DeleteExpr
forall a b. (a -> b) -> a -> b
$
    RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate RawSql
RawSql.space ([RawSql] -> RawSql) -> [RawSql] -> RawSql
forall a b. (a -> b) -> a -> b
$
      [Maybe RawSql] -> [RawSql]
forall a. [Maybe a] -> [a]
catMaybes
        [ RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (RawSql -> Maybe RawSql) -> RawSql -> Maybe RawSql
forall a b. (a -> b) -> a -> b
$ String -> RawSql
RawSql.fromString String
"DELETE FROM"
        , RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (RawSql -> Maybe RawSql) -> RawSql -> Maybe RawSql
forall a b. (a -> b) -> a -> b
$ Qualified TableName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Qualified TableName
tableName
        , (WhereClause -> RawSql) -> Maybe WhereClause -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WhereClause -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe WhereClause
maybeWhereClause
        , (ReturningExpr -> RawSql) -> Maybe ReturningExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ReturningExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe ReturningExpr
maybeReturningExpr
        ]