From 48d6c9d2261762acbfef46a9f332dd10ceca4d34 Mon Sep 17 00:00:00 2001 From: Antti Holvikari Date: Thu, 18 Jun 2015 09:52:18 +0300 Subject: [PATCH] Updates for ps-0.7 --- bower.json | 12 +-- src/Database/Postgres.js | 97 +++++++++++++++++ src/Database/Postgres.purs | 138 +++---------------------- src/Database/Postgres/SqlValue.js | 9 ++ src/Database/Postgres/SqlValue.purs | 9 +- src/Database/Postgres/Transaction.purs | 1 + test/Main.purs | 36 ++++--- 7 files changed, 150 insertions(+), 152 deletions(-) create mode 100644 src/Database/Postgres.js create mode 100644 src/Database/Postgres/SqlValue.js diff --git a/bower.json b/bower.json index 86dac26..d727744 100644 --- a/bower.json +++ b/bower.json @@ -14,12 +14,12 @@ "output" ], "dependencies": { - "purescript-arrays": "~0.3.7", - "purescript-either": "~0.1.8", - "purescript-foreign": "~0.4.2", - "purescript-foldable-traversable": "~0.3.1", - "purescript-transformers": "~0.5.5", + "purescript-arrays": "~0.4.0", + "purescript-either": "~0.2.0", + "purescript-foreign": "~0.5.0", + "purescript-foldable-traversable": "~0.4.0", + "purescript-transformers": "~0.6.0", "purescript-aff": "~0.10.1", - "purescript-integers": "~0.1.0" + "purescript-integers": "~0.2.0" } } diff --git a/src/Database/Postgres.js b/src/Database/Postgres.js new file mode 100644 index 0000000..202a142 --- /dev/null +++ b/src/Database/Postgres.js @@ -0,0 +1,97 @@ + +// module Database.Postgres + +var pg = require('pg'); + +exports["connect'"] = function (conString) { + return function(success, error) { + var client = new pg.Client(conString); + client.connect(function(err) { + if (err) { + error(err); + } else { + success(client); + } + }) + return client; + }; +} + +exports._withClient = function (conString, cb) { + return function(success, error) { + pg.connect(conString, function(err, client, done) { + if (err) { + done(true); + return error(err); + } + cb(client)(function(v) { + done(); + success(v); + }, function(err) { + done(); + error(err); + }) + }); + }; +} + +exports.runQuery_ = function (queryStr) { + return function(client) { + return function(success, error) { + client.query(queryStr, function(err, result) { + if (err) { + error(err); + } else { + success(result.rows); + } + }) + }; + }; +} + +exports.runQuery = function (queryStr) { + return function(params) { + return function(client) { + return function(success, error) { + client.query(queryStr, params, function(err, result) { + if (err) return error(err); + success(result.rows); + }) + }; + }; + }; +} + +exports.runQueryValue_ = function (queryStr) { + return function(client) { + return function(success, error) { + client.query(queryStr, function(err, result) { + if (err) return error(err); + success(result.rows.length > 0 ? result.rows[0][result.fields[0].name] : undefined); + }) + }; + }; +} + +exports.runQueryValue = function (queryStr) { + return function(params) { + return function(client) { + return function(success, error) { + client.query(queryStr, params, function(err, result) { + if (err) return error(err); + success(result.rows.length > 0 ? result.rows[0][result.fields[0].name] : undefined); + }) + }; + }; + }; +} + +exports.end = function (client) { + return function() { + client.end(); + }; +} + +exports.disconnect = function () { + pg.end(); +} diff --git a/src/Database/Postgres.purs b/src/Database/Postgres.purs index 432590d..428a583 100644 --- a/src/Database/Postgres.purs +++ b/src/Database/Postgres.purs @@ -16,6 +16,7 @@ module Database.Postgres , withClient ) where +import Prelude import Control.Alt import Control.Apply ((*>)) import Control.Monad.Eff @@ -45,7 +46,7 @@ type ConnectionString = String type ConnectionInfo = { host :: String , db :: String - , port :: Number + , port :: Int , user :: String , password :: String } @@ -64,7 +65,7 @@ connect :: forall eff. ConnectionInfo -> Aff (db :: DB | eff) Client connect = connect' <<< mkConnectionString -- | Runs a query and returns nothing. -execute :: forall eff a. Query a -> [SqlValue] -> Client -> Aff (db :: DB | eff) Unit +execute :: forall eff a. Query a -> Array SqlValue -> Client -> Aff (db :: DB | eff) Unit execute (Query sql) params client = void $ runQuery sql params client -- | Runs a query and returns nothing @@ -74,13 +75,13 @@ execute_ (Query sql) client = void $ runQuery_ sql client -- | Runs a query and returns all results. query :: forall eff a p . (IsForeign a) - => Query a -> [SqlValue] -> Client -> Aff (db :: DB | eff) [a] + => Query a -> Array SqlValue -> Client -> Aff (db :: DB | eff) (Array a) query (Query sql) params client = do rows <- runQuery sql params client either liftError pure (sequence $ read <$> rows) -- | Just like `query` but does not make any param replacement -query_ :: forall eff a. (IsForeign a) => Query a -> Client -> Aff (db :: DB | eff) [a] +query_ :: forall eff a. (IsForeign a) => Query a -> Client -> Aff (db :: DB | eff) (Array a) query_ (Query sql) client = do rows <- runQuery_ sql client either liftError pure (sequence $ read <$> rows) @@ -88,7 +89,7 @@ query_ (Query sql) client = do -- | Runs a query and returns the first row, if any queryOne :: forall eff a . (IsForeign a) - => Query a -> [SqlValue] -> Client -> Aff (db :: DB | eff) (Maybe a) + => Query a -> Array SqlValue -> Client -> Aff (db :: DB | eff) (Maybe a) queryOne (Query sql) params client = do rows <- runQuery sql params client maybe (pure Nothing) (either liftError (pure <<< Just)) $ read <$> (rows !! 0) @@ -102,7 +103,7 @@ queryOne_ (Query sql) client = do -- | Runs a query and returns a single value, if any. queryValue :: forall eff a . (IsForeign a) - => Query a -> [SqlValue] -> Client -> Aff (db :: DB | eff) (Maybe a) + => Query a -> Array SqlValue -> Client -> Aff (db :: DB | eff) (Maybe a) queryValue (Query sql) params client = do val <- runQueryValue sql params client pure $ either (const Nothing) Just (read val) @@ -134,127 +135,18 @@ withClient info p = runFn2 _withClient (mkConnectionString info) p liftError :: forall e a. ForeignError -> Aff e a liftError err = throwError $ error (show err) -finally :: forall eff a. Aff eff a -> Aff eff Unit -> Aff eff a -finally a sequel = do - res <- attempt a - sequel - either throwError pure res +foreign import connect' :: forall eff. String -> Aff (db :: DB | eff) Client +foreign import _withClient :: forall eff a. Fn2 ConnectionString (Client -> Aff (db :: DB | eff) a) (Aff (db :: DB | eff) a) -foreign import connect' """ - function connect$prime(conString) { - return function(success, error) { - var pg = require('pg'); - var client = new pg.Client(conString); - client.connect(function(err) { - if (err) { - error(err); - } else { - success(client); - } - }) - return client; - } - } - """ :: forall eff. String -> Aff (db :: DB | eff) Client - -foreign import _withClient - """ - function _withClient(conString, cb) { - return function(success, error) { - var pg = require('pg'); - pg.connect(conString, function(err, client, done) { - if (err) { - done(true); - return error(err); - } - cb(client)(function(v) { - done(); - success(v); - }, function(err) { - done(); - error(err); - }) - }); - }; - } - """ :: forall eff a. - Fn2 - ConnectionString - (Client -> Aff (db :: DB | eff) a) - (Aff (db :: DB | eff) a) - -foreign import runQuery_ """ - function runQuery_(queryStr) { - return function(client) { - return function(success, error) { - client.query(queryStr, function(err, result) { - if (err) { - error(err); - } else { - success(result.rows); - } - }) - }; - }; - } - """ :: forall eff. String -> Client -> Aff (db :: DB | eff) [Foreign] +foreign import runQuery_ :: forall eff. String -> Client -> Aff (db :: DB | eff) (Array Foreign) -foreign import runQuery """ - function runQuery(queryStr) { - return function(params) { - return function(client) { - return function(success, error) { - client.query(queryStr, params, function(err, result) { - if (err) return error(err); - success(result.rows); - }) - }; - }; - } - } - """ :: forall eff. String -> [SqlValue] -> Client -> Aff (db :: DB | eff) [Foreign] +foreign import runQuery :: forall eff. String -> Array SqlValue -> Client -> Aff (db :: DB | eff) (Array Foreign) -foreign import runQueryValue_ """ - function runQueryValue_(queryStr) { - return function(client) { - return function(success, error) { - client.query(queryStr, function(err, result) { - if (err) return error(err); - success(result.rows.length > 0 ? result.rows[0][result.fields[0].name] : undefined); - }) - }; - }; - } - """ :: forall eff. String -> Client -> Aff (db :: DB | eff) Foreign +foreign import runQueryValue_ :: forall eff. String -> Client -> Aff (db :: DB | eff) Foreign -foreign import runQueryValue """ - function runQueryValue(queryStr) { - return function(params) { - return function(client) { - return function(success, error) { - client.query(queryStr, params, function(err, result) { - if (err) return error(err); - success(result.rows.length > 0 ? result.rows[0][result.fields[0].name] : undefined); - }) - }; - }; - } - } - """ :: forall eff. String -> [SqlValue] -> Client -> Aff (db :: DB | eff) Foreign +foreign import runQueryValue :: forall eff. String -> Array SqlValue -> Client -> Aff (db :: DB | eff) Foreign -foreign import end """ - function end(client) { - return function() { - client.end(); - }; - } - """ :: forall eff. Client -> Eff (db :: DB | eff) Unit +foreign import end :: forall eff. Client -> Eff (db :: DB | eff) Unit -foreign import disconnect - """ - function disconnect() { - var pg = require('pg'); - pg.end(); - } - """ :: forall eff. Eff (db :: DB | eff) Unit +foreign import disconnect :: forall eff. Eff (db :: DB | eff) Unit diff --git a/src/Database/Postgres/SqlValue.js b/src/Database/Postgres/SqlValue.js new file mode 100644 index 0000000..83b4cbc --- /dev/null +++ b/src/Database/Postgres/SqlValue.js @@ -0,0 +1,9 @@ +'use strict'; + +// module Database.Postgres.SqlValue + +exports.unsafeToSqlValue = function (x) { + return x; +} + +exports.nullSqlValue = null; diff --git a/src/Database/Postgres/SqlValue.purs b/src/Database/Postgres/SqlValue.purs index 4dc6757..d12d8da 100644 --- a/src/Database/Postgres/SqlValue.purs +++ b/src/Database/Postgres/SqlValue.purs @@ -4,6 +4,7 @@ module Database.Postgres.SqlValue , toSql ) where +import Prelude ((<<<)) import Data.Int import Data.Maybe @@ -25,10 +26,6 @@ instance isSqlValueMaybe :: (IsSqlValue a) => IsSqlValue (Maybe a) where toSql Nothing = nullSqlValue toSql (Just x) = toSql x -foreign import unsafeToSqlValue """ - function unsafeToSqlValue(x) { - return x; - } - """ :: forall a. a -> SqlValue +foreign import unsafeToSqlValue :: forall a. a -> SqlValue -foreign import nullSqlValue "var nullSqlValue = null;" :: SqlValue +foreign import nullSqlValue :: SqlValue diff --git a/src/Database/Postgres/Transaction.purs b/src/Database/Postgres/Transaction.purs index 757b6ae..12a851a 100644 --- a/src/Database/Postgres/Transaction.purs +++ b/src/Database/Postgres/Transaction.purs @@ -1,5 +1,6 @@ module Database.Postgres.Transaction where +import Prelude import Control.Apply ((*>)) import Control.Monad.Aff import Control.Monad.Error.Class (throwError) diff --git a/test/Main.purs b/test/Main.purs index 1ae8b80..62e259f 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -1,6 +1,9 @@ module Test.Main where -import Debug.Trace +import Prelude +import qualified Control.Monad.Eff.Console as C +import Control.Monad.Aff.Console (log, print) + import Control.Monad.Eff import Control.Monad.Eff.Class import Control.Monad.Cont.Trans @@ -13,20 +16,19 @@ import Data.Either import Data.Maybe import Data.Foreign import Data.Foreign.Class -import Data.Foreign.Index import Control.Monad.Aff import Database.Postgres import Database.Postgres.SqlValue import Database.Postgres.Transaction -main = runAff (trace <<< show) (const $ trace "All ok") $ do - liftEff <<< trace $ "connecting to " <> mkConnectionString connectionInfo <> "..." +main = runAff C.print (const $ C.log "All ok") $ do + print $ "connecting to " <> mkConnectionString connectionInfo <> "..." exampleUsingWithConnection exampleLowLevel res <- attempt exampleError - liftEff $ either (const $ trace "got an error, like we should") (const $ trace "FAIL") res + either (const $ log "got an error, like we should") (const $ log "FAIL") res exampleQueries @@ -47,21 +49,21 @@ connectionInfo = , password: "test" } -exampleUsingWithConnection :: forall eff. Aff (trace :: Trace, db :: DB | eff) Unit +exampleUsingWithConnection :: forall eff. Aff (console :: C.CONSOLE, db :: DB | eff) Unit exampleUsingWithConnection = withConnection connectionInfo $ \c -> do execute_ (Query "delete from artist") c execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c execute_ (Query "insert into artist values ('Deep Purple', 1968)") c year <- queryValue_ (Query "insert into artist values ('Fairport Convention', 1967) returning year" :: Query Number) c - liftEff $ print (show year) + print (show year) artists <- query_ (Query "select * from artist" :: Query Artist) c - liftEff $ printRows artists + printRows artists -exampleLowLevel :: forall eff. Aff (trace :: Trace, db :: DB | eff) Unit +exampleLowLevel :: forall eff. Aff (console :: C.CONSOLE, db :: DB | eff) Unit exampleLowLevel = do client <- connect connectionInfo artists <- query_ (Query "select * from artist order by name desc" :: Query Artist) client - liftEff $ printRows artists + printRows artists liftEff $ end client exampleError :: forall eff. Aff (db :: DB | eff) (Maybe Artist) @@ -70,29 +72,29 @@ exampleError = withConnection connectionInfo $ \c -> do execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c queryOne_ (Query "select year from artist") c -exampleQueries :: forall eff. Aff (trace :: Trace, db :: DB | eff) Unit +exampleQueries :: forall eff. Aff (console :: C.CONSOLE, db :: DB | eff) Unit exampleQueries = withClient connectionInfo $ \c -> do - liftEff $ trace "Example queries with params:" + log "Example queries with params:" execute_ (Query "delete from artist") c execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c execute_ (Query "insert into artist values ('Deep Purple', 1968)") c execute_ (Query "insert into artist values ('Toto', 1977)") c artists <- query (Query "select * from artist where name = $1" :: Query Artist) [toSql "Toto"] c - liftEff $ printRows artists + printRows artists -exampleTransaction :: forall eff. Aff (db :: DB | eff) Unit +exampleTransaction :: forall eff. Aff (console :: C.CONSOLE, db :: DB | eff) Unit exampleTransaction = withConnection connectionInfo $ \c -> do execute_ (Query "delete from artist") c apathize $ tryInsert c one <- queryOne_ (Query "select * from artist" :: Query Artist) c - liftEff $ trace $ show one + void $ print one where tryInsert = withTransaction $ \c -> do execute_ (Query "insert into artist values ('Not there', 1999)") c throwError $ error "fail" -printRows :: forall a eff. (Show a) => [a] -> Eff (trace :: Trace | eff) Unit -printRows rows = trace $ "result:\n" <> foldMap stringify rows +printRows :: forall a eff. (Show a) => Array a -> Aff (console :: C.CONSOLE | eff) Unit +printRows rows = void $ log $ "result:\n" <> foldMap stringify rows where stringify = show >>> flip (<>) "\n" instance artistShow :: Show Artist where