persistent2

This commit is contained in:
Michael Snoyman 2014-01-16 08:24:43 +02:00
parent 646c115257
commit 7f6ae061da
5 changed files with 66 additions and 58 deletions

View File

@ -1,5 +1,5 @@
name: esqueleto name: esqueleto
version: 1.3.4.2 version: 2.0.0
synopsis: Bare bones, type-safe EDSL for SQL queries on persistent backends. synopsis: Bare bones, type-safe EDSL for SQL queries on persistent backends.
homepage: https://github.com/meteficha/esqueleto homepage: https://github.com/meteficha/esqueleto
license: BSD3 license: BSD3
@ -65,7 +65,7 @@ library
build-depends: build-depends:
base >= 4.5 && < 4.7 base >= 4.5 && < 4.7
, text == 0.11.* , text == 0.11.*
, persistent >= 1.2 && < 1.4 , persistent >= 2.0 && < 2.1
, transformers >= 0.2 , transformers >= 0.2
, unordered-containers >= 0.2 , unordered-containers >= 0.2
, tagged >= 0.2 , tagged >= 0.2
@ -91,8 +91,8 @@ test-suite test
, HUnit , HUnit
, QuickCheck , QuickCheck
, hspec >= 1.3 && < 1.8 , hspec >= 1.3 && < 1.8
, persistent-sqlite >= 1.2 && < 1.4 , persistent-sqlite >= 2.0 && < 2.1
, persistent-template >= 1.2 && < 1.4 , persistent-template >= 2.0 && < 2.1
, monad-control , monad-control
, monad-logger >= 0.3 , monad-logger >= 0.3
@ -103,7 +103,7 @@ test-suite test
build-depends: build-depends:
postgresql-simple >= 0.2 postgresql-simple >= 0.2
, postgresql-libpq >= 0.6 , postgresql-libpq >= 0.6
, persistent-postgresql >= 1.2.0 , persistent-postgresql >= 2.0
cpp-options: -DWITH_POSTGRESQL cpp-options: -DWITH_POSTGRESQL
@ -111,7 +111,7 @@ test-suite test
build-depends: build-depends:
mysql-simple >= 0.2.2.3 mysql-simple >= 0.2.2.3
, mysql >= 0.1.1.3 , mysql >= 0.1.1.3
, persistent-mysql >= 1.2.0 , persistent-mysql >= 2.0
cpp-options: -DWITH_MYSQL cpp-options: -DWITH_MYSQL

View File

@ -87,6 +87,8 @@ module Database.Esqueleto
, module Database.Esqueleto.Internal.PersistentImport , module Database.Esqueleto.Internal.PersistentImport
) where ) where
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Trans.Reader (ReaderT)
import Data.Int (Int64) import Data.Int (Int64)
import Database.Esqueleto.Internal.Language import Database.Esqueleto.Internal.Language
import Database.Esqueleto.Internal.Sql import Database.Esqueleto.Internal.Sql
@ -380,8 +382,8 @@ valkey = val . Key . PersistInt64
-- | Synonym for 'Database.Persist.Store.delete' that does not -- | Synonym for 'Database.Persist.Store.delete' that does not
-- clash with @esqueleto@'s 'delete'. -- clash with @esqueleto@'s 'delete'.
deleteKey :: ( PersistStore m deleteKey :: ( PersistStore (PersistEntityBackend val)
, PersistMonadBackend m ~ PersistEntityBackend val , MonadIO m
, PersistEntity val ) , PersistEntity val )
=> Key val -> m () => Key val -> ReaderT (PersistEntityBackend val) m ()
deleteKey = Database.Persist.delete deleteKey = Database.Persist.delete

View File

@ -9,4 +9,4 @@ import Database.Persist.Sql hiding
, Update(..), delete, deleteWhereCount, updateWhereCount, selectList , Update(..), delete, deleteWhereCount, updateWhereCount, selectList
, selectKeysList, deleteCascadeWhere, (=.), (+=.), (-=.), (*=.), (/=.) , selectKeysList, deleteCascadeWhere, (=.), (+=.), (-=.), (*=.), (/=.)
, (==.), (!=.), (<.), (>.), (<=.), (>=.), (<-.), (/<-.), (||.) , (==.), (!=.), (<.), (>.), (<=.), (>=.), (<-.), (/<-.), (||.)
, listToJSON, mapToJSON, getPersistMap, limitOffsetOrder ) , listToJSON, mapToJSON, getPersistMap, limitOffsetOrder, selectSource )

View File

@ -45,11 +45,10 @@ module Database.Esqueleto.Internal.Sql
import Control.Applicative (Applicative(..), (<$>), (<$)) import Control.Applicative (Applicative(..), (<$>), (<$))
import Control.Arrow ((***), first) import Control.Arrow ((***), first)
import Control.Exception (throw, throwIO) import Control.Exception (throw, throwIO)
import Control.Monad ((>=>), ap, void, MonadPlus(..)) import Control.Monad (ap, MonadPlus(..), liftM)
import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Logger (MonadLogger)
import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Resource (MonadResourceBase) import qualified Control.Monad.Trans.Resource as Res
import Data.Int (Int64) import Data.Int (Int64)
import Data.List (intersperse) import Data.List (intersperse)
import Data.Monoid (Monoid(..), (<>)) import Data.Monoid (Monoid(..), (<>))
@ -520,19 +519,20 @@ veryUnsafeCoerceSqlExprValueList EEmptyList =
-- | (Internal) Execute an @esqueleto@ @SELECT@ 'SqlQuery' inside -- | (Internal) Execute an @esqueleto@ @SELECT@ 'SqlQuery' inside
-- @persistent@'s 'SqlPersistT' monad. -- @persistent@'s 'SqlPersistT' monad.
rawSelectSource :: ( SqlSelect a r rawSelectSource :: ( SqlSelect a r
, MonadLogger m , MonadIO m1
, MonadResourceBase m ) , MonadIO m2 )
=> Mode => Mode
-> SqlQuery a -> SqlQuery a
-> SqlPersistT m (C.Source (C.ResourceT (SqlPersistT m)) r) -> SqlPersistT m1 (Res.Resource (C.Source m2 r))
rawSelectSource mode query = src rawSelectSource mode query =
do
conn <- R.ask
res <- run conn
return $ (C.$= massage) `fmap` res
where where
src = do
conn <- SqlPersistT R.ask
return $ run conn C.$= massage
run conn = run conn =
uncurry rawQuery $ uncurry rawQueryRes $
first builderToText $ first builderToText $
toRawSql mode pureQuery (conn, initialIdentState) query toRawSql mode pureQuery (conn, initialIdentState) query
@ -549,11 +549,14 @@ rawSelectSource mode query = src
-- | Execute an @esqueleto@ @SELECT@ query inside @persistent@'s -- | Execute an @esqueleto@ @SELECT@ query inside @persistent@'s
-- 'SqlPersistT' monad and return a 'C.Source' of rows. -- 'SqlPersistT' monad and return a 'C.Source' of rows.
selectSource :: ( SqlSelect a r selectSource :: ( SqlSelect a r
, MonadLogger m , C.MonadResource m )
, MonadResourceBase m )
=> SqlQuery a => SqlQuery a
-> SqlPersistT m (C.Source (C.ResourceT (SqlPersistT m)) r) -> C.Source (SqlPersistT m) r
selectSource = rawSelectSource SELECT selectSource query = do
src <- lift $ do
res <- rawSelectSource SELECT query
fmap snd $ Res.allocateResource res
src
-- | Execute an @esqueleto@ @SELECT@ query inside @persistent@'s -- | Execute an @esqueleto@ @SELECT@ query inside @persistent@'s
@ -598,10 +601,12 @@ selectSource = rawSelectSource SELECT
-- function composition that the @p@ inside the query is of type -- function composition that the @p@ inside the query is of type
-- @SqlExpr (Entity Person)@. -- @SqlExpr (Entity Person)@.
select :: ( SqlSelect a r select :: ( SqlSelect a r
, MonadLogger m , MonadIO m )
, MonadResourceBase m )
=> SqlQuery a -> SqlPersistT m [r] => SqlQuery a -> SqlPersistT m [r]
select = selectSource >=> runSource select query = do
res <- rawSelectSource SELECT query
conn <- R.ask
liftIO $ Res.with res $ flip R.runReaderT conn . runSource
-- | Execute an @esqueleto@ @SELECT DISTINCT@ query inside -- | Execute an @esqueleto@ @SELECT DISTINCT@ query inside
@ -609,27 +614,32 @@ select = selectSource >=> runSource
-- rows. -- rows.
selectDistinctSource selectDistinctSource
:: ( SqlSelect a r :: ( SqlSelect a r
, MonadLogger m , C.MonadResource m )
, MonadResourceBase m )
=> SqlQuery a => SqlQuery a
-> SqlPersistT m (C.Source (C.ResourceT (SqlPersistT m)) r) -> C.Source (SqlPersistT m) r
selectDistinctSource = rawSelectSource SELECT_DISTINCT selectDistinctSource query = do
src <- lift $ do
res <- rawSelectSource SELECT_DISTINCT query
fmap snd $ Res.allocateResource res
src
-- | Execute an @esqueleto@ @SELECT DISTINCT@ query inside -- | Execute an @esqueleto@ @SELECT DISTINCT@ query inside
-- @persistent@'s 'SqlPersistT' monad and return a list of rows. -- @persistent@'s 'SqlPersistT' monad and return a list of rows.
selectDistinct :: ( SqlSelect a r selectDistinct :: ( SqlSelect a r
, MonadLogger m , MonadIO m )
, MonadResourceBase m )
=> SqlQuery a -> SqlPersistT m [r] => SqlQuery a -> SqlPersistT m [r]
selectDistinct = selectDistinctSource >=> runSource selectDistinct query = do
res <- rawSelectSource SELECT_DISTINCT query
conn <- R.ask
liftIO $ Res.with res $ flip R.runReaderT conn . runSource
-- | (Internal) Run a 'C.Source' of rows. -- | (Internal) Run a 'C.Source' of rows.
runSource :: MonadResourceBase m => runSource :: Monad m =>
C.Source (C.ResourceT (SqlPersistT m)) r C.Source (SqlPersistT m) r
-> SqlPersistT m [r] -> SqlPersistT m [r]
runSource src = C.runResourceT $ src C.$$ CL.consume runSource src = src C.$$ CL.consume
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -637,13 +647,12 @@ runSource src = C.runResourceT $ src C.$$ CL.consume
-- | (Internal) Execute an @esqueleto@ statement inside -- | (Internal) Execute an @esqueleto@ statement inside
-- @persistent@'s 'SqlPersistT' monad. -- @persistent@'s 'SqlPersistT' monad.
rawEsqueleto :: ( MonadLogger m rawEsqueleto :: ( MonadIO m )
, MonadResourceBase m )
=> Mode => Mode
-> SqlQuery () -> SqlQuery ()
-> SqlPersistT m Int64 -> SqlPersistT m Int64
rawEsqueleto mode query = do rawEsqueleto mode query = do
conn <- SqlPersistT R.ask conn <- R.ask
uncurry rawExecuteCount $ uncurry rawExecuteCount $
first builderToText $ first builderToText $
toRawSql mode pureQuery (conn, initialIdentState) query toRawSql mode pureQuery (conn, initialIdentState) query
@ -671,16 +680,14 @@ rawEsqueleto mode query = do
-- from $ \\(appointment :: SqlExpr (Entity Appointment)) -> -- from $ \\(appointment :: SqlExpr (Entity Appointment)) ->
-- return () -- return ()
-- @ -- @
delete :: ( MonadLogger m delete :: ( MonadIO m )
, MonadResourceBase m )
=> SqlQuery () => SqlQuery ()
-> SqlPersistT m () -> SqlPersistT m ()
delete = void . deleteCount delete = liftM (const ()) . deleteCount
-- | Same as 'delete', but returns the number of rows affected. -- | Same as 'delete', but returns the number of rows affected.
deleteCount :: ( MonadLogger m deleteCount :: ( MonadIO m )
, MonadResourceBase m )
=> SqlQuery () => SqlQuery ()
-> SqlPersistT m Int64 -> SqlPersistT m Int64
deleteCount = rawEsqueleto DELETE deleteCount = rawEsqueleto DELETE
@ -698,17 +705,15 @@ deleteCount = rawEsqueleto DELETE
-- set p [ PersonAge =. just (val thisYear) -. p ^. PersonBorn ] -- set p [ PersonAge =. just (val thisYear) -. p ^. PersonBorn ]
-- where_ $ isNull (p ^. PersonAge) -- where_ $ isNull (p ^. PersonAge)
-- @ -- @
update :: ( MonadLogger m update :: ( MonadIO m
, MonadResourceBase m
, SqlEntity val ) , SqlEntity val )
=> (SqlExpr (Entity val) -> SqlQuery ()) => (SqlExpr (Entity val) -> SqlQuery ())
-> SqlPersistT m () -> SqlPersistT m ()
update = void . updateCount update = liftM (const ()) . updateCount
-- | Same as 'update', but returns the number of rows affected. -- | Same as 'update', but returns the number of rows affected.
updateCount :: ( MonadLogger m updateCount :: ( MonadIO m
, MonadResourceBase m
, SqlEntity val ) , SqlEntity val )
=> (SqlExpr (Entity val) -> SqlQuery ()) => (SqlExpr (Entity val) -> SqlQuery ())
-> SqlPersistT m Int64 -> SqlPersistT m Int64
@ -1473,19 +1478,19 @@ to16 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p)) = (a,b,c,d,e,f,g,h,i,j,k,
-- | Insert a 'PersistField' for every selected value. -- | Insert a 'PersistField' for every selected value.
insertSelect :: (MonadLogger m, MonadResourceBase m, SqlSelect (SqlExpr (Insertion a)) r, PersistEntity a) => insertSelect :: (MonadIO m, SqlSelect (SqlExpr (Insertion a)) r, PersistEntity a) =>
SqlQuery (SqlExpr (Insertion a)) -> SqlPersistT m () SqlQuery (SqlExpr (Insertion a)) -> SqlPersistT m ()
insertSelect = insertGeneralSelect SELECT insertSelect = insertGeneralSelect SELECT
-- | Insert a 'PersistField' for every unique selected value. -- | Insert a 'PersistField' for every unique selected value.
insertSelectDistinct :: (MonadLogger m, MonadResourceBase m, SqlSelect (SqlExpr (Insertion a)) r, PersistEntity a) => insertSelectDistinct :: (MonadIO m, SqlSelect (SqlExpr (Insertion a)) r, PersistEntity a) =>
SqlQuery (SqlExpr (Insertion a)) -> SqlPersistT m () SqlQuery (SqlExpr (Insertion a)) -> SqlPersistT m ()
insertSelectDistinct = insertGeneralSelect SELECT_DISTINCT insertSelectDistinct = insertGeneralSelect SELECT_DISTINCT
insertGeneralSelect :: (MonadLogger m, MonadResourceBase m, SqlSelect (SqlExpr (Insertion a)) r, PersistEntity a) => insertGeneralSelect :: (MonadIO m, SqlSelect (SqlExpr (Insertion a)) r, PersistEntity a) =>
Mode -> SqlQuery (SqlExpr (Insertion a)) -> SqlPersistT m () Mode -> SqlQuery (SqlExpr (Insertion a)) -> SqlPersistT m ()
insertGeneralSelect mode query = do insertGeneralSelect mode query = do
conn <- SqlPersistT R.ask conn <- R.ask
uncurry rawExecute $ first builderToText $ toRawSql mode insertQuery (conn, initialIdentState) query uncurry rawExecute $ first builderToText $ toRawSql mode insertQuery (conn, initialIdentState) query

View File

@ -19,6 +19,7 @@ import Control.Monad (replicateM, replicateM_)
import Control.Monad.IO.Class (MonadIO(liftIO)) import Control.Monad.IO.Class (MonadIO(liftIO))
import Control.Monad.Logger (MonadLogger(..), runStderrLoggingT, runNoLoggingT) import Control.Monad.Logger (MonadLogger(..), runStderrLoggingT, runNoLoggingT)
import Control.Monad.Trans.Control (MonadBaseControl(..)) import Control.Monad.Trans.Control (MonadBaseControl(..))
import Control.Monad.Trans.Reader (ReaderT)
import Database.Esqueleto import Database.Esqueleto
import Database.Persist.Sqlite (withSqliteConn) import Database.Persist.Sqlite (withSqliteConn)
#if defined (WITH_POSTGRESQL) #if defined (WITH_POSTGRESQL)
@ -793,10 +794,10 @@ main = do
insert' :: ( Functor m insert' :: ( Functor m
, PersistStore m , PersistStore (PersistEntityBackend val)
, PersistMonadBackend m ~ PersistEntityBackend val , MonadIO m
, PersistEntity val ) , PersistEntity val )
=> val -> m (Entity val) => val -> ReaderT (PersistEntityBackend val) m (Entity val)
insert' v = flip Entity v <$> insert v insert' v = flip Entity v <$> insert v