Parser.hs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. module Database.Persist.Redis.Parser
  2. ( redisToPerisistValues
  3. , toValue
  4. ) where
  5. import Control.Arrow((***))
  6. import Control.Monad (liftM, liftM3)
  7. import Control.Exception (throw)
  8. import Data.Binary (Binary(..), encode, getWord8, Get)
  9. import qualified Data.Binary as Q
  10. import qualified Data.ByteString as B
  11. import qualified Data.ByteString.Lazy as L
  12. import qualified Data.ByteString.UTF8 as U
  13. import Data.Fixed
  14. import Data.Int (Int64)
  15. import Data.Text (Text, unpack)
  16. import qualified Data.Text as T
  17. import Data.Time
  18. import Data.Word (Word8)
  19. import Database.Persist.Types
  20. import Database.Persist.Redis.Exception
  21. newtype BinText = BinText { unBinText :: Text }
  22. instance Binary BinText where
  23. put = put . U.fromString . unpack . unBinText
  24. get = do
  25. str <- Q.get
  26. return $ BinText $ (T.pack . U.toString) str
  27. newtype BinPico= BinPico { unBinPico :: Pico }
  28. instance Binary BinPico where
  29. put = put . toRational . unBinPico
  30. get = do
  31. x <- Q.get :: Get Rational
  32. return $ BinPico (fromRational x)
  33. newtype BinDiffTime = BinDiffTime { unBinDiffTime :: DiffTime }
  34. instance Binary BinDiffTime where
  35. put = put . toRational . unBinDiffTime
  36. get = do
  37. x <- Q.get :: Get Rational
  38. return $ BinDiffTime (fromRational x)
  39. newtype BinDay = BinDay { unBinDay :: Day }
  40. instance Binary BinDay where
  41. put (BinDay (ModifiedJulianDay x)) = put x
  42. get = do
  43. x <- Q.get :: Get Integer
  44. return $ BinDay (ModifiedJulianDay x)
  45. newtype BinTimeOfDay = BinTimeOfDay { unBinTimeOfDay :: TimeOfDay }
  46. instance Binary BinTimeOfDay where
  47. put (BinTimeOfDay (TimeOfDay h m s)) = do
  48. put h
  49. put m
  50. put (BinPico s)
  51. get = do
  52. let s = liftM unBinPico (Q.get :: Get BinPico)
  53. let tod = liftM3 TimeOfDay (Q.get :: Get Int) (Q.get :: Get Int) s
  54. liftM BinTimeOfDay tod
  55. {-
  56. newtype BinZT = BinZT { unBinZT :: ZT }
  57. instance Binary BinZT where
  58. put (BinZT (ZT (ZonedTime (LocalTime day timeOfDay) (TimeZone mins summer name)))) = do
  59. put (BinDay day)
  60. put (BinTimeOfDay timeOfDay)
  61. put mins
  62. put summer
  63. put name
  64. get = do
  65. day <- Q.get :: Get BinDay
  66. timeOfDay <- Q.get :: Get BinTimeOfDay
  67. mins <- Q.get :: Get Int
  68. summer <- Q.get :: Get Bool
  69. name <- Q.get :: Get String
  70. return $ BinZT $ ZT (ZonedTime (LocalTime (unBinDay day) (unBinTimeOfDay timeOfDay)) (TimeZone mins summer name))
  71. -}
  72. newtype BinPersistValue = BinPersistValue { unBinPersistValue :: PersistValue }
  73. instance Binary BinPersistValue where
  74. put (BinPersistValue (PersistText x)) = do
  75. put (1 :: Word8)
  76. put $ (U.fromString . unpack) x
  77. put (BinPersistValue (PersistByteString x)) = do
  78. put (2 :: Word8)
  79. put x
  80. put (BinPersistValue (PersistInt64 x)) = do
  81. put (3 :: Word8)
  82. put x
  83. put (BinPersistValue (PersistDouble x)) = do
  84. put (4 :: Word8)
  85. put x
  86. put (BinPersistValue (PersistBool x)) = do
  87. put (5 :: Word8)
  88. put x
  89. put (BinPersistValue (PersistDay day)) = do
  90. put (6 :: Word8)
  91. put (BinDay day)
  92. put (BinPersistValue (PersistTimeOfDay tod)) = do
  93. put (7 :: Word8)
  94. put (BinTimeOfDay tod)
  95. put (BinPersistValue (PersistUTCTime (UTCTime day pc))) = do
  96. put (8 :: Word8)
  97. put (BinDay day)
  98. put (BinDiffTime pc)
  99. put (BinPersistValue PersistNull) = put (9 :: Word8)
  100. put (BinPersistValue (PersistList x)) = do
  101. put (10 :: Word8)
  102. put (map BinPersistValue x)
  103. put (BinPersistValue (PersistMap x)) = do
  104. put (11 :: Word8)
  105. put (map (BinText *** BinPersistValue) x)
  106. put (BinPersistValue (PersistRational x)) = do
  107. put (12 :: Word8)
  108. put x
  109. put (BinPersistValue (PersistArray _)) = throw $ NotSupportedValueType "PersistArray"
  110. put (BinPersistValue (PersistDbSpecific _)) = throw $ NotSupportedValueType "PersistDbSpecific"
  111. put (BinPersistValue (PersistObjectId _)) = throw $ NotSupportedValueType "PersistObjectId"
  112. get = do
  113. tag <- getWord8
  114. let pv = case tag of
  115. 1 -> liftM (PersistText . unBinText) (Q.get :: Get BinText)
  116. 2 -> liftM PersistByteString (Q.get :: Get B.ByteString)
  117. 3 -> liftM PersistInt64 (Q.get :: Get Int64)
  118. 4 -> liftM PersistDouble (Q.get :: Get Double)
  119. 5 -> liftM PersistBool (Q.get :: Get Bool)
  120. 6 -> liftM (PersistDay . unBinDay) (Q.get :: Get BinDay)
  121. 7 -> liftM (PersistTimeOfDay . unBinTimeOfDay) (Q.get :: Get BinTimeOfDay)
  122. 8 -> do
  123. d <- Q.get :: Get BinDay
  124. dt <- Q.get :: Get BinDiffTime
  125. let utctime = UTCTime (unBinDay d) (unBinDiffTime dt)
  126. return $ PersistUTCTime utctime
  127. 9 -> return PersistNull
  128. 10-> liftM (PersistList . map unBinPersistValue) (Q.get :: Get [BinPersistValue])
  129. 11-> liftM (PersistMap . map (unBinText *** unBinPersistValue)) (Q.get :: Get [(BinText, BinPersistValue)])
  130. 12-> liftM PersistRational (Q.get :: Get Rational)
  131. -- 13-> liftM (PersistZonedTime . unBinZT) (Q.get :: Get BinZT)
  132. z -> throw $ ParserError ("Incorrect tag " ++ show z ++ " came to Binary deserialization")
  133. liftM BinPersistValue pv
  134. toValue :: PersistValue -> B.ByteString
  135. toValue = L.toStrict . encode . BinPersistValue
  136. castOne :: B.ByteString -> PersistValue
  137. castOne = unBinPersistValue . Q.decode . L.fromStrict
  138. redisToPerisistValues :: [(B.ByteString, B.ByteString)] -> [PersistValue]
  139. redisToPerisistValues = map (castOne . snd)