New text-related functions like, (%), concat_ and (++.).

This commit is contained in:
Felipe Lessa 2012-09-09 12:20:15 -03:00
parent 7df5fe0edd
commit 5a0974f4c0
4 changed files with 43 additions and 1 deletions

View File

@ -23,6 +23,7 @@ module Database.Esqueleto
, val, isNothing, just, nothing, countRows, not_
, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
, (+.), (-.), (/.), (*.)
, like, (%), concat_, (++.)
, set, (=.), (+=.), (-=.), (*=.), (/=.) )
, from
, Value(..)

View File

@ -33,6 +33,7 @@ module Database.Esqueleto.Internal.Language
import Control.Applicative (Applicative(..), (<$>))
import Control.Exception (Exception)
import Data.String (IsString)
import Data.Typeable (Typeable)
import Database.Persist.GenericSql
import Database.Persist.Store
@ -183,6 +184,25 @@ class (Functor query, Applicative query, Monad query) =>
(/.) :: PersistField a => expr (Value a) -> expr (Value a) -> expr (Value a)
(*.) :: PersistField a => expr (Value a) -> expr (Value a) -> expr (Value a)
-- | @LIKE@ operator.
like :: (PersistField s, IsString s) => expr (Value s) -> expr (Value s) -> expr (Value Bool)
-- | The string @'%'@. May be useful while using 'like' and
-- concatenation ('concat_' or '++.', depending on your
-- database). Note that you always to type the parenthesis,
-- for example:
--
-- @
-- name ``'like'`` (%) ++. val "John" ++. (%)
-- @
(%) :: (PersistField s, IsString s) => expr (Value s)
-- | The @CONCAT@ function with a variable number of
-- parameters. Supported by MySQL and PostgreSQL.
concat_ :: (PersistField s, IsString s) => [expr (Value s)] -> expr (Value s)
-- | The @||@ string concatenation operator (named after
-- Haskell's '++' in order to avoid naming clash with '||.').
-- Supported by SQLite and PostgreSQL.
(++.) :: (PersistField s, IsString s) => expr (Value s) -> expr (Value s) -> expr (Value s)
-- | @SET@ clause used on @UPDATE@s. Note that while it's not
-- a type error to use this function on a @SELECT@, it will
-- most certainly result in a runtime error.
@ -199,9 +219,10 @@ class (Functor query, Applicative query, Monad query) =>
infixl 9 ^.
infixl 7 *., /.
infixl 6 +., -.
infixr 5 ++.
infix 4 ==., >=., >., <=., <., !=.
infixr 3 &&., =., +=., -=., *=., /=.
infixr 2 ||., `InnerJoin`, `CrossJoin`, `LeftOuterJoin`, `RightOuterJoin`, `FullOuterJoin`
infixr 2 ||., `InnerJoin`, `CrossJoin`, `LeftOuterJoin`, `RightOuterJoin`, `FullOuterJoin`, `like`
-- | A single value (as opposed to a whole entity). You may use

View File

@ -294,6 +294,11 @@ instance Esqueleto SqlQuery SqlExpr SqlPersist where
(/.) = unsafeSqlBinOp " / "
(*.) = unsafeSqlBinOp " * "
like = unsafeSqlBinOp " LIKE "
(%) = unsafeSqlValue "'%'"
concat_ = unsafeSqlFunction "CONCAT"
(++.) = unsafeSqlBinOp " || "
set ent upds = Q $ W.tell mempty { sdSetClause = map apply upds }
where
apply (ESet f) = SetClause (f ent)

View File

@ -344,6 +344,21 @@ main = do
return title
liftIO $ ret `shouldBe` [ Value t1, Value t2, Value t3 ]
describe "text functions" $
it "like, (%) and (++.) work on a simple example" $
run $ do
[p1e, p2e, p3e, p4e] <- mapM insert' [p1, p2, p3, p4]
let nameContains t expected = do
ret <- select $
from $ \p -> do
where_ (p ^. PersonName `like` (%) ++. val t ++. (%))
orderBy [asc (p ^. PersonName)]
return p
liftIO $ ret `shouldBe` expected
nameContains "h" [p1e, p2e]
nameContains "i" [p4e, p3e]
nameContains "iv" [p4e]
describe "delete" $
it "works on a simple example" $
run $ do