From 6d8b84c55c0121046f9e44b06cc730482f6d908d Mon Sep 17 00:00:00 2001 From: Felipe Lessa Date: Sun, 27 Jan 2013 17:28:00 -0200 Subject: [PATCH] valList [] now works. --- src/Database/Esqueleto/Internal/Sql.hs | 18 +++++++++++++----- test/Test.hs | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/Database/Esqueleto/Internal/Sql.hs b/src/Database/Esqueleto/Internal/Sql.hs index 8d95e52..4f92c53 100644 --- a/src/Database/Esqueleto/Internal/Sql.hs +++ b/src/Database/Esqueleto/Internal/Sql.hs @@ -229,6 +229,7 @@ data SqlExpr a where EMaybe :: SqlExpr a -> SqlExpr (Maybe a) ERaw :: NeedParens -> (Connection -> (TLB.Builder, [PersistValue])) -> SqlExpr (Value a) EList :: SqlExpr (Value a) -> SqlExpr (ValueList a) + EEmptyList :: SqlExpr (ValueList a) EOrderBy :: OrderByType -> SqlExpr (Value a) -> SqlExpr OrderBy ESet :: (SqlExpr (Entity val) -> SqlExpr (Value ())) -> SqlExpr (Update val) EPreprocessedFrom :: a -> FromClause -> SqlExpr (PreprocessedFrom a) @@ -299,7 +300,7 @@ instance Esqueleto SqlQuery SqlExpr SqlBackend where val = ERaw Never . const . (,) "?" . return . toPersistValue - isNothing (ERaw p f) = ERaw Never $ first ((<> " IS NULL") . parensM p) . f + isNothing (ERaw p f) = ERaw Parens $ first ((<> " IS NULL") . parensM p) . f just (ERaw p f) = ERaw p f nothing = unsafeSqlValue "NULL" countRows = unsafeSqlValue "COUNT(*)" @@ -328,11 +329,12 @@ instance Esqueleto SqlQuery SqlExpr SqlBackend where subList_select = EList . sub_select subList_selectDistinct = EList . sub_selectDistinct + valList [] = EEmptyList valList vals = EList $ ERaw Parens $ const ( uncommas ("?" <$ vals) , map toPersistValue vals ) - v `in_` e = unsafeSqlBinOp " IN " v (veryUnsafeCoerceSqlExprValueList e) - v `notIn` e = unsafeSqlBinOp " NOT IN " v (veryUnsafeCoerceSqlExprValueList e) + v `in_` e = ifNotEmptyList e False $ unsafeSqlBinOp " IN " v (veryUnsafeCoerceSqlExprValueList e) + v `notIn` e = ifNotEmptyList e True $ unsafeSqlBinOp " NOT IN " v (veryUnsafeCoerceSqlExprValueList e) exists = unsafeSqlFunction "EXISTS " . existsHelper notExists = unsafeSqlFunction "NOT EXISTS " . existsHelper @@ -374,6 +376,10 @@ existsHelper = flip (toRawSql SELECT) . (>> return (val True :: SqlExpr (Value Bool))) +ifNotEmptyList :: SqlExpr (ValueList a) -> Bool -> SqlExpr (Value Bool) -> SqlExpr (Value Bool) +ifNotEmptyList EEmptyList b _ = val b +ifNotEmptyList (EList _) _ x = x + ---------------------------------------------------------------------- @@ -449,9 +455,11 @@ veryUnsafeCoerceSqlExprValue (ERaw p f) = ERaw p f -- | (Internal) Coerce a value's type from 'SqlExpr (ValueList --- a)' to 'SqlExpr (Value a)'. +-- a)' to 'SqlExpr (Value a)'. Does not work with empty lists. veryUnsafeCoerceSqlExprValueList :: SqlExpr (ValueList a) -> SqlExpr (Value a) -veryUnsafeCoerceSqlExprValueList (EList v) = v +veryUnsafeCoerceSqlExprValueList (EList v) = v +veryUnsafeCoerceSqlExprValueList EEmptyList = + error "veryUnsafeCoerceSqlExprValueList: empty list." ---------------------------------------------------------------------- diff --git a/test/Test.hs b/test/Test.hs index dfcb849..0bddffc 100644 --- a/test/Test.hs +++ b/test/Test.hs @@ -271,6 +271,16 @@ main = do return p liftIO $ ret `shouldBe` [ p2e ] + it "works with not_ . isNothing" $ + run $ do + p1e <- insert' p1 + _ <- insert' p2 + ret <- select $ + from $ \p -> do + where_ $ not_ (isNothing (p ^. PersonAge)) + return p + liftIO $ ret `shouldBe` [ p1e ] + it "works for a many-to-many implicit join" $ run $ do p1e@(Entity p1k _) <- insert' p1 @@ -476,6 +486,17 @@ main = do liftIO $ ret `shouldBe` [ Entity p1k p1 , Entity p2k p2 ] + it "IN works for valList (null list)" $ + run $ do + p1k <- insert p1 + p2k <- insert p2 + p3k <- insert p3 + ret <- select $ + from $ \p -> do + where_ (p ^. PersonName `in_` valList []) + return p + liftIO $ ret `shouldBe` [] + it "IN works for subList_select" $ run $ do p1k <- insert p1