git.iko.soy/typeable/postgresql-simple
on fb4ce5c help sign in
.github/workflows/haskell-ci.yml+47−116
since splitsnapshots
unifiedsplit
@@ -1,6 +1,6 @@
1# This GitHub workflow config has been generated by a script via
1# This GitHub workflow config has been generated by a script via
2#
2#
3−# haskell-ci 'github' 'cabal.project'
3+# haskell-ci 'github' 'postgresql-simple.cabal'
4#
4#
5# To regenerate the script (for example after adjusting tested-with) run
5# To regenerate the script (for example after adjusting tested-with) run
6#
6#
@@ -8,9 +8,9 @@
8#
8#
9# For more information, see https://github.com/haskell-CI/haskell-ci
9# For more information, see https://github.com/haskell-CI/haskell-ci
10#
10#
11−# version: 0.17.20231110
11+# version: 0.11.20210101
12#
12#
13−# REGENDATA ("0.17.20231110",["github","cabal.project"])
13+# REGENDATA ("0.11.20210101",["github","postgresql-simple.cabal"])
14#
14#
15name: Haskell-CI
15name: Haskell-CI
16on:
16on:
@@ -22,15 +22,13 @@ on:
22 - master
22 - master
23jobs:
23jobs:
24 linux:
24 linux:
25− name: Haskell-CI - Linux - ${{ matrix.compiler }}
25+ name: Haskell-CI Linux - GHC ${{ matrix.ghc }}
26− runs-on: ubuntu-20.04
26+ runs-on: ubuntu-18.04
27− timeout-minutes:
28− 60
29 container:
27 container:
30 image: buildpack-deps:bionic
28 image: buildpack-deps:bionic
31 services:
29 services:
32 postgres:
30 postgres:
33− image: postgres:14
31+ image: postgres:10
34 env:
32 env:
35 POSTGRES_PASSWORD: postgres
33 POSTGRES_PASSWORD: postgres
36 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
34 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
@@ -38,105 +36,54 @@ jobs:
38 strategy:
36 strategy:
39 matrix:
37 matrix:
40 include:
38 include:
41− - compiler: ghc-9.8.1
39+ - ghc: 8.10.3
42− compilerKind: ghc
43− compilerVersion: 9.8.1
44− setup-method: ghcup
45 allow-failure: false
40 allow-failure: false
46− - compiler: ghc-9.6.3
41+ - ghc: 8.8.4
47− compilerKind: ghc
48− compilerVersion: 9.6.3
49− setup-method: ghcup
50 allow-failure: false
42 allow-failure: false
51− - compiler: ghc-9.4.8
43+ - ghc: 8.6.5
52− compilerKind: ghc
53− compilerVersion: 9.4.8
54− setup-method: ghcup
55 allow-failure: false
44 allow-failure: false
56− - compiler: ghc-9.2.8
45+ - ghc: 8.4.4
57− compilerKind: ghc
58− compilerVersion: 9.2.8
59− setup-method: ghcup
60 allow-failure: false
46 allow-failure: false
61− - compiler: ghc-9.0.2
47+ - ghc: 8.2.2
62− compilerKind: ghc
63− compilerVersion: 9.0.2
64− setup-method: ghcup
65 allow-failure: false
48 allow-failure: false
66− - compiler: ghc-8.10.7
49+ - ghc: 8.0.2
67− compilerKind: ghc
68− compilerVersion: 8.10.7
69− setup-method: ghcup
70 allow-failure: false
50 allow-failure: false
71− - compiler: ghc-8.8.4
51+ - ghc: 7.10.3
72− compilerKind: ghc
73− compilerVersion: 8.8.4
74− setup-method: hvr-ppa
75 allow-failure: false
52 allow-failure: false
76− - compiler: ghc-8.6.5
53+ - ghc: 7.8.4
77− compilerKind: ghc
54+ allow-failure: false
78− compilerVersion: 8.6.5
55+ - ghc: 7.6.3
79− setup-method: hvr-ppa
80 allow-failure: false
56 allow-failure: false
81 fail-fast: false
57 fail-fast: false
82 steps:
58 steps:
83 - name: apt
59 - name: apt
84 run: |
60 run: |
85 apt-get update
61 apt-get update
86− apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
62+ apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common
87− if [ "${{ matrix.setup-method }}" = ghcup ]; then
88− mkdir -p "$HOME/.ghcup/bin"
89− curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup"
90− chmod a+x "$HOME/.ghcup/bin/ghcup"
91− "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)
92− "$HOME/.ghcup/bin/ghcup" install cabal 3.10.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
93− else
94− apt-add-repository -y 'ppa:hvr/ghc'
63+ apt-add-repository -y 'ppa:hvr/ghc'
95− apt-get update
64+ apt-get update
96− apt-get install -y "$HCNAME"
65+ apt-get install -y ghc-$GHC_VERSION cabal-install-3.2
97− mkdir -p "$HOME/.ghcup/bin"
98− curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup"
99− chmod a+x "$HOME/.ghcup/bin/ghcup"
100− "$HOME/.ghcup/bin/ghcup" install cabal 3.10.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
101− fi
102 env:
66 env:
103− HCKIND: ${{ matrix.compilerKind }}
67+ GHC_VERSION: ${{ matrix.ghc }}
104− HCNAME: ${{ matrix.compiler }}
105− HCVER: ${{ matrix.compilerVersion }}
106 - name: Set PATH and environment variables
68 - name: Set PATH and environment variables
107 run: |
69 run: |
108 echo "$HOME/.cabal/bin" >> $GITHUB_PATH
70 echo "$HOME/.cabal/bin" >> $GITHUB_PATH
109− echo "LANG=C.UTF-8" >> "$GITHUB_ENV"
71+ echo "LANG=C.UTF-8" >> $GITHUB_ENV
110− echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"
72+ echo "CABAL_DIR=$HOME/.cabal" >> $GITHUB_ENV
111− echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
73+ echo "CABAL_CONFIG=$HOME/.cabal/config" >> $GITHUB_ENV
112− HCDIR=/opt/$HCKIND/$HCVER
74+ HC=/opt/ghc/$GHC_VERSION/bin/ghc
113− if [ "${{ matrix.setup-method }}" = ghcup ]; then
114− HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER")
115− HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#')
116− HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#')
117− echo "HC=$HC" >> "$GITHUB_ENV"
75+ echo "HC=$HC" >> $GITHUB_ENV
118− echo "HCPKG=$HCPKG" >> "$GITHUB_ENV"
76+ echo "HCPKG=/opt/ghc/$GHC_VERSION/bin/ghc-pkg" >> $GITHUB_ENV
119− echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV"
120− echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
121− else
122− HC=$HCDIR/bin/$HCKIND
123− echo "HC=$HC" >> "$GITHUB_ENV"
124− echo "HCPKG=$HCDIR/bin/$HCKIND-pkg" >> "$GITHUB_ENV"
125− echo "HADDOCK=$HCDIR/bin/haddock" >> "$GITHUB_ENV"
77+ echo "HADDOCK=/opt/ghc/$GHC_VERSION/bin/haddock" >> $GITHUB_ENV
126− echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
78+ echo "CABAL=/opt/cabal/3.2/bin/cabal -vnormal+nowrap" >> $GITHUB_ENV
127− fi
128−
129 HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
79 HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
130− echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"
80+ echo "HCNUMVER=$HCNUMVER" >> $GITHUB_ENV
131− echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"
81+ echo "ARG_TESTS=--enable-tests" >> $GITHUB_ENV
132− echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"
82+ echo "ARG_BENCH=--enable-benchmarks" >> $GITHUB_ENV
133− echo "HEADHACKAGE=false" >> "$GITHUB_ENV"
134− echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"
83+ echo "ARG_COMPILER=--ghc --with-compiler=/opt/ghc/$GHC_VERSION/bin/ghc" >> $GITHUB_ENV
135− echo "GHCJSARITH=0" >> "$GITHUB_ENV"
84+ echo "GHCJSARITH=0" >> $GITHUB_ENV
136 env:
85 env:
137− HCKIND: ${{ matrix.compilerKind }}
86+ GHC_VERSION: ${{ matrix.ghc }}
138− HCNAME: ${{ matrix.compiler }}
139− HCVER: ${{ matrix.compilerVersion }}
140 - name: env
87 - name: env
141 run: |
88 run: |
142 env
89 env
@@ -159,10 +106,6 @@ jobs:
159 repository hackage.haskell.org
106 repository hackage.haskell.org
160 url: http://hackage.haskell.org/
107 url: http://hackage.haskell.org/
161 EOF
108 EOF
162− cat >> $CABAL_CONFIG <<EOF
163− program-default-options
164− ghc-options: $GHCJOBS +RTS -M3G -RTS
165− EOF
166 cat $CABAL_CONFIG
109 cat $CABAL_CONFIG
167 - name: versions
110 - name: versions
168 run: |
111 run: |
@@ -175,24 +118,20 @@ jobs:
175 - name: install cabal-plan
118 - name: install cabal-plan
176 run: |
119 run: |
177 mkdir -p $HOME/.cabal/bin
120 mkdir -p $HOME/.cabal/bin
178− curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.7.3.0/cabal-plan-0.7.3.0-x86_64-linux.xz > cabal-plan.xz
121+ curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz
179− echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c -
122+ echo 'de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz' | sha256sum -c -
180 xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan
123 xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan
181 rm -f cabal-plan.xz
124 rm -f cabal-plan.xz
182 chmod a+x $HOME/.cabal/bin/cabal-plan
125 chmod a+x $HOME/.cabal/bin/cabal-plan
183 cabal-plan --version
126 cabal-plan --version
184 - name: checkout
127 - name: checkout
185− uses: actions/checkout@v3
128+ uses: actions/checkout@v2
186 with:
129 with:
187 path: source
130 path: source
188− - name: initial cabal.project for sdist
189− run: |
190− touch cabal.project
191− echo "packages: $GITHUB_WORKSPACE/source/." >> cabal.project
192− cat cabal.project
193 - name: sdist
131 - name: sdist
194 run: |
132 run: |
195 mkdir -p sdist
133 mkdir -p sdist
134+ cd source || false
196 $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist
135 $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist
197 - name: unpack
136 - name: unpack
198 run: |
137 run: |
@@ -201,15 +140,13 @@ jobs:
201 - name: generate cabal.project
140 - name: generate cabal.project
202 run: |
141 run: |
203 PKGDIR_postgresql_simple="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/postgresql-simple-[0-9.]*')"
142 PKGDIR_postgresql_simple="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/postgresql-simple-[0-9.]*')"
204− echo "PKGDIR_postgresql_simple=${PKGDIR_postgresql_simple}" >> "$GITHUB_ENV"
143+ echo "PKGDIR_postgresql_simple=${PKGDIR_postgresql_simple}" >> $GITHUB_ENV
205− rm -f cabal.project cabal.project.local
206 touch cabal.project
144 touch cabal.project
207 touch cabal.project.local
145 touch cabal.project.local
208 echo "packages: ${PKGDIR_postgresql_simple}" >> cabal.project
146 echo "packages: ${PKGDIR_postgresql_simple}" >> cabal.project
209− echo "package postgresql-simple" >> cabal.project
147+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package postgresql-simple" >> cabal.project ; fi
210− echo " ghc-options: -Werror=missing-methods" >> cabal.project
148+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi
211 cat >> cabal.project <<EOF
149 cat >> cabal.project <<EOF
212− allow-newer: cryptohash-md5-0.11.100.1:base
213 EOF
150 EOF
214 $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(postgresql-simple)$/; }' >> cabal.project.local
151 $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(postgresql-simple)$/; }' >> cabal.project.local
215 cat cabal.project
152 cat cabal.project
@@ -218,12 +155,12 @@ jobs:
218 run: |
155 run: |
219 $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all
156 $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all
220 cabal-plan
157 cabal-plan
221− - name: restore cache
158+ - name: cache
222− uses: actions/cache/restore@v3
159+ uses: actions/cache@v2
223 with:
160 with:
224− key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
161+ key: ${{ runner.os }}-${{ matrix.ghc }}-${{ github.sha }}
225 path: ~/.cabal/store
162 path: ~/.cabal/store
226− restore-keys: ${{ runner.os }}-${{ matrix.compiler }}-
163+ restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-
227 - name: install dependencies
164 - name: install dependencies
228 run: |
165 run: |
229 $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all
166 $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all
@@ -243,14 +180,8 @@ jobs:
243 ${CABAL} -vnormal check
180 ${CABAL} -vnormal check
244 - name: haddock
181 - name: haddock
245 run: |
182 run: |
246− $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
183+ $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
247 - name: unconstrained build
184 - name: unconstrained build
248 run: |
185 run: |
249 rm -f cabal.project.local
186 rm -f cabal.project.local
250 $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
187 $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
251− - name: save cache
252− uses: actions/cache/save@v3
253− if: always()
254− with:
255− key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
256− path: ~/.cabal/store
.github/workflows/simple.ymldeleted−58
@@ -1,58 +0,0 @@
1−name: Simple
2−on:
3− push:
4− branches:
5− - master
6− pull_request:
7− branches:
8− - master
9−
10−jobs:
11− native:
12− name: "Simple: GHC ${{ matrix.ghc }} on ${{ matrix.os }}"
13− runs-on: ${{ matrix.os }}
14− strategy:
15− matrix:
16− os: [macos-latest, windows-latest]
17− ghc: ['8.10','9.0','9.2','9.4.8','9.6.3','9.8.1']
18− fail-fast: false
19− timeout-minutes:
20− 60
21− steps:
22− - name: Set git to use LF
23− run: |
24− git config --global core.autocrlf false
25− git config --global core.eol lf
26−
27− - name: Set up Haskell
28− id: setup-haskell
29− uses: haskell/actions/setup@v2
30− with:
31− ghc-version: ${{ matrix.ghc }}
32− cabal-version: '3.10.2.0'
33−
34− - name: Set up PostgreSQL
35− uses: ikalnytskyi/action-setup-postgres@v3
36− id: postgres
37− with:
38− username: ci
39− password: sw0rdfish
40− database: test
41−
42− - name: Checkout
43− uses: actions/checkout@v3.0.2
44−
45− - name: Cache
46− uses: actions/cache@v2.1.3
47− with:
48− path: ${{ steps.setup-haskell.outputs.cabal-store }}
49− key: ${{ runner.os }}-${{ matrix.ghc }}-${{ github.sha }}
50− restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-
51−
52− - name: Build
53− run: cabal build all --enable-tests
54−
55− - name: Test
56− run: cabal test all --enable-tests --test-show-details=direct
57− env:
58− DATABASE_CONNSTRING: ${{ steps.postgres.outputs.connection-uri }}
CHANGES.md+4−22
@@ -1,21 +1,3 @@
1−### Version 0.7.0.0 (2023-07-31)
2−
3− * Remove Eq Null instance. (Future `base` may break it, we remove it profilacticly).
4− * Use `postgresql-libpq >=0.10.0.0`. It includes critical fixes,
5− by using `postgresql-simple >=0.7` you won't get older `postgresql-libpq`.
6− * Drop support for GHC prior 8.6
7− * Added a class for `postgresql-simple` exceptions: `SomePostgreSqlException`.
8− This allows to catch all `postgresql-simple` exceptions at once.
9− (c.f. `AsyncException` in `base).
10−
11−### Version 0.6.5.1 (2023-07-09)
12−
13− * Support `aeson-2.2.0.0`
14−
15−### Version 0.6.5 (2022-10-30)
16−
17− * Add `withConnect`
18−
19### Version 0.6.4 (2021-01-06)
1### Version 0.6.4 (2021-01-06)
20
2
21 * Add foldCopyData helper function
3 * Add foldCopyData helper function
@@ -271,7 +253,7 @@
271 support UTF8 except for Mule Internal Code, the Multilingual
253 support UTF8 except for Mule Internal Code, the Multilingual
272 Extensions for Emacs. An exception should be raised upon
254 Extensions for Emacs. An exception should be raised upon
273 connecting to a database by the backend if the backend cannot
255 connecting to a database by the backend if the backend cannot
274− accommodate this requirement.
256+ accomodate this requirement.
275
257
276 * Added `Eq` and `Typeable` instances for `Connection`.
258 * Added `Eq` and `Typeable` instances for `Connection`.
277
259
@@ -409,7 +391,7 @@
409
391
410 * Changed the Identifier and QualifiedIdentifier to use Text in
392 * Changed the Identifier and QualifiedIdentifier to use Text in
411 order to avoid encoding errors. Technically this requires a
393 order to avoid encoding errors. Technically this requires a
412− major version bump, but let's pretend 0.4.1.0 didn't happen.
394+ major verson bump, but let's pretend 0.4.1.0 didn't happen.
413
395
414 * Removed non-exhaustive cases in the ToField instance for Values,
396 * Removed non-exhaustive cases in the ToField instance for Values,
415 and tweaked error messages.
397 and tweaked error messages.
@@ -569,7 +551,7 @@
569
551
570 * Added a brand new TypeInfo system that gives FromField instances
552 * Added a brand new TypeInfo system that gives FromField instances
571 convenient and efficient access to the pg_type metatable. This
553 convenient and efficient access to the pg_type metatable. This
572− replaced the older typename cache, and was necessary to properly
554+ replaced the older typename cache, and was neccesary to properly
573 support postgres array types. Thanks to Bas van Dijk for his
555 support postgres array types. Thanks to Bas van Dijk for his
574 work on this feature.
556 work on this feature.
575
557
@@ -661,7 +643,7 @@
661 now the preferred way of dealing with `timestamp` (without time zone).
643 now the preferred way of dealing with `timestamp` (without time zone).
662
644
663 * `Database.PostgreSQL.Simple.Time` is a new module that offers types
645 * `Database.PostgreSQL.Simple.Time` is a new module that offers types
664− that accommodate PostgreSQL's infinities.
646+ that accomodate PostgreSQL's infinities.
665
647
666 * All time-related `FromField`/`ToField` instances are now based on new,
648 * All time-related `FromField`/`ToField` instances are now based on new,
667 higher-speed parsers and printers instead of those provided by the
649 higher-speed parsers and printers instead of those provided by the
CONTRIBUTING.md+1−1
@@ -4,7 +4,7 @@ Patches welcome!
4 - If it's really **only bounds**, please simply open an issue (so you'll have a URL to refer to). I have a semi-automated process to make revisions, pull requests only disturb it.
4 - If it's really **only bounds**, please simply open an issue (so you'll have a URL to refer to). I have a semi-automated process to make revisions, pull requests only disturb it.
5 - If patch includes **source code change** (i.e. I'll need to make a release), and it's a patch to support **newer base/GHC version**:
5 - If patch includes **source code change** (i.e. I'll need to make a release), and it's a patch to support **newer base/GHC version**:
6 - Amend `tested-with` to include that GHC
6 - Amend `tested-with` to include that GHC
7− - Regenerate `.github/workflows/haskell-ci.yml` with `haskell-ci regenerate` (get the latest from [GitHub haskell-ci/haskell-ci](https://github.com/haskell-ci/haskell-ci))
7+ - Regenerate `.travis.yml` with `haskell-ci regenerate` (get the latest from [GitHub haskell-ci/haskell-ci](https://github.com/haskell-ci/haskell-ci))
8
8
9- Don't edit `CHANGELOG.md`, rather include a copyable entry in your pull request description. I often process pull requests in bulk, and everyone editing the `CHANGELOG.md` causes unnecessary conflicts.
9- Don't edit `CHANGELOG.md`, rather include a copyable entry in your pull request description. I often process pull requests in bulk, and everyone editing the `CHANGELOG.md` causes unnecessary conflicts.
10- For the same reason, do not edit `version` or `x-revision`
10- For the same reason, do not edit `version` or `x-revision`
appveyor.ymlnew file+80
@@ -0,0 +1,80 @@
1+clone_folder: "c:\\WORK"
2+
3+branches:
4+ only:
5+ - master
6+
7+services:
8+ - postgresql96
9+
10+environment:
11+ global:
12+ CABOPTS: "--store-dir=C:\\SR --http-transport=plain-http"
13+ PGUSER: postgres
14+ PGPASSWORD: Password12!
15+ PGPORT: "5432"
16+ DATABASE_CONNSTRING: appveyor
17+ matrix:
18+ # 64 bit builds
19+ - GHCVER: "8.8.1"
20+ CHOCOPTS:
21+ - GHCVER: "8.6.5"
22+ CHOCOPTS:
23+ - GHCVER: "8.4.4"
24+ CHOCOPTS:
25+ - GHCVER: "8.2.2"
26+ CHOCOPTS:
27+ - GHCVER: "8.0.2"
28+ CHOCOPTS:
29+ - GHCVER: "7.10.3.2"
30+ CHOCOPTS:
31+
32+ # Fails to link
33+ #
34+ # - GHCVER: "7.8.4.1"
35+ # CHOCOPTS:
36+
37+ # 32 bit builds
38+
39+ # Linker errors...
40+
41+ # - GHCVER: "8.6.5"
42+ # CHOCOPTS: --forcex86
43+ # - GHCVER: "8.4.4"
44+ # CHOCOPTS: --forcex86
45+ # - GHCVER: "8.2.2"
46+ # CHOCOPTS: --forcex86
47+
48+ # older segfault?
49+
50+cache:
51+- "C:\\SR"
52+
53+install:
54+ - "choco install -y ghc --version %GHCVER% %CHOCOPTS%"
55+ - "choco install -y cabal %CHOCOPTS%"
56+ - "refreshenv"
57+ - "set PATH=C:\\ghc\\ghc-%GHCVER%:C:\\msys64\\mingw64\\bin;C:\\msys64\\usr\\bin;%PATH%"
58+ - "cabal --version"
59+ - "ghc --version"
60+
61+ - set PATH=C:\Progra~1\PostgreSQL\9.6\bin\;%PATH%
62+
63+build: off
64+
65+test_script:
66+ - "cabal %CABOPTS% update -v"
67+ - createdb TestDb
68+ - IF EXIST configure.ac bash -c "autoreconf -i"
69+ - "move cabal.project.local.win cabal.project.local"
70+
71+ - "cabal %CABOPTS% v2-build -j1 libs test"
72+ # - "cabal %CABOPTS% v2-test -j1 all"
73+ - "cabal %CABOPTS% v2-run test"
74+ # - "cabal %CABOPTS% v2-run inspection" # only GHC-8.0 (or GHC-8.2+)
75+
76+ # Build from sdist
77+ - "rmdir /Q /S dist-newstyle"
78+ - "cabal v2-sdist"
79+ - "sh -c 'echo packages: dist-newstyle/sdist/*.tar.gz > cabal.project'"
80+ - "cabal v2-build -j1 postgresql-simple" # TODO: unfortunately the package name have to be here
cabal.project−2
@@ -1,4 +1,2 @@
1packages: .
1packages: .
2tests: true
2tests: true
3−
4−allow-newer: cryptohash-md5-0.11.100.1:base
postgresql-simple.cabal+46−27
@@ -1,7 +1,6 @@
1cabal-version: 1.12
1cabal-version: 1.12
2name: postgresql-simple
2name: postgresql-simple
3−version: 0.7.0.0
3+version: 0.6.4
4−x-revision: 1
5synopsis: Mid-Level PostgreSQL client library
4synopsis: Mid-Level PostgreSQL client library
6description:
5description:
7 Mid-Level PostgreSQL client library, forked from mysql-simple.
6 Mid-Level PostgreSQL client library, forked from mysql-simple.
@@ -24,14 +23,15 @@ extra-source-files:
24 test/results/unique-constraint-violation.expected
23 test/results/unique-constraint-violation.expected
25
24
26tested-with:
25tested-with:
26+ GHC ==7.6.3
27+ || ==7.8.4
28+ || ==7.10.3
29+ || ==8.0.2
30+ || ==8.2.2
31+ || ==8.4.4
27− GHC ==8.6.5
32+ || ==8.6.5
28 || ==8.8.4
33 || ==8.8.4
29− || ==8.10.7
34+ || ==8.10.3
30− || ==9.0.2
31− || ==9.2.8
32− || ==9.4.8
33− || ==9.6.3
34− || ==9.8.1
35
35
36library
36library
37 default-language: Haskell2010
37 default-language: Haskell2010
@@ -77,25 +77,34 @@ library
77
77
78 -- GHC bundled libs
78 -- GHC bundled libs
79 build-depends:
79 build-depends:
80− base >=4.12.0.0 && <4.20
80+ base >=4.6.0.0 && <4.15
81− , bytestring >=0.10.8.2 && <0.13
81+ , bytestring >=0.10.0.0 && <0.12
82− , containers >=0.6.0.1 && <0.7
82+ , containers >=0.5.0.0 && <0.7
83− , template-haskell >=2.14.0.0 && <2.22
83+ , template-haskell >=2.8.0.0 && <2.17
84− , text >=1.2.3.0 && <1.3 || >=2.0 && <2.2
84+ , text >=1.2.3.0 && <1.3
85 , time-compat >=1.9.5 && <1.12
85 , time-compat >=1.9.5 && <1.12
86− , transformers >=0.5.6.2 && <0.7
86+ , transformers >=0.3.0.0 && <0.6
87
87
88 -- Other dependencies
88 -- Other dependencies
89 build-depends:
89 build-depends:
90− aeson >=2.1.2.1 && <2.3
90+ aeson >=1.4.1.0 && <1.6
91− , attoparsec >=0.14.4 && <0.15
91+ , attoparsec >=0.13.2.2 && <0.14
92+ , bytestring-builder >=0.10.8.1.0 && <0.11
92− , case-insensitive >=1.2.1.0 && <1.3
93+ , case-insensitive >=1.2.0.11 && <1.3
93− , hashable >=1.4.3.0 && <1.5
94+ , hashable >=1.2.7.0 && <1.4
94− , Only >=0.1 && <0.1.1
95+ , Only >=0.1 && <0.1.1
95− , postgresql-libpq >=0.10.0.0 && <0.11
96+ , postgresql-libpq >=0.9.4.3 && <0.10
96− , scientific >=0.3.7.0 && <0.4
97+ , scientific >=0.3.6.2 && <0.4
97− , uuid-types >=1.0.5 && <1.1
98+ , uuid-types >=1.0.3 && <1.1
98− , vector >=0.13.0.0 && <0.14
99+ , vector >=0.12.0.1 && <0.13
100+
101+ if !impl(ghc >=8.0)
102+ build-depends:
103+ fail >=4.9.0.0 && <4.10
104+ , semigroups >=0.18.5 && <0.20
105+
106+ if !impl(ghc >=7.6)
107+ build-depends: ghc-prim
99
108
100 default-extensions:
109 default-extensions:
101 BangPatterns
110 BangPatterns
@@ -110,14 +119,22 @@ source-repository head
110 type: git
119 type: git
111 location: http://github.com/haskellari/postgresql-simple
120 location: http://github.com/haskellari/postgresql-simple
112
121
122+source-repository this
123+ type: git
124+ location: http://github.com/haskellari/postgresql-simple
125+ tag: v0.6.3
126+
113test-suite inspection
127test-suite inspection
128+ if !impl(ghc >=8.0)
129+ buildable: False
130+
114 default-language: Haskell2010
131 default-language: Haskell2010
115 type: exitcode-stdio-1.0
132 type: exitcode-stdio-1.0
116 hs-source-dirs: test
133 hs-source-dirs: test
117 main-is: Inspection.hs
134 main-is: Inspection.hs
118 build-depends:
135 build-depends:
119 base
136 base
120− , inspection-testing >=0.4.1.1 && <0.6
137+ , inspection-testing >=0.4.1.1 && <0.5
121 , postgresql-libpq
138 , postgresql-libpq
122 , postgresql-simple
139 , postgresql-simple
123 , tasty
140 , tasty
@@ -130,11 +147,10 @@ test-suite test
130 main-is: Main.hs
147 main-is: Main.hs
131 other-modules:
148 other-modules:
132 Common
149 Common
133− Exception
134− Interval
135 Notify
150 Notify
136 Serializable
151 Serializable
137 Time
152 Time
153+ Interval
138
154
139 ghc-options: -threaded
155 ghc-options: -threaded
140 ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-unused-do-bind
156 ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-unused-do-bind
@@ -164,6 +180,9 @@ test-suite test
164 , time-compat
180 , time-compat
165 , vector
181 , vector
166
182
183+ if !impl(ghc >=7.6)
184+ build-depends: ghc-prim
185+
167benchmark select
186benchmark select
168 default-language: Haskell2010
187 default-language: Haskell2010
169 type: exitcode-stdio-1.0
188 type: exitcode-stdio-1.0
src/Database/PostgreSQL/Simple.hs+1−3
@@ -64,7 +64,6 @@ module Database.PostgreSQL.Simple
64 , Only(..)
64 , Only(..)
65 , (:.)(..)
65 , (:.)(..)
66 -- ** Exceptions
66 -- ** Exceptions
67− , SomePostgreSqlException(..)
68 , SqlError(..)
67 , SqlError(..)
69 , PQ.ExecStatus(..)
68 , PQ.ExecStatus(..)
70 , FormatError(..)
69 , FormatError(..)
@@ -74,7 +73,6 @@ module Database.PostgreSQL.Simple
74 , Base.connectPostgreSQL
73 , Base.connectPostgreSQL
75 , Base.close
74 , Base.close
76 , Base.connect
75 , Base.connect
77− , Base.withConnect
78 , Base.ConnectInfo(..)
76 , Base.ConnectInfo(..)
79 , Base.defaultConnectInfo
77 , Base.defaultConnectInfo
80 , Base.postgreSQLConnectionString
78 , Base.postgreSQLConnectionString
@@ -902,7 +900,7 @@ forEachWith_ parser conn template = foldWith_ parser conn template () . const
902-- all values of the given PostgreSQL type is considered \"compatible\".
900-- all values of the given PostgreSQL type is considered \"compatible\".
903-- For instance, you can always extract a PostgreSQL 16-bit @SMALLINT@
901-- For instance, you can always extract a PostgreSQL 16-bit @SMALLINT@
904-- column to a Haskell 'Int'. The Haskell 'Float' type can accurately
902-- column to a Haskell 'Int'. The Haskell 'Float' type can accurately
905−-- represent a @SMALLINT@, so it is considered compatible with those types.
903+-- represent a @SMALLINT@, so it is considered compatble with those types.
906--
904--
907-- * A numeric compatibility check is based only on the type of a
905-- * A numeric compatibility check is based only on the type of a
908-- column, /not/ on its values. For instance, a PostgreSQL 64-bit
906-- column, /not/ on its values. For instance, a PostgreSQL 64-bit
src/Database/PostgreSQL/Simple/Compat.hs+53
@@ -12,13 +12,36 @@ module Database.PostgreSQL.Simple.Compat
12 ) where
12 ) where
13
13
14import qualified Control.Exception as E
14import qualified Control.Exception as E
15+import Data.Monoid
15import Data.ByteString (ByteString)
16import Data.ByteString (ByteString)
17+#if MIN_VERSION_bytestring(0,10,0)
16import Data.ByteString.Lazy (toStrict)
18import Data.ByteString.Lazy (toStrict)
19+#else
20+import qualified Data.ByteString as B
21+import Data.ByteString.Lazy (toChunks)
22+#endif
17import Data.ByteString.Builder (Builder, toLazyByteString)
23import Data.ByteString.Builder (Builder, toLazyByteString)
24+
25+#if MIN_VERSION_scientific(0,3,0)
18import Data.Text.Lazy.Builder.Scientific (scientificBuilder)
26import Data.Text.Lazy.Builder.Scientific (scientificBuilder)
27+#else
28+import Data.Scientific (scientificBuilder)
29+#endif
30+
31+#if __GLASGOW_HASKELL__ >= 702
19import System.IO.Unsafe (unsafeDupablePerformIO)
32import System.IO.Unsafe (unsafeDupablePerformIO)
33+#elif __GLASGOW_HASKELL__ >= 611
34+import GHC.IO (unsafeDupablePerformIO)
35+#else
36+import GHC.IOBase (unsafeDupablePerformIO)
37+#endif
38+
20import Data.Fixed (Pico)
39import Data.Fixed (Pico)
40+#if MIN_VERSION_base(4,7,0)
21import Data.Fixed (Fixed(MkFixed))
41import Data.Fixed (Fixed(MkFixed))
42+#else
43+import Unsafe.Coerce (unsafeCoerce)
44+#endif
22
45
23-- | Like 'E.mask', but backported to base before version 4.3.0.
46-- | Like 'E.mask', but backported to base before version 4.3.0.
24--
47--
@@ -28,14 +51,44 @@ import Data.Fixed (Fixed(MkFixed))
28-- 'withTransactionMode' function calls the restore callback only once, so we
51-- 'withTransactionMode' function calls the restore callback only once, so we
29-- don't need that polymorphism.
52-- don't need that polymorphism.
30mask :: ((IO a -> IO a) -> IO b) -> IO b
53mask :: ((IO a -> IO a) -> IO b) -> IO b
54+#if MIN_VERSION_base(4,3,0)
31mask io = E.mask $ \restore -> io restore
55mask io = E.mask $ \restore -> io restore
56+#else
57+mask io = do
58+ b <- E.blocked
59+ E.block $ io $ \m -> if b then m else E.unblock m
60+#endif
32{-# INLINE mask #-}
61{-# INLINE mask #-}
33
62
63+#if !MIN_VERSION_base(4,5,0)
64+infixr 6 <>
65+
66+(<>) :: Monoid m => m -> m -> m
67+(<>) = mappend
68+{-# INLINE (<>) #-}
69+#endif
70+
34toByteString :: Builder -> ByteString
71toByteString :: Builder -> ByteString
72+#if MIN_VERSION_bytestring(0,10,0)
35toByteString x = toStrict (toLazyByteString x)
73toByteString x = toStrict (toLazyByteString x)
74+#else
75+toByteString x = B.concat (toChunks (toLazyByteString x))
76+#endif
77+
78+#if MIN_VERSION_base(4,7,0)
36
79
37toPico :: Integer -> Pico
80toPico :: Integer -> Pico
38toPico = MkFixed
81toPico = MkFixed
39
82
40fromPico :: Pico -> Integer
83fromPico :: Pico -> Integer
41fromPico (MkFixed i) = i
84fromPico (MkFixed i) = i
85+
86+#else
87+
88+toPico :: Integer -> Pico
89+toPico = unsafeCoerce
90+
91+fromPico :: Pico -> Integer
92+fromPico = unsafeCoerce
93+
94+#endif
src/Database/PostgreSQL/Simple/Copy.hs+5−1
@@ -55,7 +55,7 @@ import Database.PostgreSQL.Simple.Internal hiding (result, row)
55-- | Issue a @COPY FROM STDIN@ or @COPY TO STDOUT@ query. In the former
55-- | Issue a @COPY FROM STDIN@ or @COPY TO STDOUT@ query. In the former
56-- case, the connection's state will change to @CopyIn@; in the latter,
56-- case, the connection's state will change to @CopyIn@; in the latter,
57-- @CopyOut@. The connection must be in the ready state in order
57-- @CopyOut@. The connection must be in the ready state in order
58−-- to call this function. Performs parameter substitution.
58+-- to call this function. Performs parameter subsitution.
59
59
60copy :: ( ToRow params ) => Connection -> Query -> params -> IO ()
60copy :: ( ToRow params ) => Connection -> Query -> params -> IO ()
61copy conn template qs = do
61copy conn template qs = do
@@ -86,8 +86,12 @@ doCopy funcName conn template q = do
86 PQ.TuplesOk -> err
86 PQ.TuplesOk -> err
87 PQ.CopyOut -> return ()
87 PQ.CopyOut -> return ()
88 PQ.CopyIn -> return ()
88 PQ.CopyIn -> return ()
89+#if MIN_VERSION_postgresql_libpq(0,9,3)
89 PQ.CopyBoth -> errMsg "COPY BOTH is not supported"
90 PQ.CopyBoth -> errMsg "COPY BOTH is not supported"
91+#endif
92+#if MIN_VERSION_postgresql_libpq(0,9,2)
90 PQ.SingleTuple -> errMsg "single-row mode is not supported"
93 PQ.SingleTuple -> errMsg "single-row mode is not supported"
94+#endif
91 PQ.BadResponse -> throwResultError funcName result status
95 PQ.BadResponse -> throwResultError funcName result status
92 PQ.NonfatalError -> throwResultError funcName result status
96 PQ.NonfatalError -> throwResultError funcName result status
93 PQ.FatalError -> throwResultError funcName result status
97 PQ.FatalError -> throwResultError funcName result status
src/Database/PostgreSQL/Simple/Errors.hs+3−4
@@ -25,6 +25,7 @@ module Database.PostgreSQL.Simple.Errors
25 )
25 )
26 where
26 where
27
27
28+import Control.Applicative
28import Control.Exception as E
29import Control.Exception as E
29
30
30import Data.Attoparsec.ByteString.Char8
31import Data.Attoparsec.ByteString.Char8
@@ -59,13 +60,11 @@ data ConstraintViolation
59 deriving (Show, Eq, Ord, Typeable)
60 deriving (Show, Eq, Ord, Typeable)
60
61
61-- Default instance should be enough
62-- Default instance should be enough
62−instance Exception ConstraintViolation where
63+instance Exception ConstraintViolation
63− toException = postgresqlExceptionToException
64− fromException = postgresqlExceptionFromException
65
64
66
65
67-- | Tries to convert 'SqlError' to 'ConstrainViolation', checks sqlState and
66-- | Tries to convert 'SqlError' to 'ConstrainViolation', checks sqlState and
68−-- succeeds only if able to parse sqlErrorMsg.
67+-- succeedes only if able to parse sqlErrorMsg.
69--
68--
70-- > createUser = handleJust constraintViolation handler $ execute conn ...
69-- > createUser = handleJust constraintViolation handler $ execute conn ...
71-- > where
70-- > where
src/Database/PostgreSQL/Simple/FromField.hs+5−7
@@ -118,8 +118,10 @@ module Database.PostgreSQL.Simple.FromField
118
118
119import Control.Applicative ( Const(Const), (<|>), (<$>), pure, (*>), (<*) )
119import Control.Applicative ( Const(Const), (<|>), (<$>), pure, (*>), (<*) )
120import Control.Concurrent.MVar (MVar, newMVar)
120import Control.Concurrent.MVar (MVar, newMVar)
121−import Control.Exception (Exception (toException, fromException))
121+import Control.Exception (Exception)
122import qualified Data.Aeson as JSON
122import qualified Data.Aeson as JSON
123+import qualified Data.Aeson.Internal as JSON
124+import qualified Data.Aeson.Parser as JSON (value')
123import Data.Attoparsec.ByteString.Char8 hiding (Result)
125import Data.Attoparsec.ByteString.Char8 hiding (Result)
124import Data.ByteString (ByteString)
126import Data.ByteString (ByteString)
125import qualified Data.ByteString.Char8 as B
127import qualified Data.ByteString.Char8 as B
@@ -154,8 +156,6 @@ import qualified Data.UUID.Types as UUID
154import Data.Scientific (Scientific)
156import Data.Scientific (Scientific)
155import GHC.Real (infinity, notANumber)
157import GHC.Real (infinity, notANumber)
156
158
157−import qualified Data.Aeson.Types as JSON
158−
159-- | Exception thrown if conversion from a SQL value to a Haskell
159-- | Exception thrown if conversion from a SQL value to a Haskell
160-- value fails.
160-- value fails.
161data ResultError = Incompatible { errSQLType :: String
161data ResultError = Incompatible { errSQLType :: String
@@ -182,9 +182,7 @@ data ResultError = Incompatible { errSQLType :: String
182 -- between metadata and actual data in a row).
182 -- between metadata and actual data in a row).
183 deriving (Eq, Show, Typeable)
183 deriving (Eq, Show, Typeable)
184
184
185−instance Exception ResultError where
185+instance Exception ResultError
186− toException = postgresqlExceptionToException
187− fromException = postgresqlExceptionFromException
188
186
189left :: Exception a => a -> Conversion b
187left :: Exception a => a -> Conversion b
190left = conversionError
188left = conversionError
@@ -576,7 +574,7 @@ instance FromField UUID where
576-- | json, jsonb
574-- | json, jsonb
577instance FromField JSON.Value where
575instance FromField JSON.Value where
578 fromField f mbs = parseBS =<< fromFieldJSONByteString f mbs
576 fromField f mbs = parseBS =<< fromFieldJSONByteString f mbs
579− where parseBS bs = case JSON.eitherDecodeStrict' bs of
577+ where parseBS bs = case parseOnly (JSON.value' <* endOfInput) bs of
580 Left err -> returnError ConversionFailed f err
578 Left err -> returnError ConversionFailed f err
581 Right val -> pure val
579 Right val -> pure val
582
580
src/Database/PostgreSQL/Simple/HStore/Implementation.hs+6
@@ -22,6 +22,9 @@ import Data.ByteString.Builder (Builder, byteString, char8)
22import qualified Data.ByteString.Builder as BU
22import qualified Data.ByteString.Builder as BU
23import Data.ByteString.Internal (c2w, w2c)
23import Data.ByteString.Internal (c2w, w2c)
24import qualified Data.ByteString.Lazy as BL
24import qualified Data.ByteString.Lazy as BL
25+#if !MIN_VERSION_bytestring(0,10,0)
26+import qualified Data.ByteString.Lazy.Internal as BL (foldrChunks)
27+#endif
25import Data.Map(Map)
28import Data.Map(Map)
26import qualified Data.Map as Map
29import qualified Data.Map as Map
27import Data.Text(Text)
30import Data.Text(Text)
@@ -66,6 +69,9 @@ instance Semigroup HStoreBuilder where
66
69
67instance Monoid HStoreBuilder where
70instance Monoid HStoreBuilder where
68 mempty = Empty
71 mempty = Empty
72+#if !(MIN_VERSION_base(4,11,0))
73+ mappend = (<>)
74+#endif
69
75
70class ToHStoreText a where
76class ToHStoreText a where
71 toHStoreText :: a -> HStoreText
77 toHStoreText :: a -> HStoreText
src/Database/PostgreSQL/Simple/Internal.hs+7−37
@@ -1,8 +1,6 @@
1{-# LANGUAGE CPP, BangPatterns, DoAndIfThenElse, RecordWildCards #-}
1{-# LANGUAGE CPP, BangPatterns, DoAndIfThenElse, RecordWildCards #-}
2{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
2{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4−{-# LANGUAGE ExistentialQuantification #-}
5−{-# LANGUAGE InstanceSigs #-}
6
4
7------------------------------------------------------------------------------
5------------------------------------------------------------------------------
8-- |
6-- |
@@ -36,6 +34,7 @@ import Data.Int (Int64)
36import qualified Data.IntMap as IntMap
34import qualified Data.IntMap as IntMap
37import Data.IORef
35import Data.IORef
38import Data.Maybe(fromMaybe)
36import Data.Maybe(fromMaybe)
37+import Data.Monoid
39import Data.String
38import Data.String
40import qualified Data.Text as T
39import qualified Data.Text as T
41import qualified Data.Text.Encoding as TE
40import qualified Data.Text.Encoding as TE
@@ -83,25 +82,6 @@ data Connection = Connection {
83instance Eq Connection where
82instance Eq Connection where
84 x == y = connectionHandle x == connectionHandle y
83 x == y = connectionHandle x == connectionHandle y
85
84
86−-- | Superclass for postgresql exceptions
87−data SomePostgreSqlException = forall e. Exception e => SomePostgreSqlException e
88− deriving Typeable
89−
90−postgresqlExceptionToException :: Exception e => e -> SomeException
91−postgresqlExceptionToException = toException . SomePostgreSqlException
92−
93−postgresqlExceptionFromException :: Exception e => SomeException -> Maybe e
94−postgresqlExceptionFromException x = do
95− SomePostgreSqlException a <- fromException x
96− cast a
97−
98−instance Show SomePostgreSqlException where
99− showsPrec :: Int -> SomePostgreSqlException -> ShowS
100− showsPrec p (SomePostgreSqlException e) = showsPrec p e
101−
102−instance Exception SomePostgreSqlException where
103− displayException (SomePostgreSqlException e) = displayException e
104−
105data SqlError = SqlError {
85data SqlError = SqlError {
106 sqlState :: ByteString
86 sqlState :: ByteString
107 , sqlExecStatus :: ExecStatus
87 , sqlExecStatus :: ExecStatus
@@ -113,10 +93,7 @@ data SqlError = SqlError {
113fatalError :: ByteString -> SqlError
93fatalError :: ByteString -> SqlError
114fatalError msg = SqlError "" FatalError msg "" ""
94fatalError msg = SqlError "" FatalError msg "" ""
115
95
116−instance Exception SqlError where
96+instance Exception SqlError
117− toException = postgresqlExceptionToException
118− fromException = postgresqlExceptionFromException
119−
120
97
121-- | Exception thrown if 'query' is used to perform an @INSERT@-like
98-- | Exception thrown if 'query' is used to perform an @INSERT@-like
122-- operation, or 'execute' is used to perform a @SELECT@-like operation.
99-- operation, or 'execute' is used to perform a @SELECT@-like operation.
@@ -125,9 +102,7 @@ data QueryError = QueryError {
125 , qeQuery :: Query
102 , qeQuery :: Query
126 } deriving (Eq, Show, Typeable)
103 } deriving (Eq, Show, Typeable)
127
104
128−instance Exception QueryError where
105+instance Exception QueryError
129− toException = postgresqlExceptionToException
130− fromException = postgresqlExceptionFromException
131
106
132-- | Exception thrown if a 'Query' could not be formatted correctly.
107-- | Exception thrown if a 'Query' could not be formatted correctly.
133-- This may occur if the number of \'@?@\' characters in the query
108-- This may occur if the number of \'@?@\' characters in the query
@@ -138,9 +113,7 @@ data FormatError = FormatError {
138 , fmtParams :: [ByteString]
113 , fmtParams :: [ByteString]
139 } deriving (Eq, Show, Typeable)
114 } deriving (Eq, Show, Typeable)
140
115
141−instance Exception FormatError where
116+instance Exception FormatError
142− toException = postgresqlExceptionToException
143− fromException = postgresqlExceptionFromException
144
117
145data ConnectInfo = ConnectInfo {
118data ConnectInfo = ConnectInfo {
146 connectHost :: String
119 connectHost :: String
@@ -182,12 +155,6 @@ defaultConnectInfo = ConnectInfo {
182connect :: ConnectInfo -> IO Connection
155connect :: ConnectInfo -> IO Connection
183connect = connectPostgreSQL . postgreSQLConnectionString
156connect = connectPostgreSQL . postgreSQLConnectionString
184
157
185−-- | Memory bracket around 'connect' and 'close'.
186−--
187−-- @since 0.6.5
188−withConnect :: ConnectInfo -> (Connection -> IO c) -> IO c
189−withConnect connInfo = bracket (connect connInfo) close
190−
191-- | Attempt to make a connection based on a libpq connection string.
158-- | Attempt to make a connection based on a libpq connection string.
192-- See <https://www.postgresql.org/docs/9.5/static/libpq-connect.html#LIBPQ-CONNSTRING>
159-- See <https://www.postgresql.org/docs/9.5/static/libpq-connect.html#LIBPQ-CONNSTRING>
193-- for more information. Also note that environment variables also affect
160-- for more information. Also note that environment variables also affect
@@ -517,6 +484,9 @@ instance Alternative Conversion where
517 Errors _ -> (oka <|>) <$> runConversion mb conn
484 Errors _ -> (oka <|>) <$> runConversion mb conn
518
485
519instance Monad Conversion where
486instance Monad Conversion where
487+#if !(MIN_VERSION_base(4,8,0))
488+ return = pure
489+#endif
520 m >>= f = Conversion $ \conn -> do
490 m >>= f = Conversion $ \conn -> do
521 oka <- runConversion m conn
491 oka <- runConversion m conn
522 case oka of
492 case oka of
src/Database/PostgreSQL/Simple/Internal/PQResultUtils.hs+4
@@ -76,8 +76,12 @@ finishQueryWith' q result k = do
76 PQ.CommandOk -> queryErr "query resulted in a command response (did you mean to use `execute` or forget a RETURNING?)"
76 PQ.CommandOk -> queryErr "query resulted in a command response (did you mean to use `execute` or forget a RETURNING?)"
77 PQ.CopyOut -> queryErr "query: COPY TO is not supported"
77 PQ.CopyOut -> queryErr "query: COPY TO is not supported"
78 PQ.CopyIn -> queryErr "query: COPY FROM is not supported"
78 PQ.CopyIn -> queryErr "query: COPY FROM is not supported"
79+#if MIN_VERSION_postgresql_libpq(0,9,3)
79 PQ.CopyBoth -> queryErr "query: COPY BOTH is not supported"
80 PQ.CopyBoth -> queryErr "query: COPY BOTH is not supported"
81+#endif
82+#if MIN_VERSION_postgresql_libpq(0,9,2)
80 PQ.SingleTuple -> queryErr "query: single-row mode is not supported"
83 PQ.SingleTuple -> queryErr "query: single-row mode is not supported"
84+#endif
81 PQ.BadResponse -> throwResultError "query" result status
85 PQ.BadResponse -> throwResultError "query" result status
82 PQ.NonfatalError -> throwResultError "query" result status
86 PQ.NonfatalError -> throwResultError "query" result status
83 PQ.FatalError -> throwResultError "query" result status
87 PQ.FatalError -> throwResultError "query" result status
src/Database/PostgreSQL/Simple/Notification.hs+17
@@ -47,6 +47,8 @@ import GHC.IO.Exception ( ioe_location )
47
47
48#if defined(mingw32_HOST_OS)
48#if defined(mingw32_HOST_OS)
49import Control.Concurrent ( threadDelay )
49import Control.Concurrent ( threadDelay )
50+#elif !MIN_VERSION_base(4,7,0)
51+import Control.Concurrent ( threadWaitRead )
50#else
52#else
51import GHC.Conc ( atomically )
53import GHC.Conc ( atomically )
52import Control.Concurrent ( threadWaitReadSTM )
54import Control.Concurrent ( threadWaitReadSTM )
@@ -92,6 +94,21 @@ getNotification conn = join $ withConnection conn fetch
92 -- with async exceptions, whereas threadDelay can.
94 -- with async exceptions, whereas threadDelay can.
93 Just _fd -> do
95 Just _fd -> do
94 return (threadDelay 1000000 >> loop)
96 return (threadDelay 1000000 >> loop)
97+#elif !MIN_VERSION_base(4,7,0)
98+ -- Technically there's a race condition that is usually benign.
99+ -- If the connection is closed or reset after we drop the
100+ -- lock, and then the fd index is reallocated to a new
101+ -- descriptor before we call threadWaitRead, then
102+ -- we could end up waiting on the wrong descriptor.
103+ --
104+ -- Now, if the descriptor becomes readable promptly, then
105+ -- it's no big deal as we'll wake up and notice the change
106+ -- on the next iteration of the loop. But if are very
107+ -- unlucky, then we could end up waiting a long time.
108+ Just fd -> do
109+ return $ do
110+ threadWaitRead fd `catch` (throwIO . setIOErrorLocation)
111+ loop
95#else
112#else
96 -- This case fixes the race condition above. By registering
113 -- This case fixes the race condition above. By registering
97 -- our interest in the descriptor before we drop the lock,
114 -- our interest in the descriptor before we drop the lock,
src/Database/PostgreSQL/Simple/Ok.hs+4
@@ -72,6 +72,10 @@ instance MonadPlus Ok where
72 mplus = (<|>)
72 mplus = (<|>)
73
73
74instance Monad Ok where
74instance Monad Ok where
75+#if !(MIN_VERSION_base(4,8,0))
76+ return = pure
77+#endif
78+
75 Errors es >>= _ = Errors es
79 Errors es >>= _ = Errors es
76 Ok a >>= f = f a
80 Ok a >>= f = f a
77
81
src/Database/PostgreSQL/Simple/ToField.hs+7−2
@@ -59,7 +59,11 @@ import qualified Data.Vector as V
59import qualified Database.PostgreSQL.LibPQ as PQ
59import qualified Database.PostgreSQL.LibPQ as PQ
60import Database.PostgreSQL.Simple.Time
60import Database.PostgreSQL.Simple.Time
61import Data.Scientific (Scientific)
61import Data.Scientific (Scientific)
62+#if MIN_VERSION_scientific(0,3,0)
62import Data.Text.Lazy.Builder.Scientific (scientificBuilder)
63import Data.Text.Lazy.Builder.Scientific (scientificBuilder)
64+#else
65+import Data.Scientific (scientificBuilder)
66+#endif
63import Foreign.C.Types (CUInt(..))
67import Foreign.C.Types (CUInt(..))
64
68
65-- | How to render an element when substituting it into a query.
69-- | How to render an element when substituting it into a query.
@@ -314,13 +318,14 @@ instance ToField UUID where
314instance ToField JSON.Value where
318instance ToField JSON.Value where
315 toField = toField . JSON.encode
319 toField = toField . JSON.encode
316
320
317−-- | Convert a Haskell value to JSON using 'JSON.toEncoding'.
321+-- | Convert a Haskell value to a JSON 'JSON.Value' using
322+-- 'JSON.toJSON' and convert that to a field using 'toField'.
318--
323--
319-- This can be used as the default implementation for the 'toField'
324-- This can be used as the default implementation for the 'toField'
320-- method for Haskell types that have a JSON representation in
325-- method for Haskell types that have a JSON representation in
321-- PostgreSQL.
326-- PostgreSQL.
322toJSONField :: JSON.ToJSON a => a -> Action
327toJSONField :: JSON.ToJSON a => a -> Action
323−toJSONField = toField . JSON.encode
328+toJSONField = toField . JSON.toJSON
324
329
325-- | Surround a string with single-quote characters: \"@'@\"
330-- | Surround a string with single-quote characters: \"@'@\"
326--
331--
src/Database/PostgreSQL/Simple/Types.hs+7
@@ -50,6 +50,10 @@ import Database.PostgreSQL.Simple.Compat (toByteString)
50data Null = Null
50data Null = Null
51 deriving (Read, Show, Typeable)
51 deriving (Read, Show, Typeable)
52
52
53+instance Eq Null where
54+ _ == _ = False
55+ _ /= _ = False
56+
53-- | A placeholder for the PostgreSQL @DEFAULT@ value.
57-- | A placeholder for the PostgreSQL @DEFAULT@ value.
54data Default = Default
58data Default = Default
55 deriving (Read, Show, Typeable)
59 deriving (Read, Show, Typeable)
@@ -93,6 +97,9 @@ instance Semigroup Query where
93
97
94instance Monoid Query where
98instance Monoid Query where
95 mempty = Query B.empty
99 mempty = Query B.empty
100+#if !(MIN_VERSION_base(4,11,0))
101+ mappend = (<>)
102+#endif
96
103
97-- | Wrap a list of values for use in an @IN@ clause. Replaces a
104-- | Wrap a list of values for use in an @IN@ clause. Replaces a
98-- single \"@?@\" character with a parenthesized list of rendered
105-- single \"@?@\" character with a parenthesized list of rendered
test/Exception.hsdeleted−70
@@ -1,70 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−
5−module Exception (testExceptions) where
6−
7−import Database.PostgreSQL.Simple
8−import Test.Tasty.HUnit (Assertion, assertBool)
9−import Common (TestEnv)
10−import Control.Exception (Exception (..), SomeException)
11−import Data.Maybe (isJust)
12−import Data.Either (isLeft)
13−import Control.Exception (throwIO, try)
14−
15−testExceptions :: TestEnv -> Assertion
16−testExceptions _ = do
17− let sqlError = SqlError
18− { sqlState = ""
19− , sqlExecStatus = FatalError
20− , sqlErrorMsg = ""
21− , sqlErrorDetail = ""
22− , sqlErrorHint = ""
23− }
24− let sqlEx :: SomeException = toException sqlError
25− assertBool "SqlError is SomePostgreSqlException" $ isJust (fromException sqlEx :: Maybe SomePostgreSqlException)
26− assertBool "SqlError is SqlError" $ isJust (fromException sqlEx :: Maybe SqlError)
27− eSqlError :: Either SqlError () <- try $ throwIO sqlEx
28− assertBool "Can catch SqlError" $ isLeft eSqlError
29− eSqlPostgreSqlEx :: Either SomePostgreSqlException () <- try $ throwIO sqlEx
30− assertBool "Can catch SomePostgreSqlException from SqlError" $ isLeft eSqlPostgreSqlEx
31−
32− let formatError = FormatError
33− { fmtMessage = ""
34− , fmtQuery = ""
35− , fmtParams = []
36− }
37− let formatEx :: SomeException = toException formatError
38− assertBool "FormatError is SomePostgreSqlException" $ isJust (fromException formatEx :: Maybe SomePostgreSqlException)
39− assertBool "FormatError is FormatError" $ isJust (fromException formatEx :: Maybe FormatError)
40− eFormatError :: Either FormatError () <- try $ throwIO formatEx
41− assertBool "Can catch FormatError" $ isLeft eFormatError
42− eFormatPostreSqlEx :: Either SomePostgreSqlException () <- try $ throwIO formatEx
43− assertBool "Can catch SomePostgreSqlException from FormatError" $ isLeft eFormatPostreSqlEx
44−
45− let queryError = QueryError
46− { qeMessage = ""
47− , qeQuery = ""
48− }
49− let queryEx :: SomeException = toException queryError
50− assertBool "QueryError is SomePostgreSqlException" $ isJust (fromException queryEx :: Maybe SomePostgreSqlException)
51− assertBool "QueryError is QueryError" $ isJust (fromException queryEx :: Maybe QueryError)
52− eQueryError :: Either QueryError () <- try $ throwIO queryEx
53− assertBool "Can catch QueryError" $ isLeft eQueryError
54− eQueryPostgreSqlEx :: Either SomePostgreSqlException () <- try $ throwIO queryEx
55− assertBool "Can catch SomePostgreSqlException from QueryError" $ isLeft eQueryPostgreSqlEx
56−
57− let resultError = Incompatible
58− { errSQLType = ""
59− , errSQLTableOid = Nothing
60− , errSQLField = ""
61− , errHaskellType = ""
62− , errMessage = ""
63− }
64− let resultEx :: SomeException = toException resultError
65− assertBool "ResultError is SomePostgreSqlException" $ isJust (fromException resultEx :: Maybe SomePostgreSqlException)
66− assertBool "ResultError is ResultError" $ isJust (fromException resultEx :: Maybe ResultError)
67− eResultEx :: Either ResultError () <- try $ throwIO resultEx
68− assertBool "Can catch ResultError" $ isLeft eResultEx
69− eResultPostgreSqlEx :: Either SomePostgreSqlException () <- try $ throwIO resultEx
70− assertBool "Can catch SomePostgreSqlException from ResultError" $ isLeft eResultPostgreSqlEx
test/Main.hs+2−5
@@ -55,7 +55,6 @@ import Notify
55import Serializable
55import Serializable
56import Time
56import Time
57import Interval
57import Interval
58−import Exception (testExceptions)
59
58
60tests :: TestEnv -> TestTree
59tests :: TestEnv -> TestTree
61tests env = testGroup "tests"
60tests env = testGroup "tests"
@@ -85,7 +84,6 @@ tests env = testGroup "tests"
85 , testCase "2-ary generic" . testGeneric2
84 , testCase "2-ary generic" . testGeneric2
86 , testCase "3-ary generic" . testGeneric3
85 , testCase "3-ary generic" . testGeneric3
87 , testCase "Timeout" . testTimeout
86 , testCase "Timeout" . testTimeout
88− , testCase "Exceptions" . testExceptions
89 ]
87 ]
90
88
91testBytea :: TestEnv -> TestTree
89testBytea :: TestEnv -> TestTree
@@ -139,7 +137,7 @@ testFold TestEnv{..} = do
139 xs <- readIORef ref
137 xs <- readIORef ref
140 writeIORef ref $! (a,b):xs
138 writeIORef ref $! (a,b):xs
141 xs <- readIORef ref
139 xs <- readIORef ref
142− reverse xs @?= [(a,b) | b <- [1..50], a <- [1..100]]
140+ reverse xs @?= [(a,b) | a <- [1..100], b <- [1..50]]
143
141
144 -- Make sure fold propagates our exception.
142 -- Make sure fold propagates our exception.
145 ref <- newIORef []
143 ref <- newIORef []
@@ -474,13 +472,12 @@ testCopyFailures env = testGroup "Copy failures"
474
472
475goldenTest :: TestName -> IO BL.ByteString -> TestTree
473goldenTest :: TestName -> IO BL.ByteString -> TestTree
476goldenTest testName =
474goldenTest testName =
477− goldenVsStringDiff testName diff (resultsDir </> fileName<.>"expected")
475+ goldenVsString testName (resultsDir </> fileName<.>"expected")
478 where
476 where
479 resultsDir = "test" </> "results"
477 resultsDir = "test" </> "results"
480 fileName = map normalize testName
478 fileName = map normalize testName
481 normalize c | not (isAlpha c) = '-'
479 normalize c | not (isAlpha c) = '-'
482 | otherwise = c
480 | otherwise = c
483− diff ref new = ["diff", "-u", ref, new]
484
481
485-- | Test that we provide a sensible error message on failure
482-- | Test that we provide a sensible error message on failure
486testCopyUniqueConstraintError :: TestEnv -> TestTree
483testCopyUniqueConstraintError :: TestEnv -> TestTree
test/results/malformed-input.expected+1−1
@@ -1,4 +1,4 @@
1user error (Database.PostgreSQL.Simple.Copy.putCopyEnd: failed to parse command status
1user error (Database.PostgreSQL.Simple.Copy.putCopyEnd: failed to parse command status
2−Connection error: ERROR: invalid input syntax for type integer: "z"
2+Connection error: ERROR: invalid input syntax for integer: "z"
3CONTEXT: COPY copy_unique_constraint_error_test, line 3, column x: "z"
3CONTEXT: COPY copy_unique_constraint_error_test, line 3, column x: "z"
4)
4)