From 6a0f231eb72bf00d04ddd73721e5f25c9e9fd268 Mon Sep 17 00:00:00 2001 From: Tomasz Rybarczyk Date: Mon, 4 Dec 2017 22:43:36 +0100 Subject: [PATCH 1/2] Upgrade to purescript-aff 4.0.0 --- bower.json | 2 +- src/Database/PostgreSQL.js | 54 ++++++++++++++++-------------- src/Database/PostgreSQL.purs | 65 +++++++++++++++++++++--------------- test/Main.purs | 18 +++++----- 4 files changed, 79 insertions(+), 60 deletions(-) diff --git a/bower.json b/bower.json index c961551..2f2c61f 100644 --- a/bower.json +++ b/bower.json @@ -6,7 +6,7 @@ "purescript-transformers": "^3.2.0", "purescript-lists": "^4.0.1", "purescript-foreign": "^4.0.0", - "purescript-aff": "^3.0.0", + "purescript-aff": "^4.0.0", "purescript-either": "^3.0.0", "purescript-maybe": "^3.0.0", "purescript-foldable-traversable": "^3.0.0", diff --git a/src/Database/PostgreSQL.js b/src/Database/PostgreSQL.js index 7c7aeff..e48d74f 100644 --- a/src/Database/PostgreSQL.js +++ b/src/Database/PostgreSQL.js @@ -8,18 +8,23 @@ exports.ffiNewPool = function(config) { }; }; -exports.ffiConnect = function(pool) { - return function(onError) { - return function(onSuccess) { - return function() { - pool.connect(function(err, client, done) { - if (err !== null) { - onError(err)(); - return; +exports.ffiConnect = function (pool) { + return function (onError, onSuccess) { + var p = pool.connect( + ).then(function(client) { + onSuccess({ + connection: client, + done: function() { + return client.release(); } - onSuccess({connection: client, done: done})(); }); - }; + }).catch(function(err) { + onError(err); + }); + + return function (cancelError, cancelerError, cancelerSuccess) { + p.cancel(); + cancelerSuccess(); }; }; }; @@ -27,21 +32,20 @@ exports.ffiConnect = function(pool) { exports.ffiUnsafeQuery = function(client) { return function(sql) { return function(values) { - return function(onError) { - return function(onSuccess) { - return function() { - client.query({ - text: sql, - values: values, - rowMode: 'array', - }, function(err, result) { - if (err !== null) { - onError(err)(); - return; - } - onSuccess(result.rows)(); - }); - }; + return function(onError, onSuccess) { + var q = client.query({ + text: sql, + values: values, + rowMode: 'array', + }).catch(function(err) { + onError(err); + }).then(function(result) { + onSuccess(result.rows); + }); + + return function (cancelError, cancelerError, cancelerSuccess) { + q.cancel(); + cancelerSuccess(); }; }; }; diff --git a/src/Database/PostgreSQL.purs b/src/Database/PostgreSQL.purs index f2f352e..e5b3053 100644 --- a/src/Database/PostgreSQL.purs +++ b/src/Database/PostgreSQL.purs @@ -15,11 +15,14 @@ module Database.PostgreSQL , unsafeQuery ) where -import Control.Monad.Aff (Aff, makeAff) +import Prelude + +import Control.Monad.Aff (Aff, bracket) +import Control.Monad.Aff.Compat (EffFnAff, fromEffFnAff) import Control.Monad.Eff (kind Effect, Eff) import Control.Monad.Eff.Class (liftEff) -import Control.Monad.Eff.Exception (Error, error) -import Control.Monad.Error.Class (catchError, throwError, withResource) +import Control.Monad.Eff.Exception (error) +import Control.Monad.Error.Class (catchError, throwError) import Data.Array (head) import Data.Either (Either(..)) import Data.Foreign (Foreign) @@ -30,7 +33,6 @@ import Database.PostgreSQL.Row (class FromSQLRow, class ToSQLRow, Row0(..), Row1 import Database.PostgreSQL.Row as Row import Database.PostgreSQL.Value (class FromSQLValue) import Database.PostgreSQL.Value as Value -import Prelude foreign import data POSTGRESQL :: Effect @@ -65,28 +67,41 @@ foreign import ffiNewPool . PoolConfiguration -> Eff (postgreSQL :: POSTGRESQL | eff) Pool --- | Run an action with a connection. The connection is released to the pool --- | when the action returns. + withConnection :: ∀ eff a . Pool -> (Connection -> Aff (postgreSQL :: POSTGRESQL | eff) a) -> Aff (postgreSQL :: POSTGRESQL | eff) a withConnection p k = - withResource (makeAff $ ffiConnect p) - (liftEff <<< _.done) - (k <<< _.connection) + bracket + (connect p) + (liftEff <<< _.done) + (k <<< _.connection) -foreign import ffiConnect +type PostgreSqlEff eff = (postgreSQL :: POSTGRESQL | eff) + +-- | Run an action with a connection. The connection is released to the pool +-- | when the action returns. +connect :: ∀ eff . Pool - -> (Error -> Eff (postgreSQL :: POSTGRESQL | eff) Unit) - -> ( { connection :: Connection - , done :: Eff (postgreSQL :: POSTGRESQL | eff) Unit - } - -> Eff (postgreSQL :: POSTGRESQL | eff) Unit - ) - -> Eff (postgreSQL :: POSTGRESQL | eff) Unit + -> Aff + (postgreSQL :: POSTGRESQL | eff) + { connection :: Connection + , done :: Eff (PostgreSqlEff eff) Unit + } +connect = fromEffFnAff <<< ffiConnect + +foreign import ffiConnect + :: ∀ eff + . Pool + -> EffFnAff + (PostgreSqlEff eff) + { connection :: Connection + , done :: Eff (PostgreSqlEff eff) Unit + } + -- | Run an action within a transaction. The transaction is committed if the -- | action returns, and rolled back when the action throws. If you want to @@ -144,21 +159,19 @@ scalar conn sql values = <#> map (case _ of Row1 a -> a) <<< head unsafeQuery - :: ∀ eff - . Connection - -> String - -> Array Foreign - -> Aff (postgreSQL :: POSTGRESQL | eff) (Array (Array Foreign)) -unsafeQuery c s a = makeAff $ ffiUnsafeQuery c s a + :: ∀ eff + . Connection + -> String + -> Array Foreign + -> Aff (postgreSQL :: POSTGRESQL | eff) (Array (Array Foreign)) +unsafeQuery c s = fromEffFnAff <<< ffiUnsafeQuery c s foreign import ffiUnsafeQuery :: ∀ eff . Connection -> String -> Array Foreign - -> (Error -> Eff (postgreSQL :: POSTGRESQL | eff) Unit) - -> (Array (Array Foreign) -> Eff (postgreSQL :: POSTGRESQL | eff) Unit) - -> Eff (postgreSQL :: POSTGRESQL | eff) Unit + -> EffFnAff (postgreSQL :: POSTGRESQL | eff) (Array (Array Foreign)) fromRight :: ∀ a b. Either a b -> Maybe b fromRight (Left _) = Nothing diff --git a/test/Main.purs b/test/Main.purs index 89655f0..4b873f6 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -2,26 +2,27 @@ module Test.Main ( main ) where +import Prelude + import Control.Monad.Aff (launchAff) 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.Maybe (Maybe(..)) -import Database.PostgreSQL (POSTGRESQL, PoolConfiguration, Query(..), Row0(..), Row1(..), Row2(..), Row6(..), execute, newPool, query, scalar, withConnection, withTransaction) -import Prelude +import Database.PostgreSQL (POSTGRESQL, Query(..), PoolConfiguration, execute, newPool, query, Row0(..), Row1(..), Row2(..), Row6(..), scalar, withConnection, withTransaction) import Test.Assert (ASSERT, assert) main :: ∀ eff. Eff (assert :: ASSERT, exception :: EXCEPTION, postgreSQL :: POSTGRESQL | eff) Unit main = void $ launchAff do pool <- newPool config - withConnection pool \conn -> do + withConnection pool \conn → do execute conn (Query """ - CREATE TEMPORARY TABLE foods ( - name text NOT NULL, - delicious boolean NOT NULL, - PRIMARY KEY (name) - ) + CREATE TEMPORARY TABLE foods ( + name text NOT NULL, + delicious boolean NOT NULL, + PRIMARY KEY (name) + ) """) Row0 execute conn (Query """ @@ -35,6 +36,7 @@ main = void $ launchAff do WHERE delicious ORDER BY name ASC """) Row0 + liftEff <<< assert $ names == [Row1 "pork", Row1 "rookworst"] testTransactionCommit conn From f6f3328149b98335139950581feca85d5dafeea8 Mon Sep 17 00:00:00 2001 From: Tomasz Rybarczyk Date: Tue, 5 Dec 2017 22:12:01 +0100 Subject: [PATCH 2/2] Improve coding style a bit --- src/Database/PostgreSQL.purs | 6 ++---- test/Main.purs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Database/PostgreSQL.purs b/src/Database/PostgreSQL.purs index e5b3053..6989147 100644 --- a/src/Database/PostgreSQL.purs +++ b/src/Database/PostgreSQL.purs @@ -67,7 +67,8 @@ foreign import ffiNewPool . PoolConfiguration -> Eff (postgreSQL :: POSTGRESQL | eff) Pool - +-- | Run an action with a connection. The connection is released to the pool +-- | when the action returns. withConnection :: ∀ eff a . Pool @@ -81,8 +82,6 @@ withConnection p k = type PostgreSqlEff eff = (postgreSQL :: POSTGRESQL | eff) --- | Run an action with a connection. The connection is released to the pool --- | when the action returns. connect :: ∀ eff . Pool @@ -102,7 +101,6 @@ foreign import ffiConnect , done :: Eff (PostgreSqlEff eff) Unit } - -- | Run an action within a transaction. The transaction is committed if the -- | action returns, and rolled back when the action throws. If you want to -- | change the transaction mode, issue a separate `SET TRANSACTION` statement diff --git a/test/Main.purs b/test/Main.purs index 4b873f6..5060f0b 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -16,7 +16,7 @@ import Test.Assert (ASSERT, assert) main :: ∀ eff. Eff (assert :: ASSERT, exception :: EXCEPTION, postgreSQL :: POSTGRESQL | eff) Unit main = void $ launchAff do pool <- newPool config - withConnection pool \conn → do + withConnection pool \conn -> do execute conn (Query """ CREATE TEMPORARY TABLE foods ( name text NOT NULL,