New DELETE support.
This commit is contained in:
parent
b67fcedfeb
commit
a29183028b
@ -38,17 +38,27 @@ module Database.Esqueleto
|
|||||||
, selectDistinct
|
, selectDistinct
|
||||||
, selectSource
|
, selectSource
|
||||||
, selectDistinctSource
|
, selectDistinctSource
|
||||||
|
, delete
|
||||||
|
|
||||||
-- * Re-exports
|
-- * Re-exports
|
||||||
-- $reexports
|
-- $reexports
|
||||||
|
, deleteKey
|
||||||
, module Database.Persist.GenericSql
|
, module Database.Persist.GenericSql
|
||||||
, module Database.Persist.Store
|
, module Database.Persist.Store
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Database.Esqueleto.Internal.Language
|
import Database.Esqueleto.Internal.Language
|
||||||
import Database.Esqueleto.Internal.Sql
|
import Database.Esqueleto.Internal.Sql
|
||||||
import Database.Persist.Store
|
import Database.Persist.Store hiding (delete)
|
||||||
import Database.Persist.GenericSql
|
import Database.Persist.GenericSql
|
||||||
|
import qualified Database.Persist.Store
|
||||||
|
|
||||||
|
|
||||||
|
-- | Synonym for 'Database.Persist.Store.delete' that does not
|
||||||
|
-- clash with @esqueleto@'s 'delete'.
|
||||||
|
deleteKey :: (PersistStore backend m, PersistEntity val)
|
||||||
|
=> Key backend val -> backend m ()
|
||||||
|
deleteKey = Database.Persist.Store.delete
|
||||||
|
|
||||||
-- $reexports
|
-- $reexports
|
||||||
--
|
--
|
||||||
|
|||||||
@ -16,6 +16,8 @@ module Database.Esqueleto.Internal.Sql
|
|||||||
, selectDistinctSource
|
, selectDistinctSource
|
||||||
, rawSelectSource
|
, rawSelectSource
|
||||||
, runSource
|
, runSource
|
||||||
|
, rawExecute
|
||||||
|
, delete
|
||||||
, toRawSql
|
, toRawSql
|
||||||
, Mode(..)
|
, Mode(..)
|
||||||
) where
|
) where
|
||||||
@ -33,8 +35,8 @@ import Data.Monoid (Monoid(..), (<>))
|
|||||||
import Database.Persist.EntityDef
|
import Database.Persist.EntityDef
|
||||||
import Database.Persist.GenericSql
|
import Database.Persist.GenericSql
|
||||||
import Database.Persist.GenericSql.Internal (Connection(escapeName))
|
import Database.Persist.GenericSql.Internal (Connection(escapeName))
|
||||||
import Database.Persist.GenericSql.Raw (withStmt)
|
import Database.Persist.GenericSql.Raw (withStmt, execute)
|
||||||
import Database.Persist.Store
|
import Database.Persist.Store hiding (delete)
|
||||||
import qualified Control.Monad.Trans.Reader as R
|
import qualified Control.Monad.Trans.Reader as R
|
||||||
import qualified Control.Monad.Trans.State as S
|
import qualified Control.Monad.Trans.State as S
|
||||||
import qualified Control.Monad.Trans.Writer as W
|
import qualified Control.Monad.Trans.Writer as W
|
||||||
@ -370,6 +372,45 @@ runSource :: MonadResourceBase m =>
|
|||||||
runSource src = C.runResourceT $ src C.$$ CL.consume
|
runSource src = C.runResourceT $ src C.$$ CL.consume
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
-- | (Internal) Execute an @esqueleto@ statement inside
|
||||||
|
-- @persistent@'s 'SqlPersist' monad.
|
||||||
|
rawExecute :: ( MonadLogger m
|
||||||
|
, MonadResourceBase m )
|
||||||
|
=> Mode
|
||||||
|
-> SqlQuery ()
|
||||||
|
-> SqlPersist m ()
|
||||||
|
rawExecute mode query = do
|
||||||
|
conn <- SqlPersist R.ask
|
||||||
|
uncurry execute $
|
||||||
|
first (TL.toStrict . TLB.toLazyText) $
|
||||||
|
toRawSql mode (fromDBName conn) query
|
||||||
|
|
||||||
|
|
||||||
|
-- | Execute an @esqueleto@ @DELETE@ query inside @persistent@'s
|
||||||
|
-- 'SqlPersist' monad. Note that currently there are no type
|
||||||
|
-- checks for statements that should not appear on a @DELETE@
|
||||||
|
-- query.
|
||||||
|
--
|
||||||
|
-- Example of usage:
|
||||||
|
--
|
||||||
|
-- @
|
||||||
|
-- delete $
|
||||||
|
-- from $ \appointment ->
|
||||||
|
-- where_ (appointment ^. AppointmentDate <. val now)
|
||||||
|
-- @
|
||||||
|
delete :: ( MonadLogger m
|
||||||
|
, MonadResourceBase m )
|
||||||
|
=> SqlQuery ()
|
||||||
|
-> SqlPersist m ()
|
||||||
|
delete = rawExecute DELETE
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
-- | Pretty prints a 'SqlQuery' into a SQL query.
|
-- | Pretty prints a 'SqlQuery' into a SQL query.
|
||||||
toRawSql :: SqlSelect a r => Mode -> Escape -> SqlQuery a -> (TLB.Builder, [PersistValue])
|
toRawSql :: SqlSelect a r => Mode -> Escape -> SqlQuery a -> (TLB.Builder, [PersistValue])
|
||||||
toRawSql mode esc query =
|
toRawSql mode esc query =
|
||||||
@ -384,7 +425,7 @@ toRawSql mode esc query =
|
|||||||
, makeOrderBy esc orderByClauses
|
, makeOrderBy esc orderByClauses
|
||||||
]
|
]
|
||||||
|
|
||||||
data Mode = SELECT | SELECT_DISTINCT
|
data Mode = SELECT | SELECT_DISTINCT | DELETE
|
||||||
|
|
||||||
|
|
||||||
uncommas :: [TLB.Builder] -> TLB.Builder
|
uncommas :: [TLB.Builder] -> TLB.Builder
|
||||||
@ -395,11 +436,12 @@ uncommas' = (uncommas *** mconcat) . unzip
|
|||||||
|
|
||||||
|
|
||||||
makeSelect :: SqlSelect a r => Escape -> Mode -> a -> (TLB.Builder, [PersistValue])
|
makeSelect :: SqlSelect a r => Escape -> Mode -> a -> (TLB.Builder, [PersistValue])
|
||||||
makeSelect esc mode ret = first (s <>) (sqlSelectCols esc ret)
|
makeSelect esc mode ret = first (s <>) (sqlSelectCols esc ret)
|
||||||
where
|
where
|
||||||
s = case mode of
|
s = case mode of
|
||||||
SELECT -> "SELECT "
|
SELECT -> "SELECT "
|
||||||
SELECT_DISTINCT -> "SELECT DISTINCT "
|
SELECT_DISTINCT -> "SELECT DISTINCT "
|
||||||
|
DELETE -> "DELETE"
|
||||||
|
|
||||||
|
|
||||||
makeFrom :: Escape -> [FromClause] -> (TLB.Builder, [PersistValue])
|
makeFrom :: Escape -> [FromClause] -> (TLB.Builder, [PersistValue])
|
||||||
|
|||||||
20
test/Test.hs
20
test/Test.hs
@ -343,6 +343,26 @@ main = do
|
|||||||
return title
|
return title
|
||||||
liftIO $ ret `shouldBe` [ Single t1, Single t2, Single t3 ]
|
liftIO $ ret `shouldBe` [ Single t1, Single t2, Single t3 ]
|
||||||
|
|
||||||
|
describe "delete" $
|
||||||
|
it "works on a simple example" $
|
||||||
|
run $ do
|
||||||
|
p1e <- insert' p1
|
||||||
|
p2e <- insert' p2
|
||||||
|
p3e <- insert' p3
|
||||||
|
ret1 <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [asc (p ^. PersonName)]
|
||||||
|
return p
|
||||||
|
liftIO $ ret1 `shouldBe` [ p1e, p3e, p2e ]
|
||||||
|
() <- delete $
|
||||||
|
from $ \p ->
|
||||||
|
where_ (p ^. PersonName ==. val (personName p1))
|
||||||
|
ret2 <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [asc (p ^. PersonName)]
|
||||||
|
return p
|
||||||
|
liftIO $ ret2 `shouldBe` [ p3e, p2e ]
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user