{-# LANGUAGE BangPatterns, TypeFamilies, DataKinds, PolyKinds, TypeApplications, ScopedTypeVariables, ConstraintKinds, TypeOperators, GADTs, UndecidableInstances, StandaloneDeriving, FunctionalDependencies, FlexibleContexts, InstanceSigs, AllowAmbiguousTypes, DeriveAnyClass #-}
{-|
Module: IHP.QueryBuilder.Filter
Description: WHERE clause filtering functions for QueryBuilder
Copyright: (c) digitally induced GmbH, 2020

This module provides all the filterWhere* functions for building WHERE clauses.
-}
module IHP.QueryBuilder.Filter
( filterWhere
, filterWhereCaseInsensitive
, filterWhereNot
, filterWhereIn
, filterWhereInCaseInsensitive
, filterWhereIdIn
, filterWhereNotIn
, filterWhereLike
, filterWhereILike
, filterWhereMatches
, filterWhereIMatches
, filterWherePast
, filterWhereFuture
, filterWhereGreaterThan
, filterWhereLarger
, filterWhereGreaterThanOrEqualTo
, filterWhereAtLeast
, filterWhereLessThan
, filterWhereSmaller
, filterWhereLessThanOrEqualTo
, filterWhereAtMost
, filterWhereSql
  -- * Joined table variants
, filterWhereJoinedTable
, filterWhereCaseInsensitiveJoinedTable
, filterWhereNotJoinedTable
, filterWhereInJoinedTable
, filterWhereNotInJoinedTable
, filterWhereLikeJoinedTable
, filterWhereILikeJoinedTable
, filterWhereMatchesJoinedTable
, filterWhereIMatchesJoinedTable
) where

import IHP.Prelude
import IHP.ModelSupport
import IHP.QueryBuilder.Types
import IHP.QueryBuilder.Compiler (negateFilterOperator)
import qualified Hasql.DynamicStatements.Snippet as Snippet
import Hasql.Implicits.Encoders (DefaultParamEncoder)
import IHP.Hasql.Encoders () -- Import for DefaultParamEncoder instances
import IHP.QueryBuilder.Compiler (qualifiedColumnName)

-- | Adds a simple @WHERE x = y@ condition to the query.
--
-- __Example:__ Only show projects where @active@ is @True@.
--
-- > activeProjects <- query @Project
-- >     |> filterWhere (#active, True)
-- >     |> fetch
-- > -- SELECT * FROM projects WHERE active = True
--
-- __Example:__ Find book with title @Learn you a Haskell@.
--
-- > book <- query @Book
-- >     |> filterWhere (#title, "Learn you a Haskell")
-- >     |> fetchOne
-- > -- SELECT * FROM books WHERE name = 'Learn you a Haskell' LIMIT 1
--
--
-- __Example:__ Find active projects owned by the current user.
--
-- > projects <- query @Project
-- >     |> filterWhere (#active, True)
-- >     |> filterWhere (#currentUserId, currentUserId)
-- >     |> fetch
-- > -- SELECT * FROM projects WHERE active = true AND current_user_id = '..'
--
--
-- For dynamic conditions (e.g. involving @NOW()@), see 'filterWhereSql'.
--
-- For @WHERE x IN (a, b, c)@ conditions, take a look at 'filterWhereIn' and 'filterWhereNotIn'.
--
-- For @WHERE x LIKE a@ or @WHERE x ~ a@  conditions, see 'filterWhereLike' and 'filterWhereMatches' respectively.
-- For case-insensitive versions of these operators, see 'filterWhereILike' and 'filterWhereIMatches'.
--
-- When your condition is too complex, use a raw sql query with 'IHP.ModelSupport.sqlQuery'.
filterWhere :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, EqOrIsOperator value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhere :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, EqOrIsOperator value,
 model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhere (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, value -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator value
value, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhere #-}

-- | Like 'filterWhere', but takes a type argument specifying the table which holds the column that is to be compared. The column must have been joined before using 'innerJoin' or 'innerJoinThirdTable'. Example:
--
-- __Example:__ get posts by user Tom.
--
-- > tomPosts <- query @Post
-- >                    |> innerJoin @User (#createdBy, #id)
-- >                    |> filterWhereJoinedTable @User (#name, "Tom" :: Text)
-- >                    |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name = 'Tom'
--
filterWhereJoinedTable :: forall model name table value queryBuilderProvider joinRegister table'. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, EqOrIsOperator value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereJoinedTable :: forall {k1} model (name :: Symbol) (table :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1)
       (table' :: Symbol).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, EqOrIsOperator value,
 table ~ GetTableName model,
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereJoinedTable (Proxy name
name, value
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, value -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator value
value, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereJoinedTable #-}

-- | Like 'filterWhereJoinedTable', but adds a @WHERE LOWER(x) = LOWER(y)@ condition to the query. Example:
--
-- __Example:__ get posts by user Tom, ignoring case.
--
-- > tomPosts <- query @Post
-- >                    |> innerJoin @User (#createdBy, #id)
-- >                    |> filterWhereCaseInsensitiveJoinedTable @User (#name, "Tom" :: Text)
-- >                    |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE LOWER(users.name) = LOWER('Tom')
--
filterWhereCaseInsensitiveJoinedTable :: forall model name table value queryBuilderProvider joinRegister table'. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, EqOrIsOperator value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereCaseInsensitiveJoinedTable :: forall {k1} model (name :: Symbol) (table :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1)
       (table' :: Symbol).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, EqOrIsOperator value,
 table ~ GetTableName model,
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereCaseInsensitiveJoinedTable (Proxy name
name, value
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, value -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator value
value, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"LOWER", applyRight :: Maybe Text
applyRight = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"LOWER" }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereCaseInsensitiveJoinedTable #-}

-- | Like 'filterWhere' but negates the condition.
--
-- __Example:__ Only show projects created by other users.
--
-- > activeProjects <- query @Project
-- >     |> filterWhereNot (#userId, currentUserId)
-- >     |> fetch
-- > -- SELECT * FROM projects WHERE user_id != '23d5ea33-b28e-4f0a-99b3-77a3564a2546'
--
filterWhereNot :: forall name table model value. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, EqOrIsOperator value, model ~ GetModelByTableName table, Table model) => (Proxy name, value) -> QueryBuilder table -> QueryBuilder table
filterWhereNot :: forall (name :: Symbol) (table :: Symbol) model value.
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, EqOrIsOperator value,
 model ~ GetModelByTableName table, Table model) =>
(Proxy name, value) -> QueryBuilder table -> QueryBuilder table
filterWhereNot (Proxy name
name, value
value) QueryBuilder table
queryBuilder = FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator -> FilterOperator
negateFilterOperator (value -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator value
value), value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
{-# INLINE filterWhereNot #-}

-- | Like 'filterWhereNotJoinedTable' but negates the condition.
--
-- __Example:__ Only show projects not created by user Tom.
--
-- > tomPosts <- query @Post
-- >                    |> innerJoin @User (#createdBy, #id)
-- >                    |> filterWhereNotJoinedTable @User (#name, "Tom" :: Text)
-- >                    |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name = 'Tom'
--
filterWhereNotJoinedTable :: forall model name table value queryBuilderProvider joinRegister table'. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, EqOrIsOperator value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereNotJoinedTable :: forall {k1} model (name :: Symbol) (table :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1)
       (table' :: Symbol).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, EqOrIsOperator value,
 table ~ GetTableName model,
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereNotJoinedTable (Proxy name
name, value
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator -> FilterOperator
negateFilterOperator (value -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator value
value), value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereNotJoinedTable #-}
-- | Adds a @WHERE x IN (y)@ condition to the query.
--
-- __Example:__ Only show projects where @status@ is @Draft@ or @Active@.
--
-- > visibleProjects <- query @Project
-- >     |> filterWhereIn (#status, [Draft, Active])
-- >     |> fetch
-- > -- SELECT * FROM projects WHERE status IN ('draft', 'active')
--
-- For negation use 'filterWhereNotIn'
--
filterWhereIn :: forall name table model value queryBuilderProvider (joinRegister :: Type). (KnownSymbol table, KnownSymbol name, DefaultParamEncoder [value], DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, EqOrIsOperator value, Table model) => (Proxy name, [value]) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereIn :: forall (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) joinRegister.
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder [value],
 DefaultParamEncoder value, HasField name model value,
 model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister,
 EqOrIsOperator value, Table model) =>
(Proxy name, [value])
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereIn (Proxy name
name, [value]
value) queryBuilderProvider table
queryBuilderProvider =
        case [value] -> Maybe value
forall a. [a] -> Maybe a
head [value]
nullValues of
            Maybe value
Nothing -> QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder QueryBuilder table
whereInQuery -- All values non null
            Just value
nullValue ->
                let
                    isNullValueExpr :: QueryBuilder table
isNullValueExpr = FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
IsOp, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
nullValue), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
                in
                    case [value] -> Maybe value
forall a. [a] -> Maybe a
head [value]
nonNullValues of
                        Just value
nonNullValue -> -- Some non null values, some null values
                            QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder (QueryBuilder table -> queryBuilderProvider table)
-> QueryBuilder table -> queryBuilderProvider table
forall a b. (a -> b) -> a -> b
$ QueryBuilder table -> QueryBuilder table -> QueryBuilder table
forall (table :: Symbol).
QueryBuilder table -> QueryBuilder table -> QueryBuilder table
UnionQueryBuilder
                                (QueryBuilder table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol). QueryBuilder table -> QueryBuilder table
injectQueryBuilder QueryBuilder table
whereInQuery)
                                (QueryBuilder table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol). QueryBuilder table -> QueryBuilder table
injectQueryBuilder QueryBuilder table
isNullValueExpr)
                        Maybe value
Nothing -> QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder QueryBuilder table
isNullValueExpr -- All values null
    where
        -- Only NOT NULL values can be compares inside the IN expression, NULL values have to be compares using a manual appended IS expression
        -- https://github.com/digitallyinduced/ihp/issues/906
        --
        ([value]
nonNullValues, [value]
nullValues) = [value]
value [value] -> ([value] -> ([value], [value])) -> ([value], [value])
forall a b. a -> (a -> b) -> b
|> (value -> Bool) -> [value] -> ([value], [value])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\value
v -> value -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator value
v FilterOperator -> FilterOperator -> Bool
forall a. Eq a => a -> a -> Bool
== FilterOperator
EqOp)

        whereInQuery :: QueryBuilder table
whereInQuery = FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
InOp, [value] -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param [value]
nonNullValues), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }

        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereIn #-}

-- Like 'filterWhereIn', but case insensitive.
--
-- __Example:__ Only show users where @email@ is @User1@example.com@ or @User2@example.com@.
--
-- > users <- query @User
-- >     |> filterWhereInCaseInsensitive (#email, ['User1@example.com', 'User2@example.com'])
-- >     |> fetch
-- > -- SELECT * FROM users WHERE LOWER(email) IN ('user1@example.com', 'user2@example.com')
--
filterWhereInCaseInsensitive :: forall name table model value queryBuilderProvider (joinRegister :: Type). ( KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, EqOrIsOperator value, Table model) => (Proxy name, [Text]) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereInCaseInsensitive :: forall (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) joinRegister.
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister,
 EqOrIsOperator value, Table model) =>
(Proxy name, [Text])
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereInCaseInsensitive (Proxy name
name, [Text]
values) queryBuilderProvider table
queryBuilderProvider =
        case [Text] -> Maybe Text
forall a. [a] -> Maybe a
head [Text]
nullValues of
            Maybe Text
Nothing -> QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder QueryBuilder table
whereInQuery
            Just Text
nullValue ->
                let
                    isNullValueExpr :: QueryBuilder table
isNullValueExpr = FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
IsOp, Text -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param Text
nullValue), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
                in
                    case [Text] -> Maybe Text
forall a. [a] -> Maybe a
head [Text]
nonNullValues of
                        Just Text
_ ->
                            QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder (QueryBuilder table -> queryBuilderProvider table)
-> QueryBuilder table -> queryBuilderProvider table
forall a b. (a -> b) -> a -> b
$ QueryBuilder table -> QueryBuilder table -> QueryBuilder table
forall (table :: Symbol).
QueryBuilder table -> QueryBuilder table -> QueryBuilder table
UnionQueryBuilder
                                (QueryBuilder table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol). QueryBuilder table -> QueryBuilder table
injectQueryBuilder QueryBuilder table
whereInQuery)
                                (QueryBuilder table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol). QueryBuilder table -> QueryBuilder table
injectQueryBuilder QueryBuilder table
isNullValueExpr)
                        Maybe Text
Nothing -> QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder QueryBuilder table
isNullValueExpr
    where
        ([Text]
nonNullValues, [Text]
nullValues) = [Text]
values [Text] -> ([Text] -> ([Text], [Text])) -> ([Text], [Text])
forall a b. a -> (a -> b) -> b
|> (Text -> Bool) -> [Text] -> ([Text], [Text])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\Text
v -> Text -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator Text
v FilterOperator -> FilterOperator -> Bool
forall a. Eq a => a -> a -> Bool
== FilterOperator
EqOp)

        lowerValues :: [Text]
lowerValues = (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
toLower [Text]
nonNullValues

        whereInQuery :: QueryBuilder table
whereInQuery = FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
lowerColumnName, FilterOperator
InOp, [Text] -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param [Text]
lowerValues), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }

        lowerColumnName :: Text
lowerColumnName = Text
"LOWER(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
columnName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider

{-# INLINE filterWhereInCaseInsensitive #-}

-- | Like 'filterWhereIn', but takes a type argument specifying the table which holds the column that is compared. The table needs to have been joined before using 'innerJoin' or 'innerJoinThirdTable'.
--
-- __Example:__ get posts by Tom and Tim.
--
-- > tomOrTimPosts <- query @Post
-- >    |> innerJoin @User (#createdBy, #id)
-- >    |> filterWhereInJoinedTable @User (#name, ["Tom","Tim"])
-- >    |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name IN ('Tom', 'Tim')
--
filterWhereInJoinedTable :: forall model name table value queryBuilderProvider joinRegister table'. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder [value], HasField name model value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, [value]) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereInJoinedTable :: forall {k1} model (name :: Symbol) (table :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1)
       (table' :: Symbol).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder [value],
 HasField name model value, table ~ GetTableName model,
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, [value])
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereInJoinedTable (Proxy name
name, [value]
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
InOp, [value] -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param [value]
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereInJoinedTable #-}


-- | Adds a @WHERE x NOT IN (y)@ condition to the query.
--
-- __Example:__ Only show projects where @status@ is not @Archived@
--
-- > visibleProjects <- query @Project
-- >     |> filterWhereNotIn (#status, [Archived])
-- >     |> fetch
-- > -- SELECT * FROM projects WHERE status NOT IN ('archived')
--
-- The inclusive version of this function is called 'filterWhereIn'.
--
filterWhereNotIn :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder [value], DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, EqOrIsOperator value) => (Proxy name, [value]) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereNotIn :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder [value],
 DefaultParamEncoder value, HasField name model value,
 model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister,
 EqOrIsOperator value) =>
(Proxy name, [value])
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereNotIn (Proxy name
_, []) queryBuilderProvider table
queryBuilder = queryBuilderProvider table
queryBuilder -- Handle empty case by ignoring query part: `WHERE x NOT IN ()`
filterWhereNotIn (Proxy name
name, [value]
value) queryBuilderProvider table
queryBuilderProvider =
        case [value] -> Maybe value
forall a. [a] -> Maybe a
head [value]
nullValues of
            Maybe value
Nothing -> QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder QueryBuilder table
whereNotInQuery -- All values non null
            Just value
nullValue ->
                case [value] -> Maybe value
forall a. [a] -> Maybe a
head [value]
nonNullValues of
                    Just value
nonNullValue -> QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { queryBuilder :: QueryBuilder table
queryBuilder = QueryBuilder table
whereNotInQuery, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
IsNotOp, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
nullValue), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing } -- Some non null values, some null values
                    Maybe value
Nothing -> QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
IsNotOp, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
nullValue), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing } -- All values null
    where
        -- Only NOT NULL values can be compares inside the IN expression, NULL values have to be compares using a manual appended IS expression
        -- https://github.com/digitallyinduced/ihp/issues/906
        --
        ([value]
nonNullValues, [value]
nullValues) = [value]
value [value] -> ([value] -> ([value], [value])) -> ([value], [value])
forall a b. a -> (a -> b) -> b
|> (value -> Bool) -> [value] -> ([value], [value])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\value
v -> value -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator value
v FilterOperator -> FilterOperator -> Bool
forall a. Eq a => a -> a -> Bool
== FilterOperator
EqOp)

        whereNotInQuery :: QueryBuilder table
whereNotInQuery = FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
NotInOp, [value] -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param [value]
nonNullValues), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }

        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @table) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereNotIn #-}

-- | Like 'filterWhereNotIn', but takes a type argument specifying the table which holds the column that is compared. The table needs to have been joined before using 'innerJoin' or 'innerJoinThirdTable'.
--
-- __Example:__ get posts by users not named Tom or Tim.
--
-- > notTomOrTimPosts <- query @Post
-- >    |> innerJoin @User (#createdBy, #id)
-- >    |> filterWhereNotInJoinedTable @User (#name, ["Tom","Tim"])
-- >    |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name NOT IN ('Tom', 'Tim')
filterWhereNotInJoinedTable :: forall model name table  value queryBuilderProvider joinRegister table'. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder [value], HasField name model value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, [value]) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereNotInJoinedTable :: forall {k1} model (name :: Symbol) (table :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1)
       (table' :: Symbol).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder [value],
 HasField name model value, table ~ GetTableName model,
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, [value])
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereNotInJoinedTable (Proxy name
_, []) queryBuilderProvider table'
queryBuilderProvider = queryBuilderProvider table'
queryBuilderProvider -- Handle empty case by ignoring query part: `WHERE x NOT IN ()`
filterWhereNotInJoinedTable (Proxy name
name, [value]
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
NotInOp, [value] -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param [value]
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereNotInJoinedTable #-}


-- | Adds a @WHERE x LIKE y@ condition to the query.
--
-- __Example:__ Find titles matching search term.
--
-- > articles <- query @Article
-- >     |> filterWhereLike (#title, "%" <> searchTerm <> "%")
-- >     |> fetch
-- > -- SELECT * FROM articles WHERE title LIKE '%..%'
filterWhereLike :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLike :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLike (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, MatchSensitivity -> FilterOperator
LikeOp MatchSensitivity
CaseSensitive, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereLike #-}

-- | Like 'filterWhereLik'e, but takes a type argument specifying the table which holds the column that is compared. The table needs to have been joined before using 'innerJoin' or 'innerJoinThirdTable'.
--
-- __Example:__ Serach for Posts by users whose name contains "olaf" (case insensitive)
--
-- > olafPosts <- query @Post
-- >                |> innerJoin @User (#createdBy, #id)
-- >                |> filterWhereLikeJoinedTable @User (#name, "%Olaf%")
-- >                |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name LIKE '%Olaf%'
filterWhereLikeJoinedTable :: forall model name table value queryBuilderProvider joinRegister table'. (KnownSymbol name, KnownSymbol table, table ~ GetTableName model, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereLikeJoinedTable :: forall {k1} model (name :: Symbol) (table :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1)
       (table' :: Symbol).
(KnownSymbol name, KnownSymbol table, table ~ GetTableName model,
 DefaultParamEncoder value, HasField name model value,
 model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereLikeJoinedTable (Proxy name
name, value
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, MatchSensitivity -> FilterOperator
LikeOp MatchSensitivity
CaseSensitive, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereLikeJoinedTable #-}


-- | Adds a @WHERE x ILIKE y@ condition to the query. Case-insensitive version of 'filterWhereLike'.
--
-- __Example:__ Find titles matching search term.
--
-- > articles <- query @Article
-- >     |> filterWhereILike (#title, "%" <> searchTerm <> "%")
-- >     |> fetch
-- > -- SELECT * FROM articles WHERE title ILIKE '%..%'
filterWhereILike :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereILike :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereILike (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, MatchSensitivity -> FilterOperator
LikeOp MatchSensitivity
CaseInsensitive, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereILike #-}

-- | Like 'filterWhereILike'; case-insensitive version of filterWhereLikeJoinedTable, takes a type argument specifying the table which holds the column that is compared. The table needs to have been joined before using 'innerJoin' or 'innerJoinThirdTable'.
--
-- __Example:__ Serach for Posts by users whose name contains "olaf" (case insensitive)
--
-- > olafPosts <-
-- >    query @Post
--      |> innerJoin @User (#createdBy, #id)
--      |> filterWhereILikeJoinedTable @User (#name, "%Olaf%")
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name ILIKE '%Olaf%'
filterWhereILikeJoinedTable :: forall model table name table' model' value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, table ~ GetTableName model, model' ~ GetModelByTableName table', HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereILikeJoinedTable :: forall {k1} model (table :: Symbol) (name :: Symbol)
       (table' :: Symbol) model' value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, table ~ GetTableName model,
 model' ~ GetModelByTableName table',
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereILikeJoinedTable (Proxy name
name, value
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, MatchSensitivity -> FilterOperator
LikeOp MatchSensitivity
CaseInsensitive, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereILikeJoinedTable #-}


-- | Adds a @WHERE x ~ y@ condition to the query.
--
-- __Example:__ Find names with titles in front.
--
-- > articles <- query @User
-- >     |> filterWhereMatches (#name, "^(M(rs|r|iss)|Dr|Sir). ")
-- >     |> fetch
-- > -- SELECT * FROM articles WHERE title ~ '^(M(rs|r|iss)|Dr|Sir). '
filterWhereMatches :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereMatches :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, table ~ GetTableName model,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereMatches (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, MatchSensitivity -> FilterOperator
MatchesOp MatchSensitivity
CaseSensitive, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereMatches #-}

-- | Adds a @WHERE x ~ y@ condition to the query, where the column x is held by a joined table.
--
-- __Example:__ Find Posts by people with names with titles in front.
--
-- > articles <- query @Post
-- >     |> innerJoin @User (#createdBy, #id)
-- >     |> filterWhereMatchesJoinedTable (#title, "^(M(rs|r|iss|s)|Dr|Sir). ")
-- >     |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.title ~ '^(M(rs|r|iss|s)|Dr|Sir). '

filterWhereMatchesJoinedTable :: forall model table name value queryBuilderProvider joinRegister table'. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereMatchesJoinedTable :: forall {k1} model (table :: Symbol) (name :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1)
       (table' :: Symbol).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, table ~ GetTableName model,
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereMatchesJoinedTable (Proxy name
name, value
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, MatchSensitivity -> FilterOperator
MatchesOp MatchSensitivity
CaseSensitive, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereMatchesJoinedTable #-}


-- | Adds a @WHERE x ~* y@ condition to the query. Case-insensitive version of 'filterWhereMatches'.
filterWhereIMatches :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereIMatches :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereIMatches (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, MatchSensitivity -> FilterOperator
MatchesOp MatchSensitivity
CaseInsensitive, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereIMatches #-}

-- | Case-insensitive version of 'filterWhereMatchesJoinedTable'
filterWhereIMatchesJoinedTable :: forall model table name value queryBuilderProvider joinRegister table'. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereIMatchesJoinedTable :: forall {k1} model (table :: Symbol) (name :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k1)
       (table' :: Symbol).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, table ~ GetTableName model,
 HasQueryBuilder queryBuilderProvider joinRegister,
 IsJoined model joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereIMatchesJoinedTable (Proxy name
name, value
value) queryBuilderProvider table'
queryBuilderProvider = QueryBuilder table' -> queryBuilderProvider table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder :: QueryBuilder table'
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, MatchSensitivity -> FilterOperator
MatchesOp MatchSensitivity
CaseInsensitive, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table'
queryBuilder = queryBuilderProvider table' -> QueryBuilder table'
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table'
queryBuilderProvider
{-# INLINE filterWhereIMatchesJoinedTable #-}


-- | Filter all rows by whether a field is in the past, determined by comparing 'NOW()' to the field's value.
--
-- Opposite of 'filterWhereFuture'
--
-- __Example:__ Fetch all posts scheduled for the past.
--
-- > publicPosts <- query @Post
-- >     |> filterWherePast #scheduledAt
-- >     |> fetch
-- > -- SELECT * FROM posts WHERE scheduled_at <= NOW()
filterWherePast
    :: ( KnownSymbol table
       , KnownSymbol name
       , HasField name (GetModelByTableName table) value
       , HasQueryBuilder queryBuilderProvider joinRegister
       , Table (GetModelByTableName table)
       )
    => Proxy name -> queryBuilderProvider table -> queryBuilderProvider table
filterWherePast :: forall {k} (table :: Symbol) (name :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name,
 HasField name (GetModelByTableName table) value,
 HasQueryBuilder queryBuilderProvider joinRegister,
 Table (GetModelByTableName table)) =>
Proxy name
-> queryBuilderProvider table -> queryBuilderProvider table
filterWherePast Proxy name
name = (Proxy name, Text)
-> queryBuilderProvider table -> queryBuilderProvider table
forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, HasField name model value,
 model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, Text)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereSql (Proxy name
name, Text
"<= NOW()")
{-# INLINE filterWherePast #-}

-- | Filter all rows by whether a field is in the future, determined by comparing 'NOW()' to the field's value.
--
-- Opposite of 'filterWherePast'
--
-- __Example:__ Fetch all posts scheduled for the future.
--
-- > hiddenPosts <- query @Post
-- >     |> filterWhereFuture #scheduledAt
-- >     |> fetch
-- > -- SELECT * FROM posts WHERE scheduled_at > NOW()
filterWhereFuture
    :: ( KnownSymbol table
       , KnownSymbol name
       , HasField name (GetModelByTableName table) value
       , HasQueryBuilder queryBuilderProvider joinRegister
       , Table (GetModelByTableName table)
       )
    => Proxy name -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereFuture :: forall {k} (table :: Symbol) (name :: Symbol) value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name,
 HasField name (GetModelByTableName table) value,
 HasQueryBuilder queryBuilderProvider joinRegister,
 Table (GetModelByTableName table)) =>
Proxy name
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereFuture Proxy name
name = (Proxy name, Text)
-> queryBuilderProvider table -> queryBuilderProvider table
forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, HasField name model value,
 model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, Text)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereSql (Proxy name
name, Text
"> NOW()")
{-# INLINE filterWhereFuture #-}

-- | Adds a @WHERE x > y@ condition to the query.
--
-- __Example:__ Find assignments with grade greater than 80.
--
-- > greatAssignments <- query @Assignment
-- >     |> filterWhereGreaterThan (#grade, 80)
-- >     |> fetch
-- > -- SELECT * FROM assignments WHERE grade > 80
--
-- See also: 'filterWhereLarger', 'filterWhereGreaterThanOrEqualTo', 'filterWhereAtLeast'
filterWhereGreaterThan :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereGreaterThan :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereGreaterThan (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
GreaterThanOp, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereGreaterThan #-}

-- | Alias for 'filterWhereGreaterThan'. Adds a @WHERE x > y@ condition to the query.
--
-- __Example:__ Find assignments with grade larger than 80.
--
-- > greatAssignments <- query @Assignment
-- >     |> filterWhereLarger (#grade, 80)
-- >     |> fetch
-- > -- SELECT * FROM assignments WHERE grade > 80
filterWhereLarger :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLarger :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLarger = (Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereGreaterThan
{-# INLINE filterWhereLarger #-}

-- | Adds a @WHERE x >= y@ condition to the query.
--
-- __Example:__ Find assignments with grade at least 80.
--
-- > greatAssignments <- query @Assignment
-- >     |> filterWhereGreaterThanOrEqualTo (#grade, 80)
-- >     |> fetch
-- > -- SELECT * FROM assignments WHERE grade >= 80
--
-- See also: 'filterWhereAtLeast', 'filterWhereGreaterThan', 'filterWhereLarger'
filterWhereGreaterThanOrEqualTo :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereGreaterThanOrEqualTo :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereGreaterThanOrEqualTo (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
GreaterThanOrEqualToOp, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereGreaterThanOrEqualTo #-}

-- | Alias for 'filterWhereGreaterThanOrEqualTo'. Adds a @WHERE x >= y@ condition to the query.
--
-- __Example:__ Find assignments with grade at least 80.
--
-- > greatAssignments <- query @Assignment
-- >     |> filterWhereAtLeast (#grade, 80)
-- >     |> fetch
-- > -- SELECT * FROM assignments WHERE grade >= 80
filterWhereAtLeast :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereAtLeast :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereAtLeast = (Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereGreaterThanOrEqualTo
{-# INLINE filterWhereAtLeast #-}

-- | Adds a @WHERE x < y@ condition to the query.
--
-- __Example:__ Find assignments with grade less than 60.
--
-- > poorAssignments <- query @Assignment
-- >     |> filterWhereLessThan (#grade, 60)
-- >     |> fetch
-- > -- SELECT * FROM assignments WHERE grade < 60
--
-- See also: 'filterWhereSmaller', 'filterWhereLessThanOrEqualTo', 'filterWhereAtMost'
filterWhereLessThan :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLessThan :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLessThan (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
LessThanOp, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereLessThan #-}

-- | Alias for 'filterWhereLessThan'. Adds a @WHERE x < y@ condition to the query.
--
-- __Example:__ Find assignments with grade smaller than 60.
--
-- > poorAssignments <- query @Assignment
-- >     |> filterWhereSmaller (#grade, 60)
-- >     |> fetch
-- > -- SELECT * FROM assignments WHERE grade < 60
filterWhereSmaller :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereSmaller :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereSmaller = (Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLessThan
{-# INLINE filterWhereSmaller #-}

-- | Adds a @WHERE x <= y@ condition to the query.
--
-- __Example:__ Find assignments with grade at most 60.
--
-- > poorAssignments <- query @Assignment
-- >     |> filterWhereLessThanOrEqualTo (#grade, 60)
-- >     |> fetch
-- > -- SELECT * FROM assignments WHERE grade <= 60
--
-- See also: 'filterWhereAtMost', 'filterWhereLessThan', 'filterWhereSmaller'
filterWhereLessThanOrEqualTo :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLessThanOrEqualTo :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLessThanOrEqualTo (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
LessThanOrEqualToOp, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereLessThanOrEqualTo #-}

-- | Alias for 'filterWhereLessThanOrEqualTo'. Adds a @WHERE x <= y@ condition to the query.
--
-- __Example:__ Find assignments with grade at most 60.
--
-- > poorAssignments <- query @Assignment
-- >     |> filterWhereAtMost (#grade, 60)
-- >     |> fetch
-- > -- SELECT * FROM assignments WHERE grade <= 60
filterWhereAtMost :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereAtMost :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereAtMost = (Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereLessThanOrEqualTo
{-# INLINE filterWhereAtMost #-}


-- | Allows to add a custom raw sql where condition
--
-- If your query cannot be represented with 'filterWhereSql', take a look at 'IHP.ModelSupport.sqlQuery'.
--
-- __Example:__ Fetching all projects created in the last 24 hours.
--
-- > latestProjects <- query @Project
-- >     |> filterWhereSql (#startedAt, "< current_timestamp - interval '1 day'")
-- >     |> fetch
-- > -- SELECT * FROM projects WHERE started_at < current_timestamp - interval '1 day'
--
filterWhereSql :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, HasField name model value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, Text) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereSql :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, HasField name model value,
 model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, Text)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereSql (Proxy name
name, Text
sqlCondition) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, FilterOperator
SqlOp, Text -> Snippet
Snippet.sql Text
sqlCondition), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereSql #-}

-- | Adds a @WHERE LOWER(x) = LOWER(y)@ condition to the query.
--
-- __Example:__ Get a user by an email address, ignoring case
--
-- > user <- query @User
-- >     |> filterWhereCaseInsensitive (#email, "marc@digitallyinduced.com")
-- >     |> fetchOne
-- > -- SELECT * FROM users WHERE LOWER(email) = 'marc@digitallyinduced.com'
--
-- For high performance it's best to have an index for @LOWER(field)@ in your Schema.sql
--
-- >>> CREATE UNIQUE INDEX users_email_index ON users ((LOWER(email)));
--
filterWhereCaseInsensitive :: forall name table model value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, DefaultParamEncoder value, HasField name model value, EqOrIsOperator value, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereCaseInsensitive :: forall {k} (name :: Symbol) (table :: Symbol) model value
       (queryBuilderProvider :: Symbol -> *) (joinRegister :: k).
(KnownSymbol table, KnownSymbol name, DefaultParamEncoder value,
 HasField name model value, EqOrIsOperator value,
 model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister, Table model) =>
(Proxy name, value)
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereCaseInsensitive (Proxy name
name, value
value) queryBuilderProvider table
queryBuilderProvider = QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder FilterByQueryBuilder { QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (Text
columnName, value -> FilterOperator
forall value. EqOrIsOperator value => value -> FilterOperator
toEqOrIsOperator value
value, value -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param value
value), applyLeft :: Maybe Text
applyLeft = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"LOWER", applyRight :: Maybe Text
applyRight = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"LOWER" }
    where
        columnName :: Text
columnName = Text -> Text -> Text
qualifiedColumnName (forall record. Table record => Text
tableName @model) (forall (symbol :: Symbol). KnownSymbol symbol => Text
symbolToText @name)
        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider
{-# INLINE filterWhereCaseInsensitive #-}


filterWhereIdIn :: forall table model queryBuilderProvider (joinRegister :: Type). (KnownSymbol table, Table model, model ~ GetModelByTableName table, HasQueryBuilder queryBuilderProvider joinRegister, DefaultParamEncoder [PrimaryKey (GetTableName model)]) => [Id model] -> queryBuilderProvider table -> queryBuilderProvider table
filterWhereIdIn :: forall (table :: Symbol) model
       (queryBuilderProvider :: Symbol -> *) joinRegister.
(KnownSymbol table, Table model, model ~ GetModelByTableName table,
 HasQueryBuilder queryBuilderProvider joinRegister,
 DefaultParamEncoder [PrimaryKey (GetTableName model)]) =>
[Id model]
-> queryBuilderProvider table -> queryBuilderProvider table
filterWhereIdIn [Id model]
values queryBuilderProvider table
queryBuilderProvider =
    -- We don't need to treat null values differently here, because primary keys imply not-null
    -- Extract the raw primary key values from the Id wrappers
    let
        rawPrimaryKeys :: [PrimaryKey (GetTableName model)]
rawPrimaryKeys = (Id model -> PrimaryKey (GetTableName model))
-> [Id model] -> [PrimaryKey (GetTableName model)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Id PrimaryKey (GetTableName model)
pk) -> PrimaryKey (GetTableName model)
pk) [Id model]
values

        queryBuilder :: QueryBuilder table
queryBuilder = queryBuilderProvider table -> QueryBuilder table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
queryBuilderProvider table -> QueryBuilder table
forall (table :: Symbol).
queryBuilderProvider table -> QueryBuilder table
getQueryBuilder queryBuilderProvider table
queryBuilderProvider

        whereInQuery :: QueryBuilder table
whereInQuery = FilterByQueryBuilder {QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder :: QueryBuilder table
queryBuilder, queryFilter :: (Text, FilterOperator, Snippet)
queryFilter = (forall record. Table record => Text
primaryKeyConditionColumnSelector @model, FilterOperator
InOp, [PrimaryKey (GetTableName model)] -> Snippet
forall param. DefaultParamEncoder param => param -> Snippet
Snippet.param [PrimaryKey (GetTableName model)]
rawPrimaryKeys), applyLeft :: Maybe Text
applyLeft = Maybe Text
forall a. Maybe a
Nothing, applyRight :: Maybe Text
applyRight = Maybe Text
forall a. Maybe a
Nothing}
     in
        QueryBuilder table -> queryBuilderProvider table
forall {k} (queryBuilderProvider :: Symbol -> *)
       (joinRegister :: k) (table :: Symbol).
HasQueryBuilder queryBuilderProvider joinRegister =>
QueryBuilder table -> queryBuilderProvider table
forall (table :: Symbol).
QueryBuilder table -> queryBuilderProvider table
injectQueryBuilder QueryBuilder table
whereInQuery
{-# INLINE filterWhereIdIn #-}