Skip to content

Commit 21afc24

Browse files
epostjim108dev
andauthoredMar 1, 2021
Spago and db script updates by jim108dev (#30)
* Add Spago build * Eliminate Pulp and Bower * Add script sql/create-db.sql * Fix tests Co-authored-by: jim108dev <[email protected]>
1 parent cef0eee commit 21afc24

9 files changed

+1769
-163
lines changed
 

‎.gitignore

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
bower_components/
2-
node_modules/
3-
output/
4-
README.html
1+
# Dependencies
2+
.psci_modules
3+
bower_components
4+
node_modules
5+
6+
# Generated files
7+
.psci
8+
output
9+
/.pulp-cache/
10+
/output/
11+
/generated-docs/
12+
/.psc-package/
13+
/.psc*
14+
/.purs*
15+
/.psa*
16+
/.spago

‎bower.json

-46
This file was deleted.

‎package-lock.json

+1,624
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+5-6
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
"test": "test"
88
},
99
"scripts": {
10-
"postinstall": "bower install",
11-
"build": "pulp build",
12-
"test": "pulp test"
10+
"postinstall": "spago install",
11+
"build": "spago build",
12+
"test": "spago test"
1313
},
1414
"repository": {
1515
"type": "git",
@@ -30,8 +30,7 @@
3030
"pg": "^7.10.0"
3131
},
3232
"devDependencies": {
33-
"bower": "^1.8.8",
34-
"pulp": "^12.4.2",
35-
"purescript": "^0.12.5"
33+
"purescript": "^0.13.8",
34+
"spago": "^0.19.1"
3635
}
3736
}

‎packages.dhall

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
let upstream =
2+
https://github.com/purescript/package-sets/releases/download/psc-0.13.8-20210118/packages.dhall sha256:a59c5c93a68d5d066f3815a89f398bcf00e130a51cb185b2da29b20e2d8ae115
3+
4+
in upstream

‎spago.dhall

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{ name = "purescript-node-postgres"
2+
, dependencies =
3+
[ "console", "effect", "js-date", "psci-support", "simple-json", "spec" ]
4+
, packages = ./packages.dhall
5+
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
6+
}

‎sql/create-db.sql

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
DROP DATABASE IF EXISTS test;
2+
3+
CREATE DATABASE test;
4+
CREATE USER testuser WITH ENCRYPTED PASSWORD 'test';
5+
GRANT ALL PRIVILEGES ON DATABASE test TO testuser;
6+
File renamed without changes.

‎test/Main.purs

+108-107
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ import Database.Postgres (Query(Query), connect, end, execute, execute_, query,
1717
import Database.Postgres.SqlValue (toSql)
1818
import Database.Postgres.Transaction (withTransaction)
1919
import Effect (Effect)
20-
import Effect.Aff (Aff, Error, apathize, attempt)
20+
import Effect.Aff (Aff, Error, apathize, attempt, launchAff_)
2121
import Effect.Class (liftEffect)
2222
import Effect.Exception (error)
2323
import Foreign (Foreign)
2424
import Simple.JSON as JSON
2525
import Test.Spec (describe, it)
2626
import Test.Spec.Assertions (fail, shouldEqual)
2727
import Test.Spec.Reporter.Console (consoleReporter)
28-
import Test.Spec.Runner (run)
28+
import Test.Spec.Runner (runSpec)
2929
import Unsafe.Coerce (unsafeCoerce)
3030

3131
type Artist =
@@ -50,113 +50,114 @@ read' :: forall a. JSON.ReadForeign a => Foreign -> Either Error a
5050
read' = lmap (error <<< show) <<< JSON.read
5151

5252
main :: Effect Unit
53-
main = run [consoleReporter] do
54-
describe "withClient" do
55-
it "Returns a client" do
56-
pool <- liftEffect $ mkPool connectionInfo
57-
withClient pool $ \c -> do
58-
execute_ (Query "delete from artist") c
59-
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c
60-
execute_ (Query "insert into artist values ('Deep Purple', 1968)") c
61-
let
62-
q :: Query Int
63-
q = Query "insert into artist values ('Fairport Convention', 1967) returning year"
64-
65-
year <- queryValue_ read' q c
66-
year `shouldEqual` (Just 1967)
67-
68-
artists <- query_ read' (Query "select * from artist" :: Query Artist) c
69-
length artists `shouldEqual` 3
53+
main = launchAff_ do
54+
runSpec [consoleReporter] do
55+
describe "withClient" do
56+
it "Returns a client" do
57+
pool <- liftEffect $ mkPool connectionInfo
58+
withClient pool $ \c -> do
59+
execute_ (Query "delete from artist") c
60+
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c
61+
execute_ (Query "insert into artist values ('Deep Purple', 1968)") c
62+
let
63+
q :: Query Int
64+
q = Query "insert into artist values ('Fairport Convention', 1967) returning year"
65+
66+
year <- queryValue_ read' q c
67+
year `shouldEqual` (Just 1967)
68+
69+
artists <- query_ read' (Query "select * from artist" :: Query Artist) c
70+
length artists `shouldEqual` 3
71+
liftEffect $ end pool
72+
73+
describe "Low level API" do
74+
it "Can be used to manage connections manually" do
75+
pool <- liftEffect $ mkPool connectionInfo
76+
client <- connect pool
77+
execute_ (Query "delete from artist") client
78+
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") client
79+
80+
artists <- query_ read' (Query "select * from artist order by name desc" :: Query Artist) client
81+
artists `shouldEqual` [{ name: "Led Zeppelin", year: 1968 }]
82+
83+
liftEffect $ release client
7084
liftEffect $ end pool
7185

72-
describe "Low level API" do
73-
it "Can be used to manage connections manually" do
74-
pool <- liftEffect $ mkPool connectionInfo
75-
client <- connect pool
76-
execute_ (Query "delete from artist") client
77-
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") client
78-
79-
artists <- query_ read' (Query "select * from artist order by name desc" :: Query Artist) client
80-
artists `shouldEqual` [{ name: "Led Zeppelin", year: 1968 }]
81-
82-
liftEffect $ release client
83-
liftEffect $ end pool
84-
85-
describe "Error handling" do
86-
it "When query cannot be converted to the requested data type we get an error" do
87-
res <- attempt exampleError
88-
either (const $ pure unit) (const $ fail "FAIL") res
89-
90-
describe "Query params" do
91-
it "Select using a query param" do
92-
pool <- liftEffect $ mkPool connectionInfo
93-
withClient pool $ \c -> do
94-
execute_ (Query "delete from artist") c
95-
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c
96-
execute_ (Query "insert into artist values ('Deep Purple', 1968)") c
97-
execute_ (Query "insert into artist values ('Toto', 1977)") c
98-
artists <- query read' (Query "select * from artist where name = $1" :: Query Artist) [toSql "Toto"] c
99-
length artists `shouldEqual` 1
100-
101-
noRows <- query read' (Query "select * from artist where name = $1" :: Query Artist) [toSql "FAIL"] c
102-
length noRows `shouldEqual` 0
103-
liftEffect $ end pool
104-
105-
describe "data types" do
106-
it "datetimes can be inserted" do
107-
pool <- liftEffect $ mkPool connectionInfo
108-
withClient pool \c -> do
109-
execute_ (Query "delete from types") c
110-
let date = canonicalDate <$> toEnum 2016 <*> Just January <*> toEnum 25
111-
time = Time <$> toEnum 23 <*> toEnum 1 <*> toEnum 59 <*> toEnum 0
112-
dt = DateTime <$> date <*> time
113-
maybe (fail "Not a datetime") (\ts -> do
114-
execute (Query "insert into types(timestamp_no_tz) VALUES ($1)") [toSql ts] c
115-
ts' <- queryValue_ read' (Query "select timestamp_no_tz at time zone 'UTC' from types" :: Query Foreign) c
116-
let res = unsafeCoerce <$> ts' >>= toDateTime
117-
res `shouldEqual` (Just ts)
118-
) dt
119-
liftEffect $ end pool
120-
121-
describe "sql arrays as parameters" $
122-
it "can be passed as a SqlValue" do
123-
pool <- liftEffect $ mkPool connectionInfo
124-
withClient pool \c -> do
125-
execute_ (Query "delete from artist") c
126-
execute_ (Query "insert into artist values ('Zed Leppelin', 1967)") c
127-
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c
128-
execute_ (Query "insert into artist values ('Deep Purple', 1969)") c
129-
artists <- query read' (Query "select * from artist where year = any ($1)" :: Query Artist) [toSql [1968, 1969]] c
130-
length artists `shouldEqual` 2
131-
liftEffect $ end pool
132-
133-
describe "sql boolean as parameter" $
134-
it "can be passed as a SqlValue" do
135-
pool <- liftEffect $ mkPool connectionInfo
136-
withClient pool \c -> do
137-
execute_ (Query "delete from artist") c
138-
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c -- false by default
139-
execute_ (Query "insert into artist values ('Deep Purple', 1969, TRUE)") c
140-
aliveArtists <- query read' (Query "select * from artist where isAlive = ($1)" :: Query Artist) [toSql true] c
141-
notAliveArtists <- query read' (Query "select * from artist where isAlive = ($1)" :: Query Artist) [toSql false] c
142-
length aliveArtists `shouldEqual` 1
143-
length notAliveArtists `shouldEqual` 1
144-
liftEffect $ end pool
145-
146-
describe "transactions" do
147-
it "does not commit after an error inside a transaction" do
148-
pool <- liftEffect $ mkPool connectionInfo
149-
withClient pool $ \c -> do
150-
execute_ (Query "delete from artist") c
151-
apathize $ tryInsert c
152-
one <- queryOne_ read' (Query "select * from artist" :: Query Artist) c
153-
154-
one `shouldEqual` Nothing
155-
liftEffect $ end pool
156-
where
157-
tryInsert = withTransaction $ \c -> do
158-
execute_ (Query "insert into artist values ('Not there', 1999)") c
159-
throwError $ error "fail"
86+
describe "Error handling" do
87+
it "When query cannot be converted to the requested data type we get an error" do
88+
res <- attempt exampleError
89+
either (const $ pure unit) (const $ fail "FAIL") res
90+
91+
describe "Query params" do
92+
it "Select using a query param" do
93+
pool <- liftEffect $ mkPool connectionInfo
94+
withClient pool $ \c -> do
95+
execute_ (Query "delete from artist") c
96+
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c
97+
execute_ (Query "insert into artist values ('Deep Purple', 1968)") c
98+
execute_ (Query "insert into artist values ('Toto', 1977)") c
99+
artists <- query read' (Query "select * from artist where name = $1" :: Query Artist) [toSql "Toto"] c
100+
length artists `shouldEqual` 1
101+
102+
noRows <- query read' (Query "select * from artist where name = $1" :: Query Artist) [toSql "FAIL"] c
103+
length noRows `shouldEqual` 0
104+
liftEffect $ end pool
105+
106+
describe "data types" do
107+
it "datetimes can be inserted" do
108+
pool <- liftEffect $ mkPool connectionInfo
109+
withClient pool \c -> do
110+
execute_ (Query "delete from types") c
111+
let date = canonicalDate <$> toEnum 2016 <*> Just January <*> toEnum 25
112+
time = Time <$> toEnum 23 <*> toEnum 1 <*> toEnum 59 <*> toEnum 0
113+
dt = DateTime <$> date <*> time
114+
maybe (fail "Not a datetime") (\ts -> do
115+
execute (Query "insert into types(timestamp_no_tz) VALUES ($1)") [toSql ts] c
116+
ts' <- queryValue_ read' (Query "select timestamp_no_tz at time zone 'UTC' from types" :: Query Foreign) c
117+
let res = unsafeCoerce <$> ts' >>= toDateTime
118+
res `shouldEqual` (Just ts)
119+
) dt
120+
liftEffect $ end pool
121+
122+
describe "sql arrays as parameters" $
123+
it "can be passed as a SqlValue" do
124+
pool <- liftEffect $ mkPool connectionInfo
125+
withClient pool \c -> do
126+
execute_ (Query "delete from artist") c
127+
execute_ (Query "insert into artist values ('Zed Leppelin', 1967)") c
128+
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c
129+
execute_ (Query "insert into artist values ('Deep Purple', 1969)") c
130+
artists <- query read' (Query "select * from artist where year = any ($1)" :: Query Artist) [toSql [1968, 1969]] c
131+
length artists `shouldEqual` 2
132+
liftEffect $ end pool
133+
134+
describe "sql boolean as parameter" $
135+
it "can be passed as a SqlValue" do
136+
pool <- liftEffect $ mkPool connectionInfo
137+
withClient pool \c -> do
138+
execute_ (Query "delete from artist") c
139+
execute_ (Query "insert into artist values ('Led Zeppelin', 1968)") c -- false by default
140+
execute_ (Query "insert into artist values ('Deep Purple', 1969, TRUE)") c
141+
aliveArtists <- query read' (Query "select * from artist where isAlive = ($1)" :: Query Artist) [toSql true] c
142+
notAliveArtists <- query read' (Query "select * from artist where isAlive = ($1)" :: Query Artist) [toSql false] c
143+
length aliveArtists `shouldEqual` 1
144+
length notAliveArtists `shouldEqual` 1
145+
liftEffect $ end pool
146+
147+
describe "transactions" do
148+
it "does not commit after an error inside a transaction" do
149+
pool <- liftEffect $ mkPool connectionInfo
150+
withClient pool $ \c -> do
151+
execute_ (Query "delete from artist") c
152+
apathize $ tryInsert c
153+
one <- queryOne_ read' (Query "select * from artist" :: Query Artist) c
154+
155+
one `shouldEqual` Nothing
156+
liftEffect $ end pool
157+
where
158+
tryInsert = withTransaction $ \c -> do
159+
execute_ (Query "insert into artist values ('Not there', 1999)") c
160+
throwError $ error "fail"
160161

161162
exampleError :: Aff (Maybe Artist)
162163
exampleError = do

0 commit comments

Comments
 (0)
Please sign in to comment.