Handle numeric values using purescript-decimals

This commit is contained in:
Tomasz Rybarczyk 2018-04-21 13:12:20 +02:00
parent 63c21fb220
commit 9c006c72ce
5 changed files with 40 additions and 14 deletions

View File

@ -4,7 +4,7 @@ purescript-postgresql-client is a PostgreSQL client library for PureScript.
## NOTE: I WILL NO LONGER BE MAINTAINING THIS LIBRARY. DUE TO THE COUNTLESS PROBLEMS AND PITFALLS IN THE NODE.JS POSTGRESQL LIBRARY IT IS NO MORE FUN BUT JUST A MASSIVE PITA. IF ANYBODY WANTS TO VOLUNTEER, PLEASE LET ME KNOW, AND I WILL TRANSFER OWNERSHIP OF THE REPO. I THINK THE ONLY TWO REAL SOLUTIONS WOULD BE TO EITHER WRITE A NEW LIBPQ BINDING FOR NODE OR TO WRITE A PSC BACKEND FOR A DECENT PLATFORM (NOT NODE.JS).
To use this library, you need to add `pg` as an npm dependency. You can also
To use this library, you need to add `pg` and `decimal.js` as an npm dependency. You can also
find this npm library on [https://github.com/brianc/node-postgres][pg].
The purspgpp preprocessor has been replaced by [sqltopurs], which is a code

View File

@ -16,7 +16,8 @@
"purescript-datetime": "^3.0.0",
"purescript-bifunctors": "^3.0.0",
"purescript-eff": "^3.1.0",
"purescript-exceptions": "^3.0.0"
"purescript-exceptions": "^3.0.0",
"purescript-decimals": "^3.4.0"
},
"repository": {
"type": "git",

View File

@ -1,6 +1,7 @@
{
"name": "purescript-postgresql-client",
"dependencies": {
"decimal.js": "^10.0.0",
"pg": "^6.1.2"
}
}

View File

@ -1,5 +1,7 @@
module Database.PostgreSQL.Value where
import Prelude
import Control.Monad.Eff (kind Effect)
import Control.Monad.Error.Class (throwError)
import Control.Monad.Except (runExcept)
@ -7,13 +9,14 @@ import Data.Array as Array
import Data.Bifunctor (lmap)
import Data.ByteString (ByteString)
import Data.DateTime.Instant (Instant)
import Data.Either (Either)
import Data.Decimal (Decimal)
import Data.Decimal as Decimal
import Data.Either (Either, note)
import Data.Foreign (Foreign, isNull, readArray, readBoolean, readChar, readInt, readNumber, readString, toForeign, unsafeFromForeign)
import Data.List (List)
import Data.List as List
import Data.Maybe (Maybe(..))
import Data.Traversable (traverse)
import Prelude
-- | Convert things to SQL values.
class ToSQLValue a where
@ -90,6 +93,14 @@ instance toSQLValueForeign :: ToSQLValue Foreign where
instance fromSQLValueForeign :: FromSQLValue Foreign where
fromSQLValue = pure
instance toSQLValueDecimal :: ToSQLValue Decimal where
toSQLValue = Decimal.toString >>> toForeign
instance fromSQLValueDecimal :: FromSQLValue Decimal where
fromSQLValue v = do
s lmap show $ runExcept (readString v)
note ("Decimal literal parsing failed: " <> s) (Decimal.fromString s)
foreign import null :: Foreign
foreign import instantToString :: Instant -> Foreign
foreign import unsafeIsBuffer :: a. a -> Boolean

View File

@ -9,8 +9,9 @@ import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Exception (EXCEPTION, error)
import Control.Monad.Error.Class (throwError, try)
import Data.Decimal as D
import Data.Maybe (Maybe(..))
import Database.PostgreSQL (POSTGRESQL, Query(..), PoolConfiguration, execute, newPool, query, Row0(..), Row1(..), Row2(..), Row6(..), scalar, withConnection, withTransaction)
import Database.PostgreSQL (POSTGRESQL, PoolConfiguration, Query(Query), Row0(Row0), Row1(Row1), Row2(Row2), Row3(Row3), Row9(Row9), execute, newPool, query, scalar, withConnection, withTransaction)
import Test.Assert (ASSERT, assert)
main :: eff. Eff (assert :: ASSERT, exception :: EXCEPTION, postgreSQL :: POSTGRESQL | eff) Unit
@ -21,14 +22,18 @@ main = void $ launchAff do
CREATE TEMPORARY TABLE foods (
name text NOT NULL,
delicious boolean NOT NULL,
price NUMERIC(4,2) NOT NULL,
PRIMARY KEY (name)
)
""") Row0
execute conn (Query """
INSERT INTO foods (name, delicious)
VALUES ($1, $2), ($3, $4), ($5, $6)
""") (Row6 "pork" true "sauerkraut" false "rookworst" true)
INSERT INTO foods (name, delicious, price)
VALUES ($1, $2, $3), ($4, $5, $6), ($7, $8, $9)
""") (Row9
"pork" true (D.fromString "8.30")
"sauerkraut" false (D.fromString "3.30")
"rookworst" true (D.fromString "5.60"))
names <- query conn (Query """
SELECT name
@ -39,6 +44,14 @@ main = void $ launchAff do
liftEff <<< assert $ names == [Row1 "pork", Row1 "rookworst"]
sour <- query conn (Query """
SELECT name, price
FROM foods
WHERE NOT delicious
ORDER BY name ASC
""") Row0
liftEff <<< assert $ sour == [Row2 "sauerkraut" (D.fromString "3.30")]
testTransactionCommit conn
testTransactionRollback conn
@ -48,9 +61,9 @@ main = void $ launchAff do
deleteAll conn
withTransaction conn do
execute conn (Query """
INSERT INTO foods (name, delicious)
VALUES ($1, $2)
""") (Row2 "pork" true)
INSERT INTO foods (name, delicious, price)
VALUES ($1, $2, $3)
""") (Row3 "pork" true (D.fromString "8.30"))
testCount conn 1
testCount conn 1
@ -58,9 +71,9 @@ main = void $ launchAff do
deleteAll conn
_ <- try $ withTransaction conn do
execute conn (Query """
INSERT INTO foods (name, delicious)
VALUES ($1, $2)
""") (Row2 "pork" true)
INSERT INTO foods (name, delicious, price)
VALUES ($1, $2, $3)
""") (Row3 "pork" true (D.fromString "8.30"))
testCount conn 1
throwError $ error "fail"
testCount conn 0