Update.hs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. module Database.Persist.Redis.Update
  2. ( cmdUpdate
  3. ) where
  4. import Control.Exception (throw)
  5. import Data.Either()
  6. import Data.Functor.Identity
  7. import Data.Functor.Constant
  8. import Database.Persist
  9. import Database.Persist.Redis.Exception
  10. type ASetter s t a b = (a -> Identity b) -> s -> Identity t
  11. set :: ASetter s t a b -> b -> s -> t
  12. set l b = runIdentity . l (\_ -> Identity b)
  13. type Getting r s t a b = (a -> Constant r b) -> s -> Constant r t
  14. view :: s -> Getting a s t a b -> a
  15. view s l = getConstant (l Constant s)
  16. cmdUpdate :: PersistEntity val => Entity val -> [Update val] -> Entity val
  17. cmdUpdate = foldr updateOneField
  18. updateOneField :: PersistEntity val => Update val -> Entity val -> Entity val
  19. updateOneField (BackendUpdate _) _ = throw $ NotSupportedOperation "Backend specific update"
  20. updateOneField (Update field v Assign) oldValue = set (fieldLens field) v oldValue
  21. updateOneField (Update _ _ (BackendSpecificUpdate _)) _ =
  22. throw $ NotSupportedOperation "Backend specific update withing update operation"
  23. updateOneField (Update field v up) oldValue = set (fieldLens field) newValue oldValue
  24. where
  25. lens = fieldLens field
  26. pv = toPersistValue v
  27. oldV = toPersistValue $ view oldValue lens
  28. eitherNewValue = fromPersistValue $ apply up oldV pv
  29. newValue = either (\_ -> throw IncorrectBehavior) id eitherNewValue
  30. apply :: PersistUpdate -> PersistValue -> PersistValue -> PersistValue
  31. apply Assign _ _ = throw IncorrectBehavior
  32. apply Add (PersistInt64 x) (PersistInt64 y) = PersistInt64 (x + y)
  33. apply Add (PersistDouble x) (PersistDouble y) = PersistDouble (x + y)
  34. apply Add (PersistRational x) (PersistRational y) = PersistRational (x + y)
  35. apply Add _ _ = throw $ IncorrectUpdate "Unable to apply addition to this field"
  36. apply Subtract (PersistInt64 x) (PersistInt64 y) = PersistInt64 (x - y)
  37. apply Subtract (PersistDouble x) (PersistDouble y) = PersistDouble (x - y)
  38. apply Subtract (PersistRational x) (PersistRational y) = PersistRational (x - y)
  39. apply Subtract _ _ = throw $ IncorrectUpdate "Unable to apply subtraction to this field"
  40. apply Multiply (PersistInt64 x) (PersistInt64 y) = PersistInt64 (x * y)
  41. apply Multiply (PersistDouble x) (PersistDouble y) = PersistDouble (x * y)
  42. apply Multiply (PersistRational x) (PersistRational y) = PersistRational (x * y)
  43. apply Multiply _ _ = throw $ IncorrectUpdate "Unable to apply subtraction to this field"
  44. apply Divide (PersistInt64 x) (PersistInt64 y) = PersistInt64 (div x y)
  45. apply Divide (PersistDouble x) (PersistDouble y) = PersistDouble (x / y)
  46. apply Divide (PersistRational x) (PersistRational y) = PersistRational (x / y)
  47. apply Divide _ _ = throw $ IncorrectUpdate "Unable to apply subtraction to this field"
  48. apply (BackendSpecificUpdate _) _ _ = throw IncorrectBehavior