Skip to content

Commit c1a51f8

Browse files
author
Colin de Roos
committed
Remove use of toSqlKey from assignAll
1 parent a896c0a commit c1a51f8

File tree

2 files changed

+43
-41
lines changed

2 files changed

+43
-41
lines changed

persistent-mysql/Database/Persist/MySQL.hs

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
{-# LANGUAGE GADTs #-}
66
{-# LANGUAGE LambdaCase #-}
77
{-# LANGUAGE OverloadedStrings #-}
8+
{-# LANGUAGE ScopedTypeVariables #-}
9+
{-# LANGUAGE TypeApplications #-}
810
{-# LANGUAGE TypeFamilies #-}
911
{-# LANGUAGE TypeOperators #-}
1012
{-# LANGUAGE ViewPatterns #-}
11-
{-# LANGUAGE TypeApplications #-}
12-
{-# LANGUAGE ScopedTypeVariables #-}
1313
-- Pattern match 'PersistDbSpecific'
1414
{-# OPTIONS_GHC -fno-warn-deprecations #-}
1515

@@ -29,7 +29,6 @@ module Database.Persist.MySQL
2929
-- * @ON DUPLICATE KEY UPDATE@ Functionality
3030
, insertOnDuplicateKeyUpdate
3131
, insertManyOnDuplicateKeyUpdate
32-
, assignAll
3332
, HandleUpdateCollision
3433
, copyField
3534
, copyUnlessNull
@@ -43,7 +42,6 @@ import qualified Blaze.ByteString.Builder.ByteString as BBS
4342
import qualified Blaze.ByteString.Builder.Char8 as BBB
4443

4544
import Control.Arrow
46-
import Control.Applicative
4745
import Control.Monad
4846
import Control.Monad.IO.Class (MonadIO (..))
4947
import Control.Monad.IO.Unlift (MonadUnliftIO)
@@ -1495,32 +1493,6 @@ insertOnDuplicateKeyUpdate
14951493
insertOnDuplicateKeyUpdate record =
14961494
insertManyOnDuplicateKeyUpdate [record] []
14971495

1498-
-- | Create a list with an @Update field value Assign@ for every @field@ and
1499-
-- @value@ in record, except its 'Key'.
1500-
-- This is useful in combination with @insertOnDuplicateKeyUpdate@.
1501-
-- @since 2.13.2.0
1502-
assignAll
1503-
:: forall record
1504-
. ( PersistEntityBackend record ~ SqlBackend
1505-
, PersistEntity record
1506-
, ToBackendKey SqlBackend record
1507-
)
1508-
=> record
1509-
-> [Update record]
1510-
assignAll r = snd $ runWriter $ tabulateEntityA $ \field ->
1511-
let
1512-
fieldVal = getConst $ fieldLens field Const fakeEntity
1513-
in
1514-
fieldVal
1515-
<$ when
1516-
( fieldHaskell (persistFieldDef field)
1517-
/= fieldHaskell (persistFieldDef @record persistIdField)
1518-
)
1519-
(tell [Update field fieldVal Assign])
1520-
where
1521-
-- slightly hacky. The entity key is filtered out above and never used.
1522-
fakeEntity = Entity (toSqlKey 0) r
1523-
15241496
-- | This type is used to determine how to update rows using MySQL's
15251497
-- @INSERT ... ON DUPLICATE KEY UPDATE@ functionality, exposed via
15261498
-- 'insertManyOnDuplicateKeyUpdate' in this library.
@@ -1585,14 +1557,14 @@ copyField = CopyField
15851557
-- | Create a list with a @copyField field@ for every @field@ and @value@ in
15861558
-- record, except its @Key@.
15871559
-- This is useful in combination with @insertManyOnDuplicateKeyUpdate@.
1560+
-- The implementation assumes the tabulateEntityA implementation is not strict in
1561+
-- the returned field value (and the default implementation indeed isn't).
15881562
-- @since 2.13.2.0
15891563
copyAll
15901564
:: forall record
15911565
. (PersistEntity record, HasCallStack)
15921566
=> [HandleUpdateCollision record]
15931567
copyAll = snd $ runWriter $ tabulateEntityA $ \field ->
1594-
-- This assumes the tabulateEntityA implementation is not strict in the
1595-
-- returned field value (and the default implementation indeed isn't).
15961568
error "copyAll: field value was used"
15971569
<$ when
15981570
( fieldHaskell (persistFieldDef field)

persistent/Database/Persist/Class/PersistEntity.hs

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ module Database.Persist.Class.PersistEntity
2727
, ViaPersistEntity (..)
2828
, recordName
2929
, entityValues
30+
, assignAll
3031
, keyValueEntityToJSON
3132
, keyValueEntityFromJSON
3233
, entityIdToJSON
@@ -71,6 +72,9 @@ import qualified Data.Aeson.KeyMap as AM
7172
import qualified Data.HashMap.Strict as AM
7273
#endif
7374

75+
import Control.Applicative
76+
import Control.Monad
77+
import Control.Monad.Trans.Writer.CPS
7478
import Data.Kind (Type)
7579
import Data.List.NonEmpty (NonEmpty (..))
7680
import Data.Maybe (isJust)
@@ -82,6 +86,7 @@ import qualified Data.Text.Lazy.Builder as TB
8286
import GHC.Generics
8387
import GHC.OverloadedLabels
8488
import GHC.Records
89+
import GHC.Stack
8590
import GHC.TypeLits
8691

8792
import Database.Persist.Class.PersistField
@@ -175,7 +180,7 @@ class
175180
-- @since 2.14.0.0
176181
tabulateEntityA
177182
:: (Applicative f)
178-
=> (forall a. PersistField a => EntityField record a -> f a)
183+
=> (forall a. (PersistField a) => EntityField record a -> f a)
179184
-- ^ A function that builds a fragment of a record in an
180185
-- 'Applicative' context.
181186
-> f (Entity record)
@@ -187,7 +192,7 @@ class
187192
-- @since 2.17.0.0
188193
tabulateEntityApply
189194
:: (Apply f)
190-
=> (forall a. PersistField a => EntityField record a -> f a)
195+
=> (forall a. (PersistField a) => EntityField record a -> f a)
191196
-> f (Entity record)
192197

193198
-- | Unique keys besides the 'Key'.
@@ -207,7 +212,10 @@ class
207212
fieldLens
208213
:: EntityField record field
209214
-> ( forall f
210-
. (Functor f) => (field -> f field) -> Entity record -> f (Entity record)
215+
. (Functor f)
216+
=> (field -> f field)
217+
-> Entity record
218+
-> f (Entity record)
211219
)
212220

213221
-- | Extract a @'Key' record@ from a @record@ value. Currently, this is
@@ -265,7 +273,7 @@ instance (PersistEntity record) => PathMultiPiece (ViaPersistEntity record) wher
265273
-- @since 2.14.0.0
266274
tabulateEntity
267275
:: (PersistEntity record)
268-
=> (forall a. PersistField a => EntityField record a -> a)
276+
=> (forall a. (PersistField a) => EntityField record a -> a)
269277
-> Entity record
270278
tabulateEntity fromField =
271279
runIdentity (tabulateEntityA (Identity . fromField))
@@ -275,9 +283,7 @@ type family BackendSpecificUpdate backend record
275283
-- Moved over from Database.Persist.Class.PersistUnique
276284

277285
-- | Textual representation of the record
278-
recordName
279-
:: (PersistEntity record)
280-
=> record -> Text
286+
recordName :: (PersistEntity record) => record -> Text
281287
recordName = unEntityNameHS . entityHaskell . entityDef . Just
282288

283289
-- | Updating a database entity.
@@ -391,6 +397,28 @@ entityValues (Entity k record) =
391397
where
392398
ent = entityDef $ Just record
393399

400+
-- | Create a list with an @Update field value Assign@ for every @field@ and
401+
-- @value@ in record, except its 'Key'.
402+
-- This is useful in combination with @upsert@.
403+
-- The implementation assumes 'tabulateEntityA' is not strict in the 'entityKey'
404+
-- of 'Entity' (and the default implementation indeed isn't).
405+
-- @since 2.13.2.0
406+
assignAll
407+
:: forall record. (PersistEntity record, HasCallStack) => record -> [Update record]
408+
assignAll r = snd $ runWriter $ tabulateEntityA $ \field ->
409+
let
410+
fieldVal = getConst $ fieldLens field Const fakeEntity
411+
in
412+
fieldVal
413+
<$ when
414+
( fieldHaskell (persistFieldDef field)
415+
/= fieldHaskell (persistFieldDef @record persistIdField)
416+
)
417+
(tell [Update field fieldVal Assign])
418+
where
419+
-- slightly hacky. The entity key is filtered out above and never used.
420+
fakeEntity = Entity (error "assignAll: tabulateEntityA was strict in the Entity's key") r
421+
394422
-- | Predefined @toJSON@. The resulting JSON looks like
395423
-- @{"key": 1, "value": {"name": ...}}@.
396424
--
@@ -402,7 +430,8 @@ entityValues (Entity k record) =
402430
-- @
403431
keyValueEntityToJSON
404432
:: (PersistEntity record, ToJSON record)
405-
=> Entity record -> Value
433+
=> Entity record
434+
-> Value
406435
keyValueEntityToJSON (Entity key value) =
407436
object
408437
[ "key" .= key
@@ -420,7 +449,8 @@ keyValueEntityToJSON (Entity key value) =
420449
-- @
421450
keyValueEntityFromJSON
422451
:: (PersistEntity record, FromJSON record)
423-
=> Value -> Parser (Entity record)
452+
=> Value
453+
-> Parser (Entity record)
424454
keyValueEntityFromJSON (Object o) =
425455
Entity
426456
<$> o .: "key"

0 commit comments

Comments
 (0)