on dev help sign in
money
commit5a626eb1f54b32e90eaf7f2715347ea9abbf0e2c authorEitan Chatav <eitan@Eitans-MacBook-Pro.local> dateSat 2 Mar 2019, 09:46 (8 years ago) parent91a5653
3 files changed+36−1
squeal-postgresql/src/Squeal/PostgreSQL/Binary.hs+31−1 squeal-postgresql/src/Squeal/PostgreSQL/Expression.hs+4 squeal-postgresql/src/Squeal/PostgreSQL/Schema.hs+1
squeal-postgresql/src/Squeal/PostgreSQL/Binary.hs+31−1
@@ -209,6 +209,7 @@ module Squeal.PostgreSQL.Binary
209209 , RowPG
210210 , LabelsPG
211211 -- * Storage newtypes
212+ , Money (..)
212213 , Json (..)
213214 , Jsonb (..)
214215 , Composite (..)
@@ -289,6 +290,7 @@ instance ToParam Word64 'PGint8 where toParam = K . Encoding.int8_word64
289290instance ToParam Float 'PGfloat4 where toParam = K . Encoding.float4
290291instance ToParam Double 'PGfloat8 where toParam = K . Encoding.float8
291292instance ToParam Scientific 'PGnumeric where toParam = K . Encoding.numeric
293+instance ToParam Money 'PGmoney where toParam = K . Encoding.int8_int64 . cents
292294instance ToParam UUID 'PGuuid where toParam = K . Encoding.uuid
293295instance ToParam (NetAddr IP) 'PGinet where toParam = K . Encoding.inet
294296instance ToParam Char ('PGchar 1) where toParam = K . Encoding.char_utf8
@@ -465,6 +467,7 @@ instance FromValue 'PGint8 Int64 where fromValue = Decoding.int
465467instance FromValue 'PGfloat4 Float where fromValue = Decoding.float4
466468instance FromValue 'PGfloat8 Double where fromValue = Decoding.float8
467469instance FromValue 'PGnumeric Scientific where fromValue = Decoding.numeric
470+instance FromValue 'PGmoney Money where fromValue = Money <$> Decoding.int
468471instance FromValue 'PGuuid UUID where fromValue = Decoding.uuid
469472instance FromValue 'PGinet (NetAddr IP) where fromValue = Decoding.inet
470473instance FromValue ('PGchar 1) Char where fromValue = Decoding.char
@@ -713,7 +716,34 @@ replicateMN
713716 :: forall x xs m. (All ((~) x) xs, Monad m, SListI xs)
714717 => m x -> m (NP I xs)
715718replicateMN mx = hsequence' $
716− hcpure (Proxy :: Proxy ((~) x)) (Comp (I <$> mx))
719+ hcpure (Proxy :: Proxy ((~) x)) (Comp (I <$> mx))
720+
721+{- | The `Money` newtype stores a monetary value in terms
722+of the number of cents, i.e. @$2,000.20@ would be expressed as
723+@Money { cents = 200020 }@.
724+
725+>>> import Control.Monad (void)
726+>>> import Control.Monad.Base (liftBase)
727+>>> import Squeal.PostgreSQL
728+>>> :{
729+let
730+ roundTrip :: Query_ (Public '[]) (Only Money) (Only Money)
731+ roundTrip = values_ $ parameter @1 money `as` #fromOnly
732+:}
733+
734+>>> let input = Only (Money 20020)
735+
736+>>> :{
737+void . withConnection "host=localhost port=5432 dbname=exampledb" $ do
738+ result <- runQueryParams roundTrip input
739+ Just output <- firstRow result
740+ liftBase . print $ input == output
741+:}
742+True
743+-}
744+newtype Money = Money { cents :: Int64 }
745+ deriving (Eq, Ord, Show, Read, GHC.Generic)
746+type instance PG Money = 'PGmoney
717747
718748{- | The `Json` newtype is an indication that the Haskell
719749type it's applied to should be stored as a `PGjson`.
squeal-postgresql/src/Squeal/PostgreSQL/Expression.hs+4
@@ -175,6 +175,7 @@ module Squeal.PostgreSQL.Expression
175175 , real
176176 , float8
177177 , doublePrecision
178+ , money
178179 , text
179180 , char
180181 , character
@@ -1926,6 +1927,9 @@ real = UnsafeTypeExpression "real"
19261927float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
19271928float8 = UnsafeTypeExpression "float8"
19281929doublePrecision = UnsafeTypeExpression "double precision"
1930+-- | currency amount
1931+money :: TypeExpression schema (nullity 'PGmoney)
1932+money = UnsafeTypeExpression "money"
19291933-- | variable-length character string
19301934text :: TypeExpression schemas (nullity 'PGtext)
19311935text = UnsafeTypeExpression "text"
squeal-postgresql/src/Squeal/PostgreSQL/Schema.hs+1
@@ -145,6 +145,7 @@ data PGType
145145 | PGnumeric -- ^ arbitrary precision numeric type
146146 | PGfloat4 -- ^ single precision floating-point number (4 bytes)
147147 | PGfloat8 -- ^ double precision floating-point number (8 bytes)
148+ | PGmoney -- ^ currency amount
148149 | PGchar Nat -- ^ fixed-length character string
149150 | PGvarchar Nat -- ^ variable-length character string
150151 | PGtext -- ^ variable-length character string