New DELETE support.

This commit is contained in:
Felipe Lessa 2012-09-05 20:34:24 -03:00
parent b67fcedfeb
commit a29183028b
3 changed files with 77 additions and 5 deletions

View File

@ -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
-- --

View File

@ -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])

View File

@ -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 ]
---------------------------------------------------------------------- ----------------------------------------------------------------------