diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0db9ec8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,95 @@ +language: c + +sudo: false + +matrix: + include: + - env: STACK=STACK ARGS="" + addons: {apt: {packages: [libgmp-dev]}} + - env: STACK=STACK ARGS="--resolver lts-1" + addons: {apt: {packages: [libgmp-dev]}} + - env: STACK=STACK ARGS="--resolver lts-2" + addons: {apt: {packages: [libgmp-dev]}} + - env: STACK=STACK ARGS="--resolver lts-3" + addons: {apt: {packages: [libgmp-dev]}} + - env: STACK=STACK ARGS="--resolver lts-4" + addons: {apt: {packages: [libgmp-dev]}} + - env: STACK=STACK ARGS="--resolver lts-5" + addons: {apt: {packages: [libgmp-dev]}} + - env: STACK=STACK ARGS="--resolver lts-6" + addons: {apt: {packages: [libgmp-dev]}} + - env: STACK=STACK ARGS="--resolver lts" + addons: {apt: {packages: [libgmp-dev]}} + - env: STACK=STACK ARGS="--resolver nightly" + addons: {apt: {packages: [libgmp-dev]}} + - env: CABALVER=head GHCVER=head + addons: {apt: {packages: [cabal-install-head,ghc-head], sources: [hvr-ghc]}} + + allow_failures: + - env: CABALVER=head GHCVER=head + +before_install: + - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH + +install: + - | + set -e + if [ -z "$STACK" ]; then + export PATH=/home/travis/.cabal/bin:/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH + + echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]" + cabal update + + else + travis_retry curl -o stack.tar.gz -L https://www.stackage.org/stack/linux-x86_64 + mkdir ./stack + tar -xf stack.tar.gz -C ./stack --strip-components=1 + export PATH=$PATH:./stack/ + + echo "Stack $(stack --version)" + stack update + fi + +script: + - | + set -e + if [ -n "$STACK" ]; then + echo -e "\033[0;32mstack setup.\033[0m" + stack $ARGS --no-terminal setup + + echo -e "\033[0;32mstack build.\033[0m" + stack $ARGS --no-terminal build + + echo -e "\033[0;32mstack test.\033[0m" + stack $ARGS --no-terminal test + + else + cabal --version + ghc --version + + echo -e "\033[0;32mcabal install only deps.\033[0m" + cabal install --only-dependencies --enable-tests + + echo -e "\033[0;32mcabal config with tests.\033[0m" + cabal configure --enable-tests + + echo -e "\033[0;32mcabal build.\033[0m" + cabal build + + echo -e "\033[0;32mcabal test.\033[0m" + cabal test + + echo -e "\033[0;32mcabal check.\033[0m" + cabal check + + echo -e "\033[0;32mcabal sdist.\033[0m" + cabal sdist + + echo -e "\033[0;32mcabal install tarball.\033[0m" + cabal install --force-reinstalls dist/*-*.tar.gz + fi +cache: + directories: + - $HOME/.stack + - $HOME/.cabal + diff --git a/esqueleto.cabal b/esqueleto.cabal index 65aa237..ad44aef 100644 --- a/esqueleto.cabal +++ b/esqueleto.cabal @@ -63,10 +63,10 @@ library other-modules: Database.Esqueleto.Internal.PersistentImport build-depends: - base >= 4.5 && < 4.9 + base >= 4.5 && < 4.10 , bytestring , text >= 0.11 && < 1.3 - , persistent >= 2.1.1.7 && < 2.3 + , persistent >= 2.1.1.7 && < 2.7 , transformers >= 0.2 , unordered-containers >= 0.2 , tagged >= 0.2 diff --git a/src/Database/Esqueleto.hs b/src/Database/Esqueleto.hs index eb135c2..57a90fd 100644 --- a/src/Database/Esqueleto.hs +++ b/src/Database/Esqueleto.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE FlexibleContexts, FlexibleInstances, GADTs #-} +{-# LANGUAGE FlexibleContexts, FlexibleInstances, GADTs, CPP #-} -- | The @esqueleto@ EDSL (embedded domain specific language). -- This module replaces @Database.Persist@, so instead of -- importing that module you should just import this one: @@ -405,8 +405,13 @@ import qualified Database.Persist -- | @valkey i = 'val' . 'toSqlKey'@ -- (). +#if MIN_VERSION_persistent(2,5,0) +valkey :: (Esqueleto query expr backend, ToBackendKey SqlBackend entity) => + Int64 -> expr (Value (Key entity)) +#else valkey :: (Esqueleto query expr backend, ToBackendKey SqlBackend entity, PersistField (Key entity)) => Int64 -> expr (Value (Key entity)) +#endif valkey = val . toSqlKey @@ -430,8 +435,15 @@ valJ = val . unValue -- | Synonym for 'Database.Persist.Store.delete' that does not -- clash with @esqueleto@'s 'delete'. +#if MIN_VERSION_persistent(2,5,0) +deleteKey :: ( PersistStoreWrite b + , MonadIO m + , PersistRecordBackend val b) + => Key val -> ReaderT b m () +#else deleteKey :: ( PersistStore (PersistEntityBackend val) , MonadIO m , PersistEntity val ) => Key val -> ReaderT (PersistEntityBackend val) m () +#endif deleteKey = Database.Persist.delete diff --git a/src/Database/Esqueleto/Internal/Language.hs b/src/Database/Esqueleto/Internal/Language.hs index fbe88e2..fb98f0b 100644 --- a/src/Database/Esqueleto/Internal/Language.hs +++ b/src/Database/Esqueleto/Internal/Language.hs @@ -7,6 +7,7 @@ , TypeFamilies , UndecidableInstances , GADTs + , CPP #-} -- | This is an internal module, anything exported by this module -- may change without a major version bump. Please use only @@ -52,7 +53,6 @@ import Database.Esqueleto.Internal.PersistentImport import Text.Blaze.Html (Html) import qualified Data.ByteString as B -import qualified Data.ByteString.Lazy as BL import qualified Data.Text as T import qualified Data.Text.Lazy as TL @@ -299,8 +299,13 @@ class (Functor query, Applicative query, Monad query) => sub_selectDistinct :: PersistField a => query (expr (Value a)) -> expr (Value a) -- | Project a field of an entity. +#if MIN_VERSION_persistent(2,5,0) + (^.) :: (PersistEntity val) => + expr (Entity val) -> EntityField val typ -> expr (Value typ) +#else (^.) :: (PersistEntity val, PersistField typ) => expr (Entity val) -> EntityField val typ -> expr (Value typ) +#endif -- | Project a field of an entity that may be null. (?.) :: (PersistEntity val, PersistField typ) => diff --git a/src/Database/Esqueleto/Internal/PersistentImport.hs b/src/Database/Esqueleto/Internal/PersistentImport.hs index ad193e0..0342634 100644 --- a/src/Database/Esqueleto/Internal/PersistentImport.hs +++ b/src/Database/Esqueleto/Internal/PersistentImport.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP#-} -- | Re-export "Database.Persist.Sql" without any clashes with -- @esqueleto@. module Database.Esqueleto.Internal.PersistentImport @@ -5,9 +6,15 @@ module Database.Esqueleto.Internal.PersistentImport ) where import Database.Persist.Sql hiding - ( BackendSpecificFilter, Filter(..), PersistQuery(..), SelectOpt(..) + ( BackendSpecificFilter, Filter(..), SelectOpt(..) , Update(..), delete, deleteWhereCount, updateWhereCount, selectList , selectKeysList, deleteCascadeWhere, (=.), (+=.), (-=.), (*=.), (/=.) , (==.), (!=.), (<.), (>.), (<=.), (>=.), (<-.), (/<-.), (||.) , listToJSON, mapToJSON, getPersistMap, limitOffsetOrder, selectSource - , update ) + , update +#if MIN_VERSION_persistent(2,5,0) + , PersistQueryRead(..) +#else + , PersistQuery(..) +#endif + ) diff --git a/src/Database/Esqueleto/Internal/Sql.hs b/src/Database/Esqueleto/Internal/Sql.hs index 32db5d9..c8b09b5 100644 --- a/src/Database/Esqueleto/Internal/Sql.hs +++ b/src/Database/Esqueleto/Internal/Sql.hs @@ -9,6 +9,7 @@ , UndecidableInstances , ScopedTypeVariables , InstanceSigs + , CPP #-} -- | This is an internal module, anything exported by this module -- may change without a major version bump. Please use only @@ -421,8 +422,13 @@ instance Esqueleto SqlQuery SqlExpr SqlBackend where sub_select = sub SELECT sub_selectDistinct = sub_select . distinct +#if MIN_VERSION_persistent(2,5,0) + (^.) :: forall val typ. (PersistEntity val) + => SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ) +#else (^.) :: forall val typ. (PersistEntity val, PersistField typ) => SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ) +#endif EEntity ident ^. field | isComposite = ECompositeKey $ \info -> dot info <$> compositeFields pdef | otherwise = ERaw Never $ \info -> (dot info $ persistFieldDef field, []) @@ -530,15 +536,27 @@ instance Esqueleto SqlQuery SqlExpr SqlBackend where instance ToSomeValues SqlExpr (SqlExpr (Value a)) where toSomeValues a = [SomeValue a] +#if MIN_VERSION_persistent(2,5,0) +fieldName :: (PersistEntity val) + => IdentInfo -> EntityField val typ -> TLB.Builder +#else fieldName :: (PersistEntity val, PersistField typ) => IdentInfo -> EntityField val typ -> TLB.Builder +#endif fieldName info = fromDBName info . fieldDB . persistFieldDef -- FIXME: Composite/non-id pKS not supported on set +#if MIN_VERSION_persistent(2,5,0) +setAux :: PersistEntity val + => EntityField val typ + -> (SqlExpr (Entity val) -> SqlExpr (Value typ)) + -> SqlExpr (Update val) +#else setAux :: (PersistEntity val, PersistField typ) => EntityField val typ -> (SqlExpr (Entity val) -> SqlExpr (Value typ)) -> SqlExpr (Update val) +#endif setAux field mkVal = ESet $ \ent -> unsafeSqlBinOp " = " name (mkVal ent) where name = ERaw Never $ \info -> (fieldName info field, mempty) diff --git a/stack.yaml b/stack.yaml index 966a1df..84d3b33 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1 +1 @@ -resolver: lts-5.1 +resolver: lts-6.16 diff --git a/test/Test.hs b/test/Test.hs index 80c6784..fe41de9 100644 --- a/test/Test.hs +++ b/test/Test.hs @@ -1395,11 +1395,18 @@ main = do ---------------------------------------------------------------------- +#if MIN_VERSION_persistent(2,5,0) +insert' :: ( PersistStoreWrite b + , MonadIO m + , PersistRecordBackend val b) + => val -> ReaderT b m (Entity val) +#else insert' :: ( Functor m , PersistStore (PersistEntityBackend val) , MonadIO m , PersistEntity val ) => val -> ReaderT (PersistEntityBackend val) m (Entity val) +#endif insert' v = flip Entity v <$> insert v