orville-postgresql-1.1.0.0: src/Orville/PostgreSQL/Expr/Select.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
Copyright : Flipstone Technology Partners 2023
License : MIT
Stability : Stable
@since 1.0.0.0
-}
module Orville.PostgreSQL.Expr.Select
( SelectClause
, selectClause
, SelectExpr
, selectExpr
, Distinct (Distinct)
, DistinctOnExpr
, selectDistinctOnExpr
)
where
import qualified Data.List.NonEmpty as NEL
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql
{- | Type to represent the @SELECT@ part of a SQL query. E.G.
> SELECT
or
> SELECT DISTINCT
'SelectClause' 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 SelectClause
= SelectClause RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs a 'SelectClause' using the given 'SelectExpr', which may indicate
that this is a @DISTINCT@ select.
@since 1.0.0.0
-}
selectClause :: SelectExpr -> SelectClause
selectClause expr = SelectClause (RawSql.fromString "SELECT " <> RawSql.toRawSql expr)
{- | Type to represent any expression modifying the @SELECT@ part of a SQL. E.G.
> DISTINCT
'SelectExpr' 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 SelectExpr = SelectExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | A simple value type used to indicate that a @SELECT@ should be distinct when
constructing a 'SelectExpr'.
@since 1.0.0.0
-}
data Distinct = Distinct
{- | Constructs a 'SelectExpr' that may or may not make the @SELECT@ distinct,
depending on whether 'Just Distinct' is passed or not.
@since 1.0.0.0
-}
selectExpr :: Maybe Distinct -> SelectExpr
selectExpr mbDistinct =
SelectExpr . RawSql.fromString $
case mbDistinct of
Just Distinct -> "DISTINCT "
Nothing -> ""
{- | Type to represent a expression to be used as part of a @DISTINCT@ modifer of a @SELECT@. E.G. the
foo in
> DISTINCT ON (foo)
'SelectExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom SQL.
@since 1.1.0.0
-}
newtype DistinctOnExpr = DistinctOnExpr RawSql.RawSql
deriving
( -- | @since 1.1.0.0
RawSql.SqlExpression
)
{- | Constructs a 'SelectExpr' that may or may not make the @SELECT@ distinct on the given expression.
Note that PostgreSQL states the distinct expressions must match the leftmost order by expressions if
they are both used, but this function does not enforce that.
@since 1.1.0.0
-}
selectDistinctOnExpr :: Maybe (NEL.NonEmpty DistinctOnExpr) -> SelectExpr
selectDistinctOnExpr mbDistinctOns =
SelectExpr $
case mbDistinctOns of
Just ons -> RawSql.fromString "DISTINCT ON " <> RawSql.parenthesized (RawSql.intercalate RawSql.commaSpace ons)
Nothing -> mempty