fradrive/src/Database/Esqueleto/Utils.hs
SJost 2ddda4578e Generic Columns module allowing generic sorting and filtering.
Done for an initial part of course participant table.
2019-03-08 18:11:26 +01:00

74 lines
2.4 KiB
Haskell

{-# OPTIONS_GHC -fno-warn-orphans #-}
module Database.Esqueleto.Utils
( true, false
, isInfixOf, hasInfix
, any, all
, SqlIn(..)
, mkInFilter
) where
import ClassyPrelude.Yesod hiding (isInfixOf, any, all)
import qualified Data.Set as Set
import qualified Data.Foldable as F
import qualified Database.Esqueleto as E
import Database.Esqueleto.Utils.TH
--
-- Description : Convenience for using @Esqueleto@,
-- intended to be imported qualified
-- just like Esqueleto
-- ezero = E.val (0 :: Int64)
-- | Often needed with this concrete type
true :: E.SqlExpr (E.Value Bool)
true = E.val True
-- | Often needed with this concrete type
false :: E.SqlExpr (E.Value Bool)
false = E.val False
-- | Check if the first string is contained in the text derived from the second argument
isInfixOf :: (E.Esqueleto query expr backend, E.SqlString s2) =>
Text -> expr (E.Value s2) -> expr (E.Value Bool)
isInfixOf needle strExpr = E.castString strExpr `E.ilike` (E.%) E.++. E.val needle E.++. (E.%)
hasInfix :: (E.Esqueleto query expr backend, E.SqlString s2) =>
expr (E.Value s2) -> Text -> expr (E.Value Bool)
hasInfix = flip isInfixOf
-- | Given a test and a set of values, check whether anyone succeeds the test
-- WARNING: SQL leaves it explicitely unspecified whether || is short curcuited (i.e. lazily evaluated)
any :: Foldable f =>
(a -> E.SqlExpr (E.Value Bool)) -> f a -> E.SqlExpr (E.Value Bool)
any test = F.foldr (\needle acc -> acc E.||. test needle) false
-- | Given a test and a set of values, check whether all succeeds the test
-- WARNING: SQL leaves it explicitely unspecified whether && is short curcuited (i.e. lazily evaluated)
all :: Foldable f =>
(a -> E.SqlExpr (E.Value Bool)) -> f a -> E.SqlExpr (E.Value Bool)
all test = F.foldr (\needle acc -> acc E.&&. test needle) true
$(sqlInTuples [2..16])
-- | generic filter creation for dbTable
-- Given a lens-like function, make filter
-- What I thought:
-- mkFilter :: (Foldable f, E.From query expr backend a)
-- => (a -> E.SqlExpr (E.Value b))
-- -> a
-- -> f b
-- -> E.SqlExpr (E.Value Bool)
-- What is inferred:
mkInFilter :: (PersistField a)
=> (t -> E.SqlExpr (E.Value a))
-> t
-> Set.Set a
-> E.SqlExpr (E.Value Bool)
mkInFilter lenslike row criterias
| Set.null criterias = true
| otherwise = (lenslike row) `E.in_` E.valList (Set.toList criterias)