{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Orville.PostgreSQL.Expr.Query
( QueryExpr
, queryExpr
, SelectList
, selectColumns
, DerivedColumn
, deriveColumn
, deriveColumnAs
, selectDerivedColumns
, selectStar
, TableExpr
, tableExpr
)
where
import Data.Maybe (catMaybes, fromMaybe)
import Orville.PostgreSQL.Expr.GroupBy (GroupByClause)
import Orville.PostgreSQL.Expr.LimitExpr (LimitExpr)
import Orville.PostgreSQL.Expr.Name (ColumnName)
import Orville.PostgreSQL.Expr.OffsetExpr (OffsetExpr)
import Orville.PostgreSQL.Expr.OrderBy (OrderByClause)
import Orville.PostgreSQL.Expr.Select (SelectClause)
import Orville.PostgreSQL.Expr.TableReferenceList (TableReferenceList)
import Orville.PostgreSQL.Expr.ValueExpression (ValueExpression, columnReference)
import Orville.PostgreSQL.Expr.WhereClause (WhereClause)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql
newtype QueryExpr
= QueryExpr RawSql.RawSql
deriving (RawSql -> QueryExpr
QueryExpr -> RawSql
(QueryExpr -> RawSql)
-> (RawSql -> QueryExpr) -> SqlExpression QueryExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: QueryExpr -> RawSql
toRawSql :: QueryExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> QueryExpr
unsafeFromRawSql :: RawSql -> QueryExpr
RawSql.SqlExpression)
queryExpr :: SelectClause -> SelectList -> Maybe TableExpr -> QueryExpr
queryExpr :: SelectClause -> SelectList -> Maybe TableExpr -> QueryExpr
queryExpr SelectClause
querySelectClause SelectList
selectList Maybe TableExpr
maybeTableExpr =
let
maybeFromClause :: Maybe RawSql
maybeFromClause = do
TableExpr
table <- Maybe TableExpr
maybeTableExpr
RawSql -> Maybe RawSql
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> RawSql
RawSql.fromString String
" FROM " RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> TableExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql TableExpr
table)
in
RawSql -> QueryExpr
QueryExpr (RawSql -> QueryExpr) -> RawSql -> QueryExpr
forall a b. (a -> b) -> a -> b
$
[RawSql] -> RawSql
forall a. Monoid a => [a] -> a
mconcat
[ SelectClause -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql SelectClause
querySelectClause
, SelectList -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql SelectList
selectList
, RawSql -> Maybe RawSql -> RawSql
forall a. a -> Maybe a -> a
fromMaybe (String -> RawSql
RawSql.fromString String
"") Maybe RawSql
maybeFromClause
]
newtype SelectList = SelectList RawSql.RawSql
deriving (RawSql -> SelectList
SelectList -> RawSql
(SelectList -> RawSql)
-> (RawSql -> SelectList) -> SqlExpression SelectList
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: SelectList -> RawSql
toRawSql :: SelectList -> RawSql
$cunsafeFromRawSql :: RawSql -> SelectList
unsafeFromRawSql :: RawSql -> SelectList
RawSql.SqlExpression)
selectStar :: SelectList
selectStar :: SelectList
selectStar =
RawSql -> SelectList
SelectList (String -> RawSql
RawSql.fromString String
"*")
selectColumns :: [ColumnName] -> SelectList
selectColumns :: [ColumnName] -> SelectList
selectColumns =
[DerivedColumn] -> SelectList
selectDerivedColumns ([DerivedColumn] -> SelectList)
-> ([ColumnName] -> [DerivedColumn]) -> [ColumnName] -> SelectList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ColumnName -> DerivedColumn) -> [ColumnName] -> [DerivedColumn]
forall a b. (a -> b) -> [a] -> [b]
map (ValueExpression -> DerivedColumn
deriveColumn (ValueExpression -> DerivedColumn)
-> (ColumnName -> ValueExpression) -> ColumnName -> DerivedColumn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ColumnName -> ValueExpression
columnReference)
newtype DerivedColumn = DerivedColumn RawSql.RawSql
deriving (RawSql -> DerivedColumn
DerivedColumn -> RawSql
(DerivedColumn -> RawSql)
-> (RawSql -> DerivedColumn) -> SqlExpression DerivedColumn
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: DerivedColumn -> RawSql
toRawSql :: DerivedColumn -> RawSql
$cunsafeFromRawSql :: RawSql -> DerivedColumn
unsafeFromRawSql :: RawSql -> DerivedColumn
RawSql.SqlExpression)
selectDerivedColumns :: [DerivedColumn] -> SelectList
selectDerivedColumns :: [DerivedColumn] -> SelectList
selectDerivedColumns =
RawSql -> SelectList
SelectList (RawSql -> SelectList)
-> ([DerivedColumn] -> RawSql) -> [DerivedColumn] -> SelectList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawSql -> [DerivedColumn] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate RawSql
RawSql.comma
deriveColumn :: ValueExpression -> DerivedColumn
deriveColumn :: ValueExpression -> DerivedColumn
deriveColumn =
RawSql -> DerivedColumn
DerivedColumn (RawSql -> DerivedColumn)
-> (ValueExpression -> RawSql) -> ValueExpression -> DerivedColumn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ValueExpression -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql
deriveColumnAs :: ValueExpression -> ColumnName -> DerivedColumn
deriveColumnAs :: ValueExpression -> ColumnName -> DerivedColumn
deriveColumnAs ValueExpression
valueExpr ColumnName
asColumn =
RawSql -> DerivedColumn
DerivedColumn
( ValueExpression -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ValueExpression
valueExpr
RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> String -> RawSql
RawSql.fromString String
" AS "
RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> ColumnName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ColumnName
asColumn
)
newtype TableExpr
= TableExpr RawSql.RawSql
deriving (RawSql -> TableExpr
TableExpr -> RawSql
(TableExpr -> RawSql)
-> (RawSql -> TableExpr) -> SqlExpression TableExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: TableExpr -> RawSql
toRawSql :: TableExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> TableExpr
unsafeFromRawSql :: RawSql -> TableExpr
RawSql.SqlExpression)
tableExpr ::
TableReferenceList ->
Maybe WhereClause ->
Maybe GroupByClause ->
Maybe OrderByClause ->
Maybe LimitExpr ->
Maybe OffsetExpr ->
TableExpr
tableExpr :: TableReferenceList
-> Maybe WhereClause
-> Maybe GroupByClause
-> Maybe OrderByClause
-> Maybe LimitExpr
-> Maybe OffsetExpr
-> TableExpr
tableExpr
TableReferenceList
tableReferenceList
Maybe WhereClause
maybeWhereClause
Maybe GroupByClause
maybeGroupByClause
Maybe OrderByClause
maybeOrderByClause
Maybe LimitExpr
maybeLimitExpr
Maybe OffsetExpr
maybeOffsetExpr =
RawSql -> TableExpr
TableExpr
(RawSql -> TableExpr)
-> ([RawSql] -> RawSql) -> [RawSql] -> TableExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate RawSql
RawSql.space
([RawSql] -> TableExpr) -> [RawSql] -> TableExpr
forall a b. (a -> b) -> a -> b
$ TableReferenceList -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql TableReferenceList
tableReferenceList
RawSql -> [RawSql] -> [RawSql]
forall a. a -> [a] -> [a]
: [Maybe RawSql] -> [RawSql]
forall a. [Maybe a] -> [a]
catMaybes
[ WhereClause -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql (WhereClause -> RawSql) -> Maybe WhereClause -> Maybe RawSql
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe WhereClause
maybeWhereClause
, GroupByClause -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql (GroupByClause -> RawSql) -> Maybe GroupByClause -> Maybe RawSql
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe GroupByClause
maybeGroupByClause
, OrderByClause -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql (OrderByClause -> RawSql) -> Maybe OrderByClause -> Maybe RawSql
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe OrderByClause
maybeOrderByClause
, LimitExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql (LimitExpr -> RawSql) -> Maybe LimitExpr -> Maybe RawSql
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe LimitExpr
maybeLimitExpr
, OffsetExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql (OffsetExpr -> RawSql) -> Maybe OffsetExpr -> Maybe RawSql
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe OffsetExpr
maybeOffsetExpr
]