Use makeAff instead of importing PS in FFI code

This commit is contained in:
rightfold 2017-06-03 13:43:30 +02:00
parent c1f9391701
commit feadfc2694
No known key found for this signature in database
GPG Key ID: 199D0373AC917A8F
3 changed files with 78 additions and 50 deletions

View File

@ -3,7 +3,7 @@
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"purescript-prelude": "^3.0.0", "purescript-prelude": "^3.0.0",
"purescript-transformers": "^3.1.0", "purescript-transformers": "^3.2.0",
"purescript-lists": "^4.0.1", "purescript-lists": "^4.0.1",
"purescript-foreign": "^4.0.0", "purescript-foreign": "^4.0.0",
"purescript-aff": "^3.0.0", "purescript-aff": "^3.0.0",

View File

@ -1,52 +1,48 @@
'use strict'; 'use strict';
var Control_Monad_Aff = require('../Control.Monad.Aff');
var pg = require('pg'); var pg = require('pg');
exports.newPool = function(config) { exports.ffiNewPool = function(config) {
return function(onSuccess, onError) { return function() {
onSuccess(new pg.Pool(config)); return new pg.Pool(config);
return Control_Monad_Aff.nonCanceler;
}; };
}; };
exports.withConnection = function(pool) { exports.ffiConnect = function(pool) {
return function(body) { return function(onError) {
return function(onSuccess, onError) { return function(onSuccess) {
pool.connect(function(err, client, done) { return function() {
if (err !== null) { pool.connect(function(err, client, done) {
onError(err);
return;
}
body(client)(function(r) {
done();
onSuccess(r);
}, function(e) {
done(e);
onError(e);
});
});
return Control_Monad_Aff.nonCanceler;
};
};
};
exports._query = function(client) {
return function(sql) {
return function(values) {
return function(onSuccess, onError) {
client.query({
text: sql,
values: values,
rowMode: 'array',
}, function(err, result) {
if (err !== null) { if (err !== null) {
onError(err); onError(err)();
return; return;
} }
onSuccess(result.rows); onSuccess({connection: client, done: done})();
}); });
return Control_Monad_Aff.nonCanceler; };
};
};
};
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)();
});
};
};
}; };
}; };
}; };

View File

@ -12,12 +12,14 @@ module Database.PostgreSQL
, execute , execute
, query , query
, scalar , scalar
, unsafeQuery
) where ) where
import Control.Monad.Aff (Aff) import Control.Monad.Aff (Aff, makeAff)
import Control.Monad.Eff (kind Effect) import Control.Monad.Eff (kind Effect, Eff)
import Control.Monad.Eff.Exception (error) import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Error.Class (catchError, throwError) import Control.Monad.Eff.Exception (Error, error)
import Control.Monad.Error.Class (catchError, throwError, withResource)
import Data.Array (head) import Data.Array (head)
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Foreign (Foreign) import Data.Foreign (Foreign)
@ -55,18 +57,36 @@ newtype Query i o = Query String
derive instance newtypeQuery :: Newtype (Query i o) _ derive instance newtypeQuery :: Newtype (Query i o) _
-- | Create a new connection pool. -- | Create a new connection pool.
foreign import newPool newPool :: eff. PoolConfiguration -> Aff (postgreSQL :: POSTGRESQL | eff) Pool
newPool = liftEff <<< ffiNewPool
foreign import ffiNewPool
:: eff :: eff
. PoolConfiguration . PoolConfiguration
-> Aff (postgreSQL :: POSTGRESQL | eff) Pool -> Eff (postgreSQL :: POSTGRESQL | eff) Pool
-- | Run an action with a connection. The connection is released to the pool -- | Run an action with a connection. The connection is released to the pool
-- | when the action returns. -- | when the action returns.
foreign import withConnection withConnection
:: eff a :: eff a
. Pool . Pool
-> (Connection -> Aff (postgreSQL :: POSTGRESQL | eff) a) -> (Connection -> Aff (postgreSQL :: POSTGRESQL | eff) a)
-> Aff (postgreSQL :: POSTGRESQL | eff) a -> Aff (postgreSQL :: POSTGRESQL | eff) a
withConnection p k =
withResource (makeAff $ ffiConnect p)
(liftEff <<< _.done)
(k <<< _.connection)
foreign import ffiConnect
:: 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
-- | Run an action within a transaction. The transaction is committed if the -- | 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 -- | action returns, and rolled back when the action throws. If you want to
@ -92,7 +112,7 @@ execute
-> i -> i
-> Aff (postgreSQL :: POSTGRESQL | eff) Unit -> Aff (postgreSQL :: POSTGRESQL | eff) Unit
execute conn (Query sql) values = execute conn (Query sql) values =
void $ _query conn sql (toSQLRow values) void $ unsafeQuery conn sql (toSQLRow values)
-- | Execute a PostgreSQL query and return its results. -- | Execute a PostgreSQL query and return its results.
query query
@ -104,11 +124,13 @@ query
-> i -> i
-> Aff (postgreSQL :: POSTGRESQL | eff) (Array o) -> Aff (postgreSQL :: POSTGRESQL | eff) (Array o)
query conn (Query sql) values = query conn (Query sql) values =
_query conn sql (toSQLRow values) unsafeQuery conn sql (toSQLRow values)
>>= traverse (fromSQLRow >>> case _ of >>= traverse (fromSQLRow >>> case _ of
Right row -> pure row Right row -> pure row
Left msg -> throwError (error msg)) Left msg -> throwError (error msg))
-- | Execute a PostgreSQL query and return the first field of the first row in
-- | the result.
scalar scalar
:: i o eff :: i o eff
. ToSQLRow i . ToSQLRow i
@ -121,12 +143,22 @@ scalar conn sql values =
query conn sql values query conn sql values
<#> map (case _ of Row1 a -> a) <<< head <#> map (case _ of Row1 a -> a) <<< head
foreign import _query unsafeQuery
:: eff
. Connection
-> String
-> Array Foreign
-> Aff (postgreSQL :: POSTGRESQL | eff) (Array (Array Foreign))
unsafeQuery c s a = makeAff $ ffiUnsafeQuery c s a
foreign import ffiUnsafeQuery
:: eff :: eff
. Connection . Connection
-> String -> String
-> Array Foreign -> Array Foreign
-> Aff (postgreSQL :: POSTGRESQL | eff) (Array (Array Foreign)) -> (Error -> Eff (postgreSQL :: POSTGRESQL | eff) Unit)
-> (Array (Array Foreign) -> Eff (postgreSQL :: POSTGRESQL | eff) Unit)
-> Eff (postgreSQL :: POSTGRESQL | eff) Unit
fromRight :: a b. Either a b -> Maybe b fromRight :: a b. Either a b -> Maybe b
fromRight (Left _) = Nothing fromRight (Left _) = Nothing