Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Integral types to parse PersistRational #1528

Merged
merged 6 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ packages:
persistent-redis
persistent-qq

constraints:
-- https://github.com/mongodb-haskell/mongodb/pull/152
mongoDB < 2.7.1.3

-- GHC 9.4 shims for persistent

-- These need hackage revisions but otherwise test fine in the repo
Expand Down
7 changes: 7 additions & 0 deletions persistent/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog for persistent

## 2.14.6.1

* [#1528](https://github.com/yesodweb/persistent/pull/1528)
* The `PersistField Int{,8,16,32,64}` instances will now work with a
`PersistRational`, provided that the denominator is 1. This fixes the bug
where `SUM` in Postgres would change the type of a column being summed.

## 2.14.6.0

* [#1477](https://github.com/yesodweb/persistent/pull/1477)
Expand Down
63 changes: 32 additions & 31 deletions persistent/Database/Persist/Class/PersistField.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import Numeric.Natural (Natural)
import Text.Blaze.Html
import Text.Blaze.Html.Renderer.Text (renderHtml)
import GHC.TypeLits
import Data.Ratio (numerator, denominator)

import Database.Persist.Types.Base

Expand Down Expand Up @@ -135,49 +136,49 @@ instance PersistField Html where

instance PersistField Int where
toPersistValue = PersistInt64 . fromIntegral
fromPersistValue (PersistInt64 i) = Right $ fromIntegral i
fromPersistValue (PersistDouble i) = Right (truncate i :: Int) -- oracle
fromPersistValue x = Left $ fromPersistValueError "Int" "integer" x
fromPersistValue = fromPersistValueIntegral "Int" "integer"

instance PersistField Int8 where
toPersistValue = PersistInt64 . fromIntegral
fromPersistValue (PersistInt64 i) = Right $ fromIntegral i
fromPersistValue (PersistDouble i) = Right (truncate i :: Int8) -- oracle
fromPersistValue (PersistByteString bs) = case readInt bs of -- oracle
Just (i,"") -> Right $ fromIntegral i
Just (i,extra) -> Left $ extraInputError "Int64" bs i extra
Nothing -> Left $ intParseError "Int64" bs
fromPersistValue x = Left $ fromPersistValueError "Int8" "integer" x
fromPersistValue = fromPersistValueIntegral "Int8" "integer"

instance PersistField Int16 where
toPersistValue = PersistInt64 . fromIntegral
fromPersistValue (PersistInt64 i) = Right $ fromIntegral i
fromPersistValue (PersistDouble i) = Right (truncate i :: Int16) -- oracle
fromPersistValue (PersistByteString bs) = case readInt bs of -- oracle
Just (i,"") -> Right $ fromIntegral i
Just (i,extra) -> Left $ extraInputError "Int64" bs i extra
Nothing -> Left $ intParseError "Int64" bs
fromPersistValue x = Left $ fromPersistValueError "Int16" "integer" x
fromPersistValue = fromPersistValueIntegral "Int16" "integer"

instance PersistField Int32 where
toPersistValue = PersistInt64 . fromIntegral
fromPersistValue (PersistInt64 i) = Right $ fromIntegral i
fromPersistValue (PersistDouble i) = Right (truncate i :: Int32) -- oracle
fromPersistValue (PersistByteString bs) = case readInt bs of -- oracle
Just (i,"") -> Right $ fromIntegral i
Just (i,extra) -> Left $ extraInputError "Int64" bs i extra
Nothing -> Left $ intParseError "Int64" bs
fromPersistValue x = Left $ fromPersistValueError "Int32" "integer" x
fromPersistValue = fromPersistValueIntegral "Int32" "integer"

instance PersistField Int64 where
toPersistValue = PersistInt64
fromPersistValue (PersistInt64 i) = Right i
fromPersistValue (PersistDouble i) = Right (truncate i :: Int64) -- oracle
fromPersistValue (PersistByteString bs) = case readInt bs of -- oracle
Just (i,"") -> Right $ fromIntegral i
Just (i,extra) -> Left $ extraInputError "Int64" bs i extra
Nothing -> Left $ intParseError "Int64" bs
fromPersistValue x = Left $ fromPersistValueError "Int64" "integer" x
fromPersistValue = fromPersistValueIntegral "Int64" "integer"

fromPersistValueIntegral :: Integral a => Text -> Text -> PersistValue -> Either Text a
fromPersistValueIntegral haskellType sqlType pv = case pv of
PersistInt64 i ->
Right (fromIntegral i)
PersistDouble i ->
Right $ truncate i -- oracle
PersistRational i ->
case denominator i of
1 ->
Right $ fromIntegral $ numerator i
_denom ->
boom
PersistByteString bs ->
case readInt bs of -- oracle
Just (i,"") ->
Right $ fromIntegral i
Just (i,extra) ->
Left $ extraInputError haskellType bs i extra
Nothing ->
Left $ intParseError haskellType bs
_ ->
boom
where
boom =
Left $ fromPersistValueError haskellType sqlType pv

extraInputError :: (Show result)
=> Text -- ^ Haskell type
Expand Down
2 changes: 1 addition & 1 deletion persistent/persistent.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: persistent
version: 2.14.6.0
version: 2.14.6.1
license: MIT
license-file: LICENSE
author: Michael Snoyman <[email protected]>
Expand Down
3 changes: 3 additions & 0 deletions stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ packages:
- ./persistent-postgresql
- ./persistent-redis
- ./persistent-qq

extra-deps:
- attoparsec-aeson-2.1.0.0
Loading