Add between (#127)
* Update between so it works with SQL values * Add support for composite keys in between clause * Remove unused values from ERaw in construct * Update unsafeSqlBinOp to handle composite keys and between to use >=., <=. and &&. * Support composite keys in unsafeSqlBinOp correctly * Updated changelog * Update version number of between to 3.1.0
This commit is contained in:
parent
a452946f58
commit
5d8f5b53e6
@ -6,6 +6,8 @@ Unreleased
|
|||||||
|
|
||||||
- @Vlix
|
- @Vlix
|
||||||
- [#128](https://github.com/bitemyapp/esqueleto/pull/128): Added `Database.Esqueleto.PostgreSQL.JSON` module with JSON operators and `JSONB` data type.
|
- [#128](https://github.com/bitemyapp/esqueleto/pull/128): Added `Database.Esqueleto.PostgreSQL.JSON` module with JSON operators and `JSONB` data type.
|
||||||
|
- @ibarrae
|
||||||
|
- [#127](https://github.com/bitemyapp/esqueleto/pull/127): Added `between` and support for composite keys in `unsafeSqlBinOp`.
|
||||||
|
|
||||||
3.0.0
|
3.0.0
|
||||||
=======
|
=======
|
||||||
|
|||||||
@ -44,7 +44,7 @@ module Database.Esqueleto
|
|||||||
, val, isNothing, just, nothing, joinV, withNonNull
|
, val, isNothing, just, nothing, joinV, withNonNull
|
||||||
, countRows, count, countDistinct
|
, countRows, count, countDistinct
|
||||||
, not_, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
, not_, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
||||||
, (+.), (-.), (/.), (*.)
|
, between, (+.), (-.), (/.), (*.)
|
||||||
, random_, round_, ceiling_, floor_
|
, random_, round_, ceiling_, floor_
|
||||||
, min_, max_, sum_, avg_, castNum, castNumM
|
, min_, max_, sum_, avg_, castNum, castNumM
|
||||||
, coalesce, coalesceDefault
|
, coalesce, coalesceDefault
|
||||||
|
|||||||
@ -455,6 +455,11 @@ not_ (ECompositeKey _) = throw (CompositeKeyErr NotError)
|
|||||||
(*.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
|
(*.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
|
||||||
(*.) = unsafeSqlBinOp " * "
|
(*.) = unsafeSqlBinOp " * "
|
||||||
|
|
||||||
|
-- | @BETWEEN@.
|
||||||
|
--
|
||||||
|
-- @since: 3.1.0
|
||||||
|
between :: PersistField a => SqlExpr (Value a) -> (SqlExpr (Value a), SqlExpr (Value a)) -> SqlExpr (Value Bool)
|
||||||
|
a `between` (b, c) = a >=. b &&. a <=. c
|
||||||
|
|
||||||
random_ :: (PersistField a, Num a) => SqlExpr (Value a)
|
random_ :: (PersistField a, Num a) => SqlExpr (Value a)
|
||||||
random_ = unsafeSqlValue "RANDOM()"
|
random_ = unsafeSqlValue "RANDOM()"
|
||||||
@ -1242,7 +1247,6 @@ data CompositeKeyError =
|
|||||||
| CombineInsertionError
|
| CombineInsertionError
|
||||||
| FoldHelpError
|
| FoldHelpError
|
||||||
| SqlCaseError
|
| SqlCaseError
|
||||||
| SqlBinOpError
|
|
||||||
| SqlCastAsError
|
| SqlCastAsError
|
||||||
| MakeOnClauseError
|
| MakeOnClauseError
|
||||||
| MakeExcError
|
| MakeExcError
|
||||||
@ -1641,7 +1645,16 @@ unsafeSqlBinOp op (ERaw p1 f1) (ERaw p2 f2) = ERaw Parens f
|
|||||||
(b2, vals2) = f2 info
|
(b2, vals2) = f2 info
|
||||||
in ( parensM p1 b1 <> op <> parensM p2 b2
|
in ( parensM p1 b1 <> op <> parensM p2 b2
|
||||||
, vals1 <> vals2 )
|
, vals1 <> vals2 )
|
||||||
unsafeSqlBinOp _ _ _ = throw (CompositeKeyErr SqlBinOpError)
|
unsafeSqlBinOp op a b = unsafeSqlBinOp op (construct a) (construct b)
|
||||||
|
where construct :: SqlExpr (Value a) -> SqlExpr (Value a)
|
||||||
|
construct (ERaw p f) = ERaw Parens $ \info ->
|
||||||
|
let (b1, vals) = f info
|
||||||
|
build ("?", [PersistList vals']) =
|
||||||
|
(uncommas $ replicate (length vals') "?", vals')
|
||||||
|
build expr = expr
|
||||||
|
in build (parensM p b1, vals)
|
||||||
|
construct (ECompositeKey f) =
|
||||||
|
ERaw Parens $ \info -> (uncommas $ f info, mempty)
|
||||||
{-# INLINE unsafeSqlBinOp #-}
|
{-# INLINE unsafeSqlBinOp #-}
|
||||||
|
|
||||||
|
|
||||||
@ -2785,4 +2798,3 @@ insertSelect = void . insertSelectCount
|
|||||||
insertSelectCount :: (MonadIO m, PersistEntity a) =>
|
insertSelectCount :: (MonadIO m, PersistEntity a) =>
|
||||||
SqlQuery (SqlExpr (Insertion a)) -> SqlWriteT m Int64
|
SqlQuery (SqlExpr (Insertion a)) -> SqlWriteT m Int64
|
||||||
insertSelectCount = rawEsqueleto INSERT_INTO . fmap EInsertFinal
|
insertSelectCount = rawEsqueleto INSERT_INTO . fmap EInsertFinal
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ module Database.Esqueleto.Internal.Language
|
|||||||
, val, isNothing, just, nothing, joinV, withNonNull
|
, val, isNothing, just, nothing, joinV, withNonNull
|
||||||
, countRows, count, countDistinct
|
, countRows, count, countDistinct
|
||||||
, not_, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
, not_, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
||||||
, (+.), (-.), (/.), (*.)
|
, between, (+.), (-.), (/.), (*.)
|
||||||
, random_, round_, ceiling_, floor_
|
, random_, round_, ceiling_, floor_
|
||||||
, min_, max_, sum_, avg_, castNum, castNumM
|
, min_, max_, sum_, avg_, castNum, castNumM
|
||||||
, coalesce, coalesceDefault
|
, coalesce, coalesceDefault
|
||||||
|
|||||||
@ -630,6 +630,54 @@ testSelectWhere run = do
|
|||||||
return p
|
return p
|
||||||
liftIO $ ret `shouldBe` [ p3e ]
|
liftIO $ ret `shouldBe` [ p3e ]
|
||||||
|
|
||||||
|
describe "when using between" $ do
|
||||||
|
it "works for a simple example with [uses just . val]" $
|
||||||
|
run $ do
|
||||||
|
p1e <- insert' p1
|
||||||
|
_ <- insert' p2
|
||||||
|
_ <- insert' p3
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
where_ ((p ^. PersonAge) `between` (just $ val 20, just $ val 40))
|
||||||
|
return p
|
||||||
|
liftIO $ ret `shouldBe` [ p1e ]
|
||||||
|
it "works for a proyected fields value" $
|
||||||
|
run $ do
|
||||||
|
_ <- insert' p1 >> insert' p2 >> insert' p3
|
||||||
|
ret <-
|
||||||
|
select $
|
||||||
|
from $ \p -> do
|
||||||
|
where_ $
|
||||||
|
just (p ^. PersonFavNum)
|
||||||
|
`between`
|
||||||
|
(p ^. PersonAge, p ^. PersonWeight)
|
||||||
|
liftIO $ ret `shouldBe` []
|
||||||
|
describe "when projecting composite keys" $ do
|
||||||
|
it "works when using composite keys with val" $
|
||||||
|
run $ do
|
||||||
|
insert_ $ Point 1 2 ""
|
||||||
|
ret <-
|
||||||
|
select $
|
||||||
|
from $ \p -> do
|
||||||
|
where_ $
|
||||||
|
p ^. PointId
|
||||||
|
`between`
|
||||||
|
( val $ PointKey 1 2
|
||||||
|
, val $ PointKey 5 6 )
|
||||||
|
liftIO $ ret `shouldBe` [()]
|
||||||
|
it "works when using ECompositeKey constructor" $
|
||||||
|
run $ do
|
||||||
|
insert_ $ Point 1 2 ""
|
||||||
|
ret <-
|
||||||
|
select $
|
||||||
|
from $ \p -> do
|
||||||
|
where_ $
|
||||||
|
p ^. PointId
|
||||||
|
`between`
|
||||||
|
( EI.ECompositeKey $ const ["3", "4"]
|
||||||
|
, EI.ECompositeKey $ const ["5", "6"] )
|
||||||
|
liftIO $ ret `shouldBe` []
|
||||||
|
|
||||||
it "works with avg_" $
|
it "works with avg_" $
|
||||||
run $ do
|
run $ do
|
||||||
_ <- insert' p1
|
_ <- insert' p1
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user