diff --git a/examples/Main.hs b/examples/Main.hs index 451044b..aa29cd4 100644 --- a/examples/Main.hs +++ b/examples/Main.hs @@ -10,6 +10,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-unused-top-binds #-} @@ -19,15 +20,14 @@ module Main ) where import Blog -import Control.Monad (void) -import Control.Monad (forM_) +import Control.Monad (forM_, void) import Control.Monad.IO.Class (MonadIO, liftIO) import Control.Monad.IO.Unlift (MonadUnliftIO) import Control.Monad.Logger (MonadLogger) import Control.Monad.Reader (MonadReader(..), runReaderT) import Control.Monad.Trans.Control (MonadBaseControl) import Data.Monoid ((<>)) -import Database.Esqueleto +import Database.Esqueleto.Experimental import Database.Persist.Postgresql (ConnectionString, withPostgresqlConn) import Database.Persist.TH ( AtLeastOneUniqueKey(..) @@ -62,9 +62,9 @@ putPersons :: (MonadIO m, MonadLogger m) => SqlPersistT m () putPersons = do -- | Select all values from the `person` table - people <- select $ - from $ \person -> do - return person + people <- select $ do + person <- from $ table @Person + return person -- | entityVal extracts the Person value, which we then extract -- | the person name from the record and print it @@ -75,8 +75,8 @@ getJohns :: (MonadIO m, MonadLogger m) => SqlReadT m [Entity Person] getJohns = -- | Select all persons where their name is equal to "John" - select $ - from $ \p -> do + select $ do + p <- from $ table @Person where_ (p ^. PersonName ==. val "John") return p @@ -85,8 +85,8 @@ getAdults :: (MonadIO m, MonadLogger m) => SqlReadT m [Entity Person] getAdults = -- | Select any Person where their age is >= 18 and NOT NULL - select $ - from $ \p -> do + select $ do + p <- from $ table @Person where_ (p ^. PersonAge >=. just (val 18)) return p @@ -95,8 +95,10 @@ getBlogPostsByAuthors :: (MonadIO m, MonadLogger m) => SqlReadT m [(Entity BlogPost, Entity Person)] getBlogPostsByAuthors = -- | Select all persons and their blogposts, ordering by title - select $ - from $ \(b, p) -> do + select $ do + p :& b <- + from $ table @Person + `crossJoin` table @BlogPost where_ (b ^. BlogPostAuthorId ==. p ^. PersonId) orderBy [asc (b ^. BlogPostTitle)] return (b, p) @@ -108,9 +110,11 @@ getAuthorMaybePosts = -- | Select all persons doing a left outer join on blogposts -- | Since a person may not have any blogposts the BlogPost Entity is wrapped -- | in a Maybe - select $ - from $ \(p `LeftOuterJoin` mb) -> do - on (just (p ^. PersonId) ==. mb ?. BlogPostAuthorId) + select $ do + (p :& mb) <- + from $ table @Person + `leftJoin` table @BlogPost + `on` (\(p :& mb) -> (just (p ^. PersonId) ==. mb ?. BlogPostAuthorId)) orderBy [asc (p ^. PersonName), asc (mb ?. BlogPostTitle)] return (p, mb) @@ -122,10 +126,13 @@ followers = -- | Note carefully that the order of the ON clauses is reversed! -- | You're required to write your ons in reverse order because that helps composability -- | (see the documentation of on for more details). - select $ - from $ \(p1 `InnerJoin` f `InnerJoin` p2) -> do - on (p2 ^. PersonId ==. f ^. FollowFollowed) - on (p1 ^. PersonId ==. f ^. FollowFollower) + select $ do + (p1 :& f :& p2) <- + from $ table @Person + `innerJoin` table @Follow + `on` (\(p1 :& f) -> p1 ^. PersonId ==. f ^. FollowFollower) + `innerJoin` table @Person + `on` (\(_ :& f :& p2) -> p2 ^. PersonId ==. f ^. FollowFollowed) return (p1, f, p2) @@ -146,8 +153,8 @@ deleteYoungsters = do -- | In this case where `ON DELETE CASCADE` is not generated by migration -- | we select all the entities we want to delete and then for each one -- | one we extract the key and use Persistent's `deleteCascade` - youngsters <- select $ - from $ \p -> do + youngsters <- select $ do + p <- from $ table @Person where_ (p ^. PersonAge <. just (val 14)) pure p forM_ youngsters (deleteCascade . entityKey) @@ -157,7 +164,8 @@ insertBlogPosts :: (MonadIO m, MonadLogger m) => SqlWriteT m () insertBlogPosts = -- | Insert a new blogpost for every person - insertSelect $ from $ \p -> + insertSelect $ do + p <- from $ table @Person return $ BlogPost <# (val "Group Blog Post") <&> (p ^. PersonId) diff --git a/src/Database/Esqueleto.hs b/src/Database/Esqueleto.hs index fadeb24..ac98b24 100644 --- a/src/Database/Esqueleto.hs +++ b/src/Database/Esqueleto.hs @@ -1,8 +1,8 @@ -{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE PatternSynonyms #-} -{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE RankNTypes #-} -- | The @esqueleto@ EDSL (embedded domain specific language). -- This module replaces @Database.Persist@, so instead of -- importing that module you should just import this one: @@ -126,13 +126,13 @@ module Database.Esqueleto , module Database.Esqueleto.Internal.PersistentImport ) where -import Control.Monad.IO.Class (MonadIO) -import Control.Monad.Trans.Reader (ReaderT) -import Data.Int (Int64) -import qualified Data.Map.Strict as Map -import Database.Esqueleto.Internal.Language -import Database.Esqueleto.Internal.PersistentImport -import Database.Esqueleto.Internal.Sql +import Control.Monad.IO.Class (MonadIO) +import Control.Monad.Trans.Reader (ReaderT) +import Data.Int (Int64) +import qualified Data.Map.Strict as Map +import Database.Esqueleto.Internal.Language +import Database.Esqueleto.Internal.PersistentImport +import Database.Esqueleto.Internal.Sql import qualified Database.Persist diff --git a/src/Database/Esqueleto/Experimental.hs b/src/Database/Esqueleto/Experimental.hs index ce3303f..3dc8b44 100644 --- a/src/Database/Esqueleto/Experimental.hs +++ b/src/Database/Esqueleto/Experimental.hs @@ -219,19 +219,16 @@ module Database.Esqueleto.Experimental , module Database.Esqueleto.Internal.PersistentImport ) where -import Database.Esqueleto.Internal.Internal hiding - (From, - from, - on) -import Database.Esqueleto.Internal.PersistentImport +import Database.Esqueleto.Internal.Internal hiding (From, from, on) +import Database.Esqueleto.Internal.PersistentImport -import Database.Esqueleto.Experimental.From -import Database.Esqueleto.Experimental.From.CommonTableExpression -import Database.Esqueleto.Experimental.From.Join -import Database.Esqueleto.Experimental.From.SqlSetOperation -import Database.Esqueleto.Experimental.ToAlias -import Database.Esqueleto.Experimental.ToAliasReference -import Database.Esqueleto.Experimental.ToMaybe +import Database.Esqueleto.Experimental.From +import Database.Esqueleto.Experimental.From.CommonTableExpression +import Database.Esqueleto.Experimental.From.Join +import Database.Esqueleto.Experimental.From.SqlSetOperation +import Database.Esqueleto.Experimental.ToAlias +import Database.Esqueleto.Experimental.ToAliasReference +import Database.Esqueleto.Experimental.ToMaybe -- $setup -- diff --git a/src/Database/Esqueleto/Experimental/From/Join.hs b/src/Database/Esqueleto/Experimental/From/Join.hs index c685adc..6d847f1 100644 --- a/src/Database/Esqueleto/Experimental/From/Join.hs +++ b/src/Database/Esqueleto/Experimental/From/Join.hs @@ -1,37 +1,32 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} module Database.Esqueleto.Experimental.From.Join where -import Data.Bifunctor (first) -import Data.Kind (Constraint) -import Data.Proxy -import qualified Data.Text.Lazy.Builder as TLB -import Database.Esqueleto.Experimental.From -import Database.Esqueleto.Experimental.From.SqlSetOperation -import Database.Esqueleto.Experimental.ToAlias -import Database.Esqueleto.Experimental.ToAliasReference -import Database.Esqueleto.Experimental.ToMaybe -import Database.Esqueleto.Internal.Internal hiding - (From (..), - from, - fromJoin, - on) -import Database.Esqueleto.Internal.PersistentImport (Entity (..), - EntityField, - PersistEntity, - PersistField) -import GHC.TypeLits +import Data.Bifunctor (first) +import Data.Kind (Constraint) +import Data.Proxy +import qualified Data.Text.Lazy.Builder as TLB +import Database.Esqueleto.Experimental.From +import Database.Esqueleto.Experimental.From.SqlSetOperation +import Database.Esqueleto.Experimental.ToAlias +import Database.Esqueleto.Experimental.ToAliasReference +import Database.Esqueleto.Experimental.ToMaybe +import Database.Esqueleto.Internal.Internal hiding + (From(..), from, fromJoin, on) +import Database.Esqueleto.Internal.PersistentImport + (Entity(..), EntityField, PersistEntity, PersistField) +import GHC.TypeLits -- | A left-precedence pair. Pronounced \"and\". Used to represent expressions -- that have been joined together. @@ -65,7 +60,7 @@ instance ValidOnClause (a -> SqlQuery b) -- \`on\` (\\(p :& bP) -> -- p ^. PersonId ==. bP ^. BlogPostAuthorId) -- @ -on :: ValidOnClause a => a -> (b -> SqlExpr (Value Bool)) -> (a, b -> SqlExpr (Value Bool)) +on :: ValidOnClause a => a -> (b -> SqlExpr Bool) -> (a, b -> SqlExpr Bool) on = (,) infix 9 `on` @@ -73,7 +68,7 @@ type family ErrorOnLateral a :: Constraint where ErrorOnLateral (a -> SqlQuery b) = TypeError ('Text "LATERAL can only be used for INNER, LEFT, and CROSS join kinds.") ErrorOnLateral _ = () -fromJoin :: TLB.Builder -> RawFn -> RawFn -> Maybe (SqlExpr (Value Bool)) -> RawFn +fromJoin :: TLB.Builder -> RawFn -> RawFn -> Maybe (SqlExpr Bool) -> RawFn fromJoin joinKind lhs rhs monClause = \paren info -> first (parensM paren) $ @@ -86,14 +81,14 @@ fromJoin joinKind lhs rhs monClause = makeOnClause info (ERaw _ f) = first (" ON " <>) (f Never info) type family HasOnClause actual expected :: Constraint where - HasOnClause (a, b -> SqlExpr (Value Bool)) c = () -- Let the compiler handle the type mismatch + HasOnClause (a, b -> SqlExpr Bool) c = () -- Let the compiler handle the type mismatch HasOnClause a expected = TypeError ( 'Text "Missing ON clause for join with" ':$$: 'ShowType a ':$$: 'Text "" ':$$: 'Text "Expected: " ':$$: 'ShowType a - ':$$: 'Text "`on` " ':<>: 'ShowType (expected -> SqlExpr (Value Bool)) + ':$$: 'Text "`on` " ':<>: 'ShowType (expected -> SqlExpr Bool) ':$$: 'Text "" ) @@ -114,7 +109,7 @@ type family HasOnClause actual expected :: Constraint where innerJoin :: ( ToFrom a a' , ToFrom b b' , HasOnClause rhs (a' :& b') - , rhs ~ (b, (a' :& b') -> SqlExpr (Value Bool)) + , rhs ~ (b, (a' :& b') -> SqlExpr Bool) ) => a -> rhs -> From (a' :& b') innerJoin lhs (rhs, on') = From $ do (leftVal, leftFrom) <- unFrom (toFrom lhs) @@ -138,7 +133,7 @@ innerJoinLateral :: ( ToFrom a a' , SqlSelect b r , ToAlias b , ToAliasReference b - , rhs ~ (a' -> SqlQuery b, (a' :& b) -> SqlExpr (Value Bool)) + , rhs ~ (a' -> SqlQuery b, (a' :& b) -> SqlExpr Bool) ) => a -> rhs -> From (a' :& b) innerJoinLateral lhs (rhsFn, on') = From $ do @@ -210,7 +205,7 @@ leftJoin :: ( ToFrom a a' , ToFrom b b' , ToMaybe b' , HasOnClause rhs (a' :& ToMaybeT b') - , rhs ~ (b, (a' :& ToMaybeT b') -> SqlExpr (Value Bool)) + , rhs ~ (b, (a' :& ToMaybeT b') -> SqlExpr Bool) ) => a -> rhs -> From (a' :& ToMaybeT b') leftJoin lhs (rhs, on') = From $ do (leftVal, leftFrom) <- unFrom (toFrom lhs) @@ -236,7 +231,7 @@ leftJoinLateral :: ( ToFrom a a' , ToAlias b , ToAliasReference b , ToMaybe b - , rhs ~ (a' -> SqlQuery b, (a' :& ToMaybeT b) -> SqlExpr (Value Bool)) + , rhs ~ (a' -> SqlQuery b, (a' :& ToMaybeT b) -> SqlExpr Bool) ) => a -> rhs -> From (a' :& ToMaybeT b) leftJoinLateral lhs (rhsFn, on') = From $ do @@ -266,7 +261,7 @@ rightJoin :: ( ToFrom a a' , ToFrom b b' , ToMaybe a' , HasOnClause rhs (ToMaybeT a' :& b') - , rhs ~ (b, (ToMaybeT a' :& b') -> SqlExpr (Value Bool)) + , rhs ~ (b, (ToMaybeT a' :& b') -> SqlExpr Bool) ) => a -> rhs -> From (ToMaybeT a' :& b') rightJoin lhs (rhs, on') = From $ do (leftVal, leftFrom) <- unFrom (toFrom lhs) @@ -295,7 +290,7 @@ fullOuterJoin :: ( ToFrom a a' , ToMaybe a' , ToMaybe b' , HasOnClause rhs (ToMaybeT a' :& ToMaybeT b') - , rhs ~ (b, (ToMaybeT a' :& ToMaybeT b') -> SqlExpr (Value Bool)) + , rhs ~ (b, (ToMaybeT a' :& ToMaybeT b') -> SqlExpr Bool) ) => a -> rhs -> From (ToMaybeT a' :& ToMaybeT b') fullOuterJoin lhs (rhs, on') = From $ do (leftVal, leftFrom) <- unFrom (toFrom lhs) @@ -329,7 +324,7 @@ class DoInnerJoin lateral lhs rhs res | lateral rhs lhs -> res where instance ( ToFrom a a' , ToFrom b b' , HasOnClause rhs (a' :& b') - , rhs ~ (b, (a' :& b') -> SqlExpr (Value Bool)) + , rhs ~ (b, (a' :& b') -> SqlExpr Bool) ) => DoInnerJoin NotLateral a rhs (a' :& b') where doInnerJoin _ = innerJoin @@ -338,7 +333,7 @@ instance ( ToFrom a a' , ToAlias b , ToAliasReference b , d ~ (a' :& b) - ) => DoInnerJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr (Value Bool)) d where + ) => DoInnerJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr Bool) d where doInnerJoin _ = innerJoinLateral instance ( DoInnerJoin lateral lhs rhs r, lateral ~ IsLateral rhs ) @@ -353,7 +348,7 @@ instance ( ToFrom a a' , ToMaybe b' , ToMaybeT b' ~ mb , HasOnClause rhs (a' :& mb) - , rhs ~ (b, (a' :& mb) -> SqlExpr (Value Bool)) + , rhs ~ (b, (a' :& mb) -> SqlExpr Bool) ) => DoLeftJoin NotLateral a rhs (a' :& mb) where doLeftJoin _ = leftJoin @@ -363,7 +358,7 @@ instance ( ToFrom a a' , SqlSelect b r , ToAlias b , ToAliasReference b - ) => DoLeftJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr (Value Bool)) d where + ) => DoLeftJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr Bool) d where doLeftJoin _ = leftJoinLateral instance ( DoLeftJoin lateral lhs rhs r, lateral ~ IsLateral rhs ) @@ -389,7 +384,7 @@ instance ( ToFrom a a' , ToMaybeT a' ~ ma , HasOnClause rhs (ma :& b') , ErrorOnLateral b - , rhs ~ (b, (ma :& b') -> SqlExpr (Value Bool)) + , rhs ~ (b, (ma :& b') -> SqlExpr Bool) ) => ToFrom (RightOuterJoin a rhs) (ma :& b') where toFrom (RightOuterJoin a b) = rightJoin a b @@ -401,7 +396,7 @@ instance ( ToFrom a a' , ToMaybeT b' ~ mb , HasOnClause rhs (ma :& mb) , ErrorOnLateral b - , rhs ~ (b, (ma :& mb) -> SqlExpr (Value Bool)) + , rhs ~ (b, (ma :& mb) -> SqlExpr Bool) ) => ToFrom (FullOuterJoin a rhs) (ma :& mb) where toFrom (FullOuterJoin a b) = fullOuterJoin a b diff --git a/src/Database/Esqueleto/Experimental/ToAlias.hs b/src/Database/Esqueleto/Experimental/ToAlias.hs index 7c2c4e6..ae2aefe 100644 --- a/src/Database/Esqueleto/Experimental/ToAlias.hs +++ b/src/Database/Esqueleto/Experimental/ToAlias.hs @@ -1,13 +1,12 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilies #-} module Database.Esqueleto.Experimental.ToAlias where -import Database.Esqueleto.Internal.Internal hiding (From, - from, on) -import Database.Esqueleto.Internal.PersistentImport +import Database.Esqueleto.Internal.Internal hiding (From, from, on) +import Database.Esqueleto.Internal.PersistentImport {-# DEPRECATED ToAliasT "This type alias doesn't do anything. Please delete it. Will be removed in the next release." #-} type ToAliasT a = a diff --git a/src/Database/Esqueleto/Experimental/ToAliasReference.hs b/src/Database/Esqueleto/Experimental/ToAliasReference.hs index dfe3b1c..cc6548e 100644 --- a/src/Database/Esqueleto/Experimental/ToAliasReference.hs +++ b/src/Database/Esqueleto/Experimental/ToAliasReference.hs @@ -1,14 +1,13 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilies #-} module Database.Esqueleto.Experimental.ToAliasReference where -import Data.Coerce -import Database.Esqueleto.Internal.Internal hiding (From, - from, on) -import Database.Esqueleto.Internal.PersistentImport +import Data.Coerce +import Database.Esqueleto.Internal.Internal hiding (From, from, on) +import Database.Esqueleto.Internal.PersistentImport {-# DEPRECATED ToAliasReferenceT "This type alias doesn't do anything. Please delete it. Will be removed in the next release." #-} type ToAliasReferenceT a = a diff --git a/src/Database/Esqueleto/Experimental/ToMaybe.hs b/src/Database/Esqueleto/Experimental/ToMaybe.hs index 66b2b80..223a2db 100644 --- a/src/Database/Esqueleto/Experimental/ToMaybe.hs +++ b/src/Database/Esqueleto/Experimental/ToMaybe.hs @@ -1,12 +1,11 @@ {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilies #-} module Database.Esqueleto.Experimental.ToMaybe where -import Database.Esqueleto.Internal.Internal hiding (From (..), - from, on) -import Database.Esqueleto.Internal.PersistentImport (Entity (..)) +import Database.Esqueleto.Internal.Internal hiding (From(..), from, on) +import Database.Esqueleto.Internal.PersistentImport (Entity(..)) type family Nullable a where Nullable (Maybe a) = a diff --git a/src/Database/Esqueleto/Internal/Internal.hs b/src/Database/Esqueleto/Internal/Internal.hs index dbd14c2..c42f4a4 100644 --- a/src/Database/Esqueleto/Internal/Internal.hs +++ b/src/Database/Esqueleto/Internal/Internal.hs @@ -132,7 +132,7 @@ fromFinish (PreprocessedFrom ret f') = Q $ do return ret -- | @WHERE@ clause: restrict the query's result. -where_ :: SqlExpr (Bool) -> SqlQuery () +where_ :: SqlExpr Bool -> SqlQuery () where_ expr = Q $ W.tell mempty { sdWhereClause = Where expr } -- | An @ON@ clause, useful to describe how two tables are related. Cross joins @@ -191,7 +191,7 @@ where_ expr = Q $ W.tell mempty { sdWhereClause = Where expr } -- 'on' (baz '^.' BazId '==.' bar '^.' BarBazId) -- ... -- @ -on :: SqlExpr (Bool) -> SqlQuery () +on :: SqlExpr Bool -> SqlQuery () on expr = Q $ W.tell mempty { sdFromClause = [OnClause expr] } -- | @GROUP BY@ clause. You can enclose multiple columns @@ -377,7 +377,7 @@ rand = ERaw noMeta $ \_ _ -> ("RANDOM()", []) -- | @HAVING@. -- -- @since 1.2.2 -having :: SqlExpr (Bool) -> SqlQuery () +having :: SqlExpr Bool -> SqlQuery () having expr = Q $ W.tell mempty { sdHavingClause = Where expr } -- | Add a locking clause to the query. Please read @@ -617,7 +617,7 @@ val v = ERaw noMeta $ \_ _ -> ("?", [toPersistValue v]) -- > - error: {lhs: v ==. val Nothing, rhs: Database.Esqueleto.isNothing v, name: Use Esqueleto's isNothing} -- > - error: {lhs: v !=. nothing, rhs: not_ (Database.Esqueleto.isNothing v), name: Use Esqueleto's not isNothing} -- > - error: {lhs: v !=. val Nothing, rhs: not_ (Database.Esqueleto.isNothing v), name: Use Esqueleto's not isNothing} -isNothing :: PersistField typ => SqlExpr ((Maybe typ)) -> SqlExpr (Bool) +isNothing :: PersistField typ => SqlExpr ((Maybe typ)) -> SqlExpr Bool isNothing v = case v of ERaw m f -> @@ -673,7 +673,7 @@ count = countHelper "" "" countDistinct :: Num a => SqlExpr typ -> SqlExpr a countDistinct = countHelper "(DISTINCT " ")" -not_ :: SqlExpr (Bool) -> SqlExpr (Bool) +not_ :: SqlExpr Bool -> SqlExpr Bool not_ v = ERaw noMeta $ \p info -> first ("NOT " <>) $ x p info where x p info = @@ -685,27 +685,28 @@ not_ v = ERaw noMeta $ \p info -> first ("NOT " <>) $ x p info let (b, vals) = f Never info in (parensM p b, vals) -(==.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr (Bool) + +(==.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr Bool (==.) = unsafeSqlBinOpComposite " = " " AND " -(>=.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr (Bool) +(>=.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr Bool (>=.) = unsafeSqlBinOp " >= " -(>.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr (Bool) +(>.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr Bool (>.) = unsafeSqlBinOp " > " -(<=.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr (Bool) +(<=.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr Bool (<=.) = unsafeSqlBinOp " <= " -(<.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr (Bool) +(<.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr Bool (<.) = unsafeSqlBinOp " < " -(!=.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr (Bool) +(!=.) :: PersistField typ => SqlExpr typ -> SqlExpr typ -> SqlExpr Bool (!=.) = unsafeSqlBinOpComposite " != " " OR " -(&&.) :: SqlExpr (Bool) -> SqlExpr (Bool) -> SqlExpr (Bool) +(&&.) :: SqlExpr Bool -> SqlExpr Bool -> SqlExpr Bool (&&.) = unsafeSqlBinOp " AND " -(||.) :: SqlExpr (Bool) -> SqlExpr (Bool) -> SqlExpr (Bool) +(||.) :: SqlExpr Bool -> SqlExpr Bool -> SqlExpr Bool (||.) = unsafeSqlBinOp " OR " (+.) :: PersistField a => SqlExpr a -> SqlExpr a -> SqlExpr a @@ -723,7 +724,7 @@ not_ v = ERaw noMeta $ \p info -> first ("NOT " <>) $ x p info -- | @BETWEEN@. -- -- @since: 3.1.0 -between :: PersistField a => SqlExpr a -> (SqlExpr a, SqlExpr a) -> SqlExpr (Bool) +between :: PersistField a => SqlExpr a -> (SqlExpr a, SqlExpr a) -> SqlExpr Bool a `between` (b, c) = a >=. b &&. a <=. c random_ :: (PersistField a, Num a) => SqlExpr a @@ -831,7 +832,7 @@ right_ :: (SqlString s, Num a) => (SqlExpr s, SqlExpr a) -> SqlExpr s right_ = unsafeSqlFunction "RIGHT" -- | @LIKE@ operator. -like :: SqlString s => SqlExpr s -> SqlExpr s -> SqlExpr (Bool) +like :: SqlString s => SqlExpr s -> SqlExpr s -> SqlExpr Bool like = unsafeSqlBinOp " LIKE " -- | @ILIKE@ operator (case-insensitive @LIKE@). @@ -839,7 +840,7 @@ like = unsafeSqlBinOp " LIKE " -- Supported by PostgreSQL only. -- -- @since 2.2.3 -ilike :: SqlString s => SqlExpr s -> SqlExpr s -> SqlExpr (Bool) +ilike :: SqlString s => SqlExpr s -> SqlExpr s -> SqlExpr Bool ilike = unsafeSqlBinOp " ILIKE " -- | The string @'%'@. May be useful while using 'like' and @@ -915,7 +916,7 @@ justList (ERaw m f) = ERaw m f -- @ -- -- Where @personIds@ is of type @[Key Person]@. -in_ :: PersistField typ => SqlExpr typ -> SqlExpr (ValueList typ) -> SqlExpr (Bool) +in_ :: PersistField typ => SqlExpr typ -> SqlExpr (ValueList typ) -> SqlExpr Bool (ERaw _ v) `in_` (ERaw _ list) = ERaw noMeta $ \p info -> let (b1, vals1) = v Parens info @@ -927,7 +928,7 @@ in_ :: PersistField typ => SqlExpr typ -> SqlExpr (ValueList typ) -> SqlExpr (Bo (b1 <> " IN " <> b2, vals1 <> vals2) -- | @NOT IN@ operator. -notIn :: PersistField typ => SqlExpr typ -> SqlExpr (ValueList typ) -> SqlExpr (Bool) +notIn :: PersistField typ => SqlExpr typ -> SqlExpr (ValueList typ) -> SqlExpr Bool (ERaw _ v) `notIn` (ERaw _ list) = ERaw noMeta $ \p info -> let (b1, vals1) = v Parens info @@ -944,14 +945,14 @@ notIn :: PersistField typ => SqlExpr typ -> SqlExpr (ValueList typ) -> SqlExpr ( -- 'where_' (post '^.' BlogPostAuthorId '==.' person '^.' PersonId) -- return person -- @ -exists :: SqlQuery () -> SqlExpr (Bool) +exists :: SqlQuery () -> SqlExpr Bool exists q = ERaw noMeta $ \p info -> let ERaw _ f = existsHelper q (b, vals) = f Never info in ( parensM p $ "EXISTS " <> b, vals) -- | @NOT EXISTS@ operator. -notExists :: SqlQuery () -> SqlExpr (Bool) +notExists :: SqlQuery () -> SqlExpr Bool notExists q = ERaw noMeta $ \p info -> let ERaw _ f = existsHelper q (b, vals) = f Never info @@ -1033,7 +1034,7 @@ field /=. expr = setAux field (\ent -> ent ^. field /. expr) -- reproduce this via 'nothing'. -- -- @since 2.1.2 -case_ :: PersistField a => [(SqlExpr (Bool), SqlExpr a)] -> SqlExpr a -> SqlExpr a +case_ :: PersistField a => [(SqlExpr Bool, SqlExpr a)] -> SqlExpr a -> SqlExpr a case_ = unsafeSqlCase -- | Convert an entity's key into another entity's. @@ -1092,7 +1093,7 @@ infixl 2 `InnerJoin`, `CrossJoin`, `LeftOuterJoin`, `RightOuterJoin`, `FullOuter -- | Syntax sugar for 'case_'. -- -- @since 2.1.2 -when_ :: expr (Bool) -> () -> expr a -> (expr (Bool), expr a) +when_ :: expr Bool -> () -> expr a -> (expr Bool, expr a) when_ cond _ expr = (cond, expr) -- | Syntax sugar for 'case_'. @@ -1733,8 +1734,8 @@ instance Monoid DistinctClause where -- | A part of a @FROM@ clause. data FromClause = FromStart Ident EntityDef - | FromJoin FromClause JoinKind FromClause (Maybe (SqlExpr (Bool))) - | OnClause (SqlExpr (Bool)) + | FromJoin FromClause JoinKind FromClause (Maybe (SqlExpr Bool)) + | OnClause (SqlExpr Bool) | FromRaw (NeedParens -> IdentInfo -> (TLB.Builder, [PersistValue])) data CommonTableExpressionKind @@ -1795,7 +1796,7 @@ newtype SetClause = SetClause (SqlExpr Update) collectOnClauses :: SqlBackend -> [FromClause] - -> Either (SqlExpr (Bool)) [FromClause] + -> Either (SqlExpr Bool) [FromClause] collectOnClauses sqlBackend = go Set.empty [] where go is [] (f@(FromStart i _) : fs) = @@ -1811,8 +1812,8 @@ collectOnClauses sqlBackend = go Set.empty [] findMatching :: Set Ident -> [FromClause] - -> SqlExpr (Bool) - -> Either (SqlExpr (Bool)) (Set Ident, [FromClause]) + -> SqlExpr Bool + -> Either (SqlExpr Bool) (Set Ident, [FromClause]) findMatching idents fromClauses expr = case fromClauses of f : acc -> @@ -1841,7 +1842,7 @@ collectOnClauses sqlBackend = go Set.empty [] tryMatch :: Set Ident - -> SqlExpr (Bool) + -> SqlExpr Bool -> FromClause -> Maybe (Set Ident, FromClause) tryMatch idents expr fromClause = @@ -1906,7 +1907,7 @@ collectOnClauses sqlBackend = go Set.empty [] $ renderedExpr -- | A complete @WHERE@ clause. -data WhereClause = Where (SqlExpr (Bool)) +data WhereClause = Where (SqlExpr Bool) | NoWhere instance Semigroup WhereClause where @@ -2058,6 +2059,9 @@ hasCompositeKeyMeta = Maybe.isJust . sqlExprMetaCompositeFields -- interpolated by the SQL backend. data SqlExpr a = ERaw SqlExprMeta (NeedParens -> IdentInfo -> (TLB.Builder, [PersistValue])) +instance Num a => Num (SqlExpr a) where + + -- | Data type to support from hack data PreprocessedFrom a = PreprocessedFrom a FromClause @@ -2098,16 +2102,16 @@ sub mode query = ERaw noMeta $ \_ info -> first parens $ toRawSql mode info quer fromDBName :: IdentInfo -> DBName -> TLB.Builder fromDBName (conn, _) = TLB.fromText . connEscapeName conn -existsHelper :: SqlQuery () -> SqlExpr (Bool) +existsHelper :: SqlQuery () -> SqlExpr Bool existsHelper = sub SELECT . (>> return true) where - true :: SqlExpr (Bool) + true :: SqlExpr Bool true = val True -- | (Internal) Create a case statement. -- -- Since: 2.1.1 -unsafeSqlCase :: PersistField a => [(SqlExpr (Bool), SqlExpr a)] -> SqlExpr a -> SqlExpr a +unsafeSqlCase :: PersistField a => [(SqlExpr Bool, SqlExpr a)] -> SqlExpr a -> SqlExpr a unsafeSqlCase when v = ERaw noMeta buildCase where buildCase :: NeedParens -> IdentInfo -> (TLB.Builder, [PersistValue]) @@ -2116,11 +2120,11 @@ unsafeSqlCase when v = ERaw noMeta buildCase (whenText, whenVals) = mapWhen when Parens info in ( "CASE" <> whenText <> " ELSE " <> elseText <> " END", whenVals <> elseVals) - mapWhen :: [(SqlExpr (Bool), SqlExpr a)] -> NeedParens -> IdentInfo -> (TLB.Builder, [PersistValue]) + mapWhen :: [(SqlExpr Bool, SqlExpr a)] -> NeedParens -> IdentInfo -> (TLB.Builder, [PersistValue]) mapWhen [] _ _ = throw (UnexpectedCaseErr UnsafeSqlCaseError) mapWhen when' p info = foldl (foldHelp p info) (mempty, mempty) when' - foldHelp :: NeedParens -> IdentInfo -> (TLB.Builder, [PersistValue]) -> (SqlExpr (Bool), SqlExpr a) -> (TLB.Builder, [PersistValue]) + foldHelp :: NeedParens -> IdentInfo -> (TLB.Builder, [PersistValue]) -> (SqlExpr Bool, SqlExpr a) -> (TLB.Builder, [PersistValue]) foldHelp p info (b0, vals0) (v1, v2) = let (b1, vals1) = valueToSql v1 p info (b2, vals2) = valueToSql v2 p info @@ -2135,7 +2139,7 @@ unsafeSqlCase when v = ERaw noMeta buildCase -- signature. For example: -- -- @ --- (==.) :: SqlExpr a -> SqlExpr a -> SqlExpr (Bool) +-- (==.) :: SqlExpr a -> SqlExpr a -> SqlExpr Bool -- (==.) = unsafeSqlBinOp " = " -- @ -- @@ -2176,7 +2180,7 @@ unsafeSqlBinOp op a b = unsafeSqlBinOp op (construct a) (construct b) -- Usage example: -- -- @ --- (==.) :: SqlExpr a -> SqlExpr a -> SqlExpr (Bool) +-- (==.) :: SqlExpr a -> SqlExpr a -> SqlExpr Bool -- (==.) = unsafeSqlBinOpComposite " = " " AND " -- @ -- @@ -2832,7 +2836,7 @@ makeFrom info mode fs = ret makeOnClause (ERaw _ f) = first (" ON " <>) (f Never info) - mkExc :: SqlExpr (Bool) -> OnClauseWithoutMatchingJoinException + mkExc :: SqlExpr Bool -> OnClauseWithoutMatchingJoinException mkExc (ERaw _ f) = OnClauseWithoutMatchingJoinException $ TL.unpack $ TLB.toLazyText $ fst (f Never info) @@ -3545,7 +3549,7 @@ insertSelectCount = rawEsqueleto INSERT_INTO -- representation of the clauses passed to an "On" clause. -- -- @since 3.2.0 -renderExpr :: SqlBackend -> SqlExpr (Bool) -> T.Text +renderExpr :: SqlBackend -> SqlExpr Bool -> T.Text renderExpr sqlBackend e = case e of ERaw _ mkBuilderValues -> let (builder, _) = mkBuilderValues Never (sqlBackend, initialIdentState) diff --git a/src/Database/Esqueleto/Internal/Language.hs b/src/Database/Esqueleto/Internal/Language.hs index 289a39c..429a8dd 100644 --- a/src/Database/Esqueleto/Internal/Language.hs +++ b/src/Database/Esqueleto/Internal/Language.hs @@ -1,13 +1,13 @@ -{-# LANGUAGE DeriveDataTypeable #-} -{-# LANGUAGE EmptyDataDecls #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE EmptyDataDecls #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE PatternSynonyms #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} -- | This is an internal module, anything exported by this module -- may change without a major version bump. Please use only @@ -139,5 +139,5 @@ module Database.Esqueleto.Internal.Language , subSelectUnsafe ) where -import Database.Esqueleto.Internal.Internal -import Database.Esqueleto.Internal.PersistentImport +import Database.Esqueleto.Internal.Internal +import Database.Esqueleto.Internal.PersistentImport diff --git a/src/Database/Esqueleto/Internal/PersistentImport.hs b/src/Database/Esqueleto/Internal/PersistentImport.hs index 84e8582..8ca1d07 100644 --- a/src/Database/Esqueleto/Internal/PersistentImport.hs +++ b/src/Database/Esqueleto/Internal/PersistentImport.hs @@ -151,6 +151,7 @@ import Database.Persist.Sql hiding , delete , deleteCascadeWhere , deleteWhereCount + , exists , getPersistMap , limitOffsetOrder , listToJSON @@ -174,5 +175,4 @@ import Database.Persist.Sql hiding , (>.) , (>=.) , (||.) - , exists ) diff --git a/src/Database/Esqueleto/MySQL.hs b/src/Database/Esqueleto/MySQL.hs index 4182fc6..398e6bf 100644 --- a/src/Database/Esqueleto/MySQL.hs +++ b/src/Database/Esqueleto/MySQL.hs @@ -14,5 +14,5 @@ import Database.Esqueleto.Internal.PersistentImport -- because MySQL uses `rand()`. -- -- /Since: 2.6.0/ -random_ :: (PersistField a, Num a) => SqlExpr (Value a) +random_ :: (PersistField a, Num a) => SqlExpr a random_ = unsafeSqlValue "RAND()" diff --git a/src/Database/Esqueleto/PostgreSQL.hs b/src/Database/Esqueleto/PostgreSQL.hs index 35a2c43..38a3c46 100644 --- a/src/Database/Esqueleto/PostgreSQL.hs +++ b/src/Database/Esqueleto/PostgreSQL.hs @@ -52,18 +52,18 @@ import Database.Persist.Class (OnlyOneUniqueKey) -- because MySQL uses `rand()`. -- -- @since 2.6.0 -random_ :: (PersistField a, Num a) => SqlExpr (Value a) +random_ :: (PersistField a, Num a) => SqlExpr a random_ = unsafeSqlValue "RANDOM()" -- | Empty array literal. (@val []@) does unfortunately not work -emptyArray :: SqlExpr (Value [a]) +emptyArray :: SqlExpr [a] emptyArray = unsafeSqlValue "'{}'" -- | Coalesce an array with an empty default value maybeArray :: (PersistField a, PersistField [a]) - => SqlExpr (Value (Maybe [a])) - -> SqlExpr (Value [a]) + => SqlExpr (Maybe [a]) + -> SqlExpr [a] maybeArray x = coalesceDefault [x] (emptyArray) -- | Aggregate mode @@ -82,7 +82,7 @@ unsafeSqlAggregateFunction -> AggMode -> a -> [OrderByClause] - -> SqlExpr (Value b) + -> SqlExpr b unsafeSqlAggregateFunction name mode args orderByClauses = ERaw noMeta $ \_ info -> let (orderTLB, orderVals) = makeOrderByNoNewline info orderByClauses -- Don't add a space if we don't have order by clauses @@ -106,14 +106,14 @@ unsafeSqlAggregateFunction name mode args orderByClauses = ERaw noMeta $ \_ info --- into an array. arrayAggWith :: AggMode - -> SqlExpr (Value a) + -> SqlExpr a -> [OrderByClause] - -> SqlExpr (Value (Maybe [a])) + -> SqlExpr (Maybe [a]) arrayAggWith = unsafeSqlAggregateFunction "array_agg" --- | (@array_agg@) Concatenate input values, including @NULL@s, --- into an array. -arrayAgg :: (PersistField a) => SqlExpr (Value a) -> SqlExpr (Value (Maybe [a])) +arrayAgg :: (PersistField a) => SqlExpr a -> SqlExpr (Maybe [a]) arrayAgg x = arrayAggWith AggModeAll x [] -- | (@array_agg@) Concatenate distinct input values, including @NULL@s, into @@ -122,19 +122,19 @@ arrayAgg x = arrayAggWith AggModeAll x [] -- @since 2.5.3 arrayAggDistinct :: (PersistField a, PersistField [a]) - => SqlExpr (Value a) - -> SqlExpr (Value (Maybe [a])) + => SqlExpr a + -> SqlExpr (Maybe [a]) arrayAggDistinct x = arrayAggWith AggModeDistinct x [] -- | (@array_remove@) Remove all elements equal to the given value from the -- array. -- -- @since 2.5.3 -arrayRemove :: SqlExpr (Value [a]) -> SqlExpr (Value a) -> SqlExpr (Value [a]) +arrayRemove :: SqlExpr [a] -> SqlExpr a -> SqlExpr [a] arrayRemove arr elem' = unsafeSqlFunction "array_remove" (arr, elem') -- | Remove @NULL@ values from an array -arrayRemoveNull :: SqlExpr (Value [Maybe a]) -> SqlExpr (Value [a]) +arrayRemoveNull :: SqlExpr [Maybe a] -> SqlExpr [a] -- This can't be a call to arrayRemove because it changes the value type arrayRemoveNull x = unsafeSqlFunction "array_remove" (x, unsafeSqlValue "NULL") @@ -144,10 +144,10 @@ arrayRemoveNull x = unsafeSqlFunction "array_remove" (x, unsafeSqlValue "NULL") stringAggWith :: SqlString s => AggMode -- ^ Aggregate mode (ALL or DISTINCT) - -> SqlExpr (Value s) -- ^ Input values. - -> SqlExpr (Value s) -- ^ Delimiter. + -> SqlExpr s -- ^ Input values. + -> SqlExpr s -- ^ Delimiter. -> [OrderByClause] -- ^ ORDER BY clauses - -> SqlExpr (Value (Maybe s)) -- ^ Concatenation. + -> SqlExpr (Maybe s) -- ^ Concatenation. stringAggWith mode expr delim os = unsafeSqlAggregateFunction "string_agg" mode (expr, delim) os @@ -157,19 +157,19 @@ stringAggWith mode expr delim os = -- @since 2.2.8 stringAgg :: SqlString s - => SqlExpr (Value s) -- ^ Input values. - -> SqlExpr (Value s) -- ^ Delimiter. - -> SqlExpr (Value (Maybe s)) -- ^ Concatenation. + => SqlExpr s -- ^ Input values. + -> SqlExpr s -- ^ Delimiter. + -> SqlExpr (Maybe s) -- ^ Concatenation. stringAgg expr delim = stringAggWith AggModeAll expr delim [] -- | (@chr@) Translate the given integer to a character. (Note the result will -- depend on the character set of your database.) -- -- @since 2.2.11 -chr :: SqlString s => SqlExpr (Value Int) -> SqlExpr (Value s) +chr :: SqlString s => SqlExpr Int -> SqlExpr s chr = unsafeSqlFunction "chr" -now_ :: SqlExpr (Value UTCTime) +now_ :: SqlExpr UTCTime now_ = unsafeSqlFunction "NOW" () upsert @@ -350,11 +350,11 @@ insertSelectWithConflictCount unique query conflictQuery = do -- -- @since 3.3.3.3 filterWhere - :: SqlExpr (Value a) + :: SqlExpr a -- ^ Aggregate function - -> SqlExpr (Value Bool) + -> SqlExpr Bool -- ^ Filter clause - -> SqlExpr (Value a) + -> SqlExpr a filterWhere aggExpr clauseExpr = ERaw noMeta $ \_ info -> let (aggBuilder, aggValues) = case aggExpr of ERaw _ aggF -> aggF Never info diff --git a/src/Database/Esqueleto/PostgreSQL/JSON.hs b/src/Database/Esqueleto/PostgreSQL/JSON.hs index a105ff8..63418a1 100644 --- a/src/Database/Esqueleto/PostgreSQL/JSON.hs +++ b/src/Database/Esqueleto/PostgreSQL/JSON.hs @@ -189,7 +189,7 @@ infixl 6 ||., -., --., #-. -- @ -- -- @since 3.1.0 -(->>.) :: JSONBExpr a -> JSONAccessor -> SqlExpr (Value (Maybe Text)) +(->>.) :: JSONBExpr a -> JSONAccessor -> SqlExpr (Maybe Text) (->>.) value (JSONKey txt) = unsafeSqlBinOp " ->> " value $ val txt (->>.) value (JSONIndex i) = unsafeSqlBinOp " ->> " value $ val i @@ -253,7 +253,7 @@ infixl 6 ||., -., --., #-. -- @ -- -- @since 3.1.0 -(#>>.) :: JSONBExpr a -> [Text] -> SqlExpr (Value (Maybe Text)) +(#>>.) :: JSONBExpr a -> [Text] -> SqlExpr (Maybe Text) (#>>.) value = unsafeSqlBinOp " #>> " value . mkTextArray -- | /Requires PostgreSQL version >= 9.4/ @@ -275,7 +275,7 @@ infixl 6 ||., -., --., #-. -- @ -- -- @since 3.1.0 -(@>.) :: JSONBExpr a -> JSONBExpr b -> SqlExpr (Value Bool) +(@>.) :: JSONBExpr a -> JSONBExpr b -> SqlExpr Bool (@>.) = unsafeSqlBinOp " @> " -- | /Requires PostgreSQL version >= 9.4/ @@ -297,7 +297,7 @@ infixl 6 ||., -., --., #-. -- @ -- -- @since 3.1.0 -(<@.) :: JSONBExpr a -> JSONBExpr b -> SqlExpr (Value Bool) +(<@.) :: JSONBExpr a -> JSONBExpr b -> SqlExpr Bool (<@.) = unsafeSqlBinOp " <@ " -- | /Requires PostgreSQL version >= 9.4/ @@ -320,7 +320,7 @@ infixl 6 ||., -., --., #-. -- @ -- -- @since 3.1.0 -(?.) :: JSONBExpr a -> Text -> SqlExpr (Value Bool) +(?.) :: JSONBExpr a -> Text -> SqlExpr Bool (?.) value = unsafeSqlBinOp " ?? " value . val -- | /Requires PostgreSQL version >= 9.4/ @@ -343,7 +343,7 @@ infixl 6 ||., -., --., #-. -- @ -- -- @since 3.1.0 -(?|.) :: JSONBExpr a -> [Text] -> SqlExpr (Value Bool) +(?|.) :: JSONBExpr a -> [Text] -> SqlExpr Bool (?|.) value = unsafeSqlBinOp " ??| " value . mkTextArray -- | /Requires PostgreSQL version >= 9.4/ @@ -366,7 +366,7 @@ infixl 6 ||., -., --., #-. -- @ -- -- @since 3.1.0 -(?&.) :: JSONBExpr a -> [Text] -> SqlExpr (Value Bool) +(?&.) :: JSONBExpr a -> [Text] -> SqlExpr Bool (?&.) value = unsafeSqlBinOp " ??& " value . mkTextArray -- | /Requires PostgreSQL version >= 9.5/ @@ -579,5 +579,5 @@ infixl 6 ||., -., --., #-. (#-.) :: JSONBExpr a -> [Text] -> JSONBExpr b (#-.) value = unsafeSqlBinOp " #- " value . mkTextArray -mkTextArray :: [Text] -> SqlExpr (Value PersistValue) +mkTextArray :: [Text] -> SqlExpr PersistValue mkTextArray = val . PersistArray . fmap toPersistValue diff --git a/src/Database/Esqueleto/PostgreSQL/JSON/Instances.hs b/src/Database/Esqueleto/PostgreSQL/JSON/Instances.hs index 0f85170..c3f725e 100644 --- a/src/Database/Esqueleto/PostgreSQL/JSON/Instances.hs +++ b/src/Database/Esqueleto/PostgreSQL/JSON/Instances.hs @@ -2,13 +2,13 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} -{-# language DerivingStrategies #-} module Database.Esqueleto.PostgreSQL.JSON.Instances where -import Data.Aeson (FromJSON(..), ToJSON(..), encode, eitherDecodeStrict) +import Data.Aeson (FromJSON(..), ToJSON(..), eitherDecodeStrict, encode) import Data.Bifunctor (first) import qualified Data.ByteString.Lazy as BSL (toStrict) import Data.String (IsString(..)) @@ -42,7 +42,7 @@ newtype JSONB a = JSONB { unJSONB :: a } -- | 'SqlExpr' of a NULL-able 'JSONB' value. Hence the 'Maybe'. -- -- Note: NULL here is a PostgreSQL NULL, not a JSON 'null' -type JSONBExpr a = SqlExpr (Value (Maybe (JSONB a))) +type JSONBExpr a = SqlExpr (Maybe (JSONB a)) -- | Convenience function to lift a regular value into -- a 'JSONB' expression. diff --git a/src/Database/Esqueleto/SQLite.hs b/src/Database/Esqueleto/SQLite.hs index f7adc1b..61c89e9 100644 --- a/src/Database/Esqueleto/SQLite.hs +++ b/src/Database/Esqueleto/SQLite.hs @@ -14,5 +14,5 @@ import Database.Esqueleto.Internal.PersistentImport -- because MySQL uses `rand()`. -- -- /Since: 2.6.0/ -random_ :: (PersistField a, Num a) => SqlExpr (Value a) +random_ :: (PersistField a, Num a) => SqlExpr a random_ = unsafeSqlValue "RANDOM()"