Skip to content

Commit 5ce6d94

Browse files
authored
Merge pull request #21 from mbg/psql/connection-string
PostgreSql: Support connecting with connection strings
2 parents 4eb9aab + 04945e8 commit 5ce6d94

File tree

5 files changed

+59
-18
lines changed

5 files changed

+59
-18
lines changed

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog for network-wait
22

3+
## 0.3.0
4+
5+
- Functions in the `Network.Wait.PostgreSQL` module are now overloaded to accept different types of connection information. In addition to the previously supported `ConnectInfo` type, the function now also accept connection strings in the form of `ByteString` values.
6+
37
## 0.2.0
48

59
- Add `Network.Wait.Redis` module with functions to wait for Redis servers to become ready to accept connections. This module and its dependency on `hedis` are not enabled by default. The `network-wait:redis` flag must be enabled for this package's Redis support.

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,23 @@ main = do
4141

4242
Internally, this uses `postgresql-simple` to connect to the specified server (`defaultConnectInfo` in the example above) and send a `SELECT 1;` query. If the query is answered correctly, we consider the server to be in a state ready to accept commands.
4343

44+
Alternatively, a connection string may be used instead of a `ConnectInfo` value:
45+
46+
```haskell
47+
import Data.ByteString (ByteString)
48+
import Control.Retry (retryPolicyDefault)
49+
import Database.PostgreSQL.Simple (defaultConnectInfo)
50+
import Network.Wait.PostgreSQL (waitPostgreSQL)
51+
52+
connStr :: ByteString
53+
connStr = "host=localhost port=5432"
54+
55+
main :: IO ()
56+
main = do
57+
waitPostgreSQL retryPolicyDefault connStr
58+
putStrLn "Yay, the PostgreSQL server is ready to accept commands!"
59+
```
60+
4461
The `Network.Wait.PostgreSQL` module is gated behind the `network-wait:postgres` flag so that the PostgreSQL-specific dependencies are only required when PostgresSQL support is required by users of this library.
4562

4663
## Example: Redis

network-wait.cabal

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
cabal-version: 1.12
22

3-
-- This file has been generated from package.yaml by hpack version 0.34.4.
3+
-- This file has been generated from package.yaml by hpack version 0.38.1.
44
--
55
-- see: https://github.com/sol/hpack
66

77
name: network-wait
8-
version: 0.2.0.0
8+
version: 0.3.0.0
99
synopsis: Lightweight library for waiting on networked services to become available.
1010
description: Please see the README on GitHub at <https://github.com/mbg/network-wait#readme> and
1111
Haddock documentation for all modules, including those that are gated behind
@@ -15,7 +15,7 @@ homepage: https://github.com/mbg/network-wait#readme
1515
bug-reports: https://github.com/mbg/network-wait/issues
1616
author: Michael B. Gale
1717
maintainer: github@michael-gale.co.uk
18-
copyright: 2022 Michael B. Gale
18+
copyright: 2025 Michael B. Gale
1919
license: MIT
2020
license-file: LICENSE
2121
build-type: Simple
@@ -47,9 +47,11 @@ library
4747
ghc-options: -Wall
4848
build-depends:
4949
base >=4.7 && <5
50+
, bytestring
5051
, exceptions
5152
, network
5253
, retry
54+
default-language: Haskell2010
5355
if flag(postgres)
5456
build-depends:
5557
postgresql-simple
@@ -62,7 +64,6 @@ library
6264
if flag(redis)
6365
exposed-modules:
6466
Network.Wait.Redis
65-
default-language: Haskell2010
6667

6768
test-suite network-wait-test
6869
type: exitcode-stdio-1.0
@@ -74,20 +75,21 @@ test-suite network-wait-test
7475
ghc-options: -Wall
7576
build-depends:
7677
base >=4.7 && <5
78+
, bytestring
7779
, exceptions
7880
, network
7981
, network-simple
8082
, network-wait
8183
, retry
8284
, tasty
8385
, tasty-hunit
86+
default-language: Haskell2010
8487
if flag(postgres)
8588
build-depends:
8689
postgresql-simple
8790
if flag(redis)
8891
build-depends:
8992
hedis
90-
default-language: Haskell2010
9193

9294
test-suite network-wait-test-postgres
9395
type: exitcode-stdio-1.0
@@ -99,12 +101,14 @@ test-suite network-wait-test-postgres
99101
ghc-options: -Wall
100102
build-depends:
101103
base >=4.7 && <5
104+
, bytestring
102105
, exceptions
103106
, network
104107
, network-wait
105108
, retry
106109
, tasty
107110
, tasty-hunit
111+
default-language: Haskell2010
108112
if flag(postgres)
109113
build-depends:
110114
postgresql-simple
@@ -115,7 +119,6 @@ test-suite network-wait-test-postgres
115119
buildable: True
116120
else
117121
buildable: False
118-
default-language: Haskell2010
119122

120123
test-suite network-wait-test-redis
121124
type: exitcode-stdio-1.0
@@ -127,12 +130,14 @@ test-suite network-wait-test-redis
127130
ghc-options: -Wall
128131
build-depends:
129132
base >=4.7 && <5
133+
, bytestring
130134
, exceptions
131135
, network
132136
, network-wait
133137
, retry
134138
, tasty
135139
, tasty-hunit
140+
default-language: Haskell2010
136141
if flag(postgres)
137142
build-depends:
138143
postgresql-simple
@@ -143,4 +148,3 @@ test-suite network-wait-test-redis
143148
buildable: True
144149
else
145150
buildable: False
146-
default-language: Haskell2010

package.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
name: network-wait
2-
version: 0.2.0.0
2+
version: 0.3.0.0
33
github: "mbg/network-wait"
44
license: MIT
55
author: "Michael B. Gale"
66
maintainer: "github@michael-gale.co.uk"
7-
copyright: "2022 Michael B. Gale"
7+
copyright: "2025 Michael B. Gale"
88

99
extra-source-files:
1010
- README.md
@@ -20,6 +20,7 @@ description: |
2020
2121
dependencies:
2222
- base >= 4.7 && < 5
23+
- bytestring
2324
- exceptions
2425
- network
2526
- retry

src/Network/Wait/PostgreSQL.hs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
-- connection can be established, the functions in this module also check
1313
-- whether the PostgreSQL server is ready to accept commands.
1414
module Network.Wait.PostgreSQL (
15+
PostgreSqlConnectInfo(..),
1516
waitPostgreSql,
1617
waitPostgreSqlVerbose,
1718
waitPostgreSqlVerboseFormat,
@@ -20,6 +21,8 @@ module Network.Wait.PostgreSQL (
2021

2122
-------------------------------------------------------------------------------
2223

24+
import Data.ByteString ( ByteString )
25+
2326
import Control.Monad
2427
import Control.Monad.Catch
2528
import Control.Monad.IO.Class
@@ -32,20 +35,32 @@ import Network.Wait
3235

3336
-------------------------------------------------------------------------------
3437

38+
-- | Used to abstract over different ways to describe a database connection.
39+
class PostgreSqlConnectInfo a where
40+
-- | `connectDb` @info@ attempts to establish a database connection using
41+
-- a configuration given by @info@.
42+
connectDb :: a -> IO Connection
43+
44+
instance PostgreSqlConnectInfo ConnectInfo where
45+
connectDb = connect
46+
47+
instance PostgreSqlConnectInfo ByteString where
48+
connectDb = connectPostgreSQL
49+
3550
-- | `waitPostgreSql` @retryPolicy connectInfo@ is a variant of
3651
-- `waitPostgresWith` which does not install any additional handlers.
3752
waitPostgreSql
38-
:: (MonadIO m, MonadMask m)
39-
=> RetryPolicyM m -> ConnectInfo -> m Connection
53+
:: (MonadIO m, MonadMask m, PostgreSqlConnectInfo info)
54+
=> RetryPolicyM m -> info -> m Connection
4055
waitPostgreSql = waitPostgreSqlWith []
4156

4257
-- | `waitPostgreSqlVerbose` @outputHandler retryPolicy connectInfo@ is a variant
4358
-- of `waitPostgreSqlVerboseFormat` which catches all exceptions derived from
4459
-- `SomeException` and formats retry attempt information using `defaultLogMsg`
4560
-- before passing the resulting `String` to @out@.
4661
waitPostgreSqlVerbose
47-
:: (MonadIO m, MonadMask m)
48-
=> (String -> m ()) -> RetryPolicyM m -> ConnectInfo -> m Connection
62+
:: (MonadIO m, MonadMask m, PostgreSqlConnectInfo info)
63+
=> (String -> m ()) -> RetryPolicyM m -> info -> m Connection
4964
waitPostgreSqlVerbose out =
5065
waitPostgreSqlVerboseFormat @SomeException $
5166
\b ex st -> out $ defaultLogMsg b ex st
@@ -55,10 +70,10 @@ waitPostgreSqlVerbose out =
5570
-- `logRetries` which passes status information for each retry attempt
5671
-- to @outputHandler@.
5772
waitPostgreSqlVerboseFormat
58-
:: forall e m . (MonadIO m, MonadMask m, Exception e)
73+
:: forall e m info. (MonadIO m, MonadMask m, PostgreSqlConnectInfo info, Exception e)
5974
=> (Bool -> e -> RetryStatus -> m ())
6075
-> RetryPolicyM m
61-
-> ConnectInfo
76+
-> info
6277
-> m Connection
6378
waitPostgreSqlVerboseFormat out = waitPostgreSqlWith [h]
6479
where h = logRetries (const $ pure True) out
@@ -74,13 +89,13 @@ waitPostgreSqlVerboseFormat out = waitPostgreSqlWith [h]
7489
-- @extraHandlers@ may also be used to report retry attempts to e.g. the
7590
-- standard output or a logger.
7691
waitPostgreSqlWith
77-
:: (MonadIO m, MonadMask m)
78-
=> [RetryStatus -> Handler m Bool] -> RetryPolicyM m -> ConnectInfo
92+
:: (MonadIO m, MonadMask m, PostgreSqlConnectInfo info)
93+
=> [RetryStatus -> Handler m Bool] -> RetryPolicyM m -> info
7994
-> m Connection
8095
waitPostgreSqlWith hs policy info =
8196
recoveringWith hs policy $
8297
liftIO $
83-
bracket (connect info) close $ \con -> do
98+
bracket (connectDb info) close $ \con -> do
8499
rs <- query_ @[Int] con "SELECT 1;"
85100
unless (rs == [[1]]) $ throwM $
86101
fatalError "Unexpected result for SELECT 1."

0 commit comments

Comments
 (0)