InsertDuplicateUpdate.hs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. {-# LANGUAGE ExistentialQuantification #-}
  2. {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  3. {-# LANGUAGE OverloadedStrings #-}
  4. {-# LANGUAGE QuasiQuotes #-}
  5. {-# LANGUAGE TemplateHaskell #-}
  6. {-# LANGUAGE TypeFamilies #-}
  7. {-# LANGUAGE UndecidableInstances #-}
  8. module InsertDuplicateUpdate where
  9. import Data.List (sort)
  10. import Database.Persist.MySQL
  11. import MyInit
  12. share [mkPersist sqlSettings, mkMigrate "duplicateMigrate"] [persistUpperCase|
  13. Item
  14. name Text sqltype=varchar(80)
  15. description Text
  16. price Double Maybe
  17. quantity Int Maybe
  18. Primary name
  19. deriving Eq Show Ord
  20. |]
  21. specs :: Spec
  22. specs = describe "DuplicateKeyUpdate" $ do
  23. let item1 = Item "item1" "" (Just 3) Nothing
  24. item2 = Item "item2" "hello world" Nothing (Just 2)
  25. items = [item1, item2]
  26. describe "insertOnDuplicateKeyUpdate" $ do
  27. it "inserts appropriately" $ db $ do
  28. deleteWhere ([] :: [Filter Item])
  29. insertOnDuplicateKeyUpdate item1 [ItemDescription =. "i am item 1"]
  30. Just item <- get (ItemKey "item1")
  31. item @== item1
  32. it "performs only updates given if record already exists" $ db $ do
  33. deleteWhere ([] :: [Filter Item])
  34. let newDescription = "I am a new description"
  35. _ <- insert item1
  36. insertOnDuplicateKeyUpdate
  37. (Item "item1" "i am inserted description" (Just 1) (Just 2))
  38. [ItemDescription =. newDescription]
  39. Just item <- get (ItemKey "item1")
  40. item @== item1 { itemDescription = newDescription }
  41. describe "insertManyOnDuplicateKeyUpdate" $ do
  42. it "inserts fresh records" $ db $ do
  43. deleteWhere ([] :: [Filter Item])
  44. insertMany_ items
  45. let newItem = Item "item3" "fresh" Nothing Nothing
  46. insertManyOnDuplicateKeyUpdate
  47. (newItem : items)
  48. [copyField ItemDescription]
  49. []
  50. dbItems <- map entityVal <$> selectList [] []
  51. sort dbItems @== sort (newItem : items)
  52. it "updates existing records" $ db $ do
  53. deleteWhere ([] :: [Filter Item])
  54. insertMany_ items
  55. insertManyOnDuplicateKeyUpdate
  56. items
  57. []
  58. [ItemQuantity +=. Just 1]
  59. it "only copies passing values" $ db $ do
  60. deleteWhere ([] :: [Filter Item])
  61. insertMany_ items
  62. let newItems = map (\i -> i { itemQuantity = Just 0, itemPrice = fmap (*2) (itemPrice i) }) items
  63. postUpdate = map (\i -> i { itemPrice = fmap (*2) (itemPrice i) }) items
  64. insertManyOnDuplicateKeyUpdate
  65. newItems
  66. [ copyUnlessEq ItemQuantity (Just 0)
  67. , copyField ItemPrice
  68. ]
  69. []
  70. dbItems <- sort . fmap entityVal <$> selectList [] []
  71. dbItems @== sort postUpdate
  72. it "inserts without modifying existing records if no updates specified" $ db $ do
  73. let newItem = Item "item3" "hi friends!" Nothing Nothing
  74. deleteWhere ([] :: [Filter Item])
  75. insertMany_ items
  76. insertManyOnDuplicateKeyUpdate
  77. (newItem : items)
  78. []
  79. []
  80. dbItems <- sort . fmap entityVal <$> selectList [] []
  81. dbItems @== sort (newItem : items)