git.iko.soy/typeable/postgresql-simple
on da248e5 help sign in
20 files changed+298−340
since splitsnapshots
unifiedsplit
.github/workflows/haskell-ci.yml+47−106 .github/workflows/simple.yml−58 CHANGES.md+4−22 appveyor.yml+80 postgresql-simple.cabal+48−26 src/Database/PostgreSQL/Simple.hs+1−3 src/Database/PostgreSQL/Simple/Compat.hs+53 src/Database/PostgreSQL/Simple/Copy.hs+5−1 src/Database/PostgreSQL/Simple/Errors.hs+3−4 src/Database/PostgreSQL/Simple/FromField.hs+5−7 src/Database/PostgreSQL/Simple/HStore/Implementation.hs+6 src/Database/PostgreSQL/Simple/Internal.hs+7−37 src/Database/PostgreSQL/Simple/Internal/PQResultUtils.hs+4 src/Database/PostgreSQL/Simple/Notification.hs+17 src/Database/PostgreSQL/Simple/Ok.hs+4 src/Database/PostgreSQL/Simple/ToField.hs+4 src/Database/PostgreSQL/Simple/Types.hs+7 test/Exception.hs−70 test/Main.hs+2−5 test/results/malformed-input.expected+1−1
.github/workflows/haskell-ci.yml+47−106
@@ -8,9 +8,9 @@
88#
99# For more information, see https://github.com/haskell-CI/haskell-ci
1010#
11−# version: 0.17.20231110
11+# version: 0.12
1212#
13−# REGENDATA ("0.17.20231110",["github","cabal.project"])
13+# REGENDATA ("0.12",["github","cabal.project"])
1414#
1515name: Haskell-CI
1616on:
@@ -23,14 +23,12 @@ on:
2323jobs:
2424 linux:
2525 name: Haskell-CI - Linux - ${{ matrix.compiler }}
26− runs-on: ubuntu-20.04
27− timeout-minutes:
28− 60
26+ runs-on: ubuntu-18.04
2927 container:
3028 image: buildpack-deps:bionic
3129 services:
3230 postgres:
33− image: postgres:14
31+ image: postgres:10
3432 env:
3533 POSTGRES_PASSWORD: postgres
3634 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
@@ -38,105 +36,59 @@ jobs:
3836 strategy:
3937 matrix:
4038 include:
41− - compiler: ghc-9.8.1
42− compilerKind: ghc
43− compilerVersion: 9.8.1
44− setup-method: ghcup
39+ - compiler: ghc-9.0.1
4540 allow-failure: false
46− - compiler: ghc-9.6.3
47− compilerKind: ghc
48− compilerVersion: 9.6.3
49− setup-method: ghcup
41+ - compiler: ghc-8.10.4
5042 allow-failure: false
51− - compiler: ghc-9.4.8
52− compilerKind: ghc
53− compilerVersion: 9.4.8
54− setup-method: ghcup
43+ - compiler: ghc-8.8.4
5544 allow-failure: false
56− - compiler: ghc-9.2.8
57− compilerKind: ghc
58− compilerVersion: 9.2.8
59− setup-method: ghcup
45+ - compiler: ghc-8.6.5
6046 allow-failure: false
61− - compiler: ghc-9.0.2
62− compilerKind: ghc
63− compilerVersion: 9.0.2
64− setup-method: ghcup
47+ - compiler: ghc-8.4.4
6548 allow-failure: false
66− - compiler: ghc-8.10.7
67− compilerKind: ghc
68− compilerVersion: 8.10.7
69− setup-method: ghcup
49+ - compiler: ghc-8.2.2
7050 allow-failure: false
71− - compiler: ghc-8.8.4
72− compilerKind: ghc
73− compilerVersion: 8.8.4
74− setup-method: hvr-ppa
51+ - compiler: ghc-8.0.2
7552 allow-failure: false
76− - compiler: ghc-8.6.5
77− compilerKind: ghc
78− compilerVersion: 8.6.5
79− setup-method: hvr-ppa
53+ - compiler: ghc-7.10.3
54+ allow-failure: false
55+ - compiler: ghc-7.8.4
56+ allow-failure: false
57+ - compiler: ghc-7.6.3
8058 allow-failure: false
8159 fail-fast: false
8260 steps:
8361 - name: apt
8462 run: |
8563 apt-get update
86− apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
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'
95− apt-get update
96− apt-get install -y "$HCNAME"
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
64+ apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common
65+ apt-add-repository -y 'ppa:hvr/ghc'
66+ apt-get update
67+ apt-get install -y $CC cabal-install-3.4
10268 env:
103− HCKIND: ${{ matrix.compilerKind }}
104− HCNAME: ${{ matrix.compiler }}
105− HCVER: ${{ matrix.compilerVersion }}
69+ CC: ${{ matrix.compiler }}
10670 - name: Set PATH and environment variables
10771 run: |
10872 echo "$HOME/.cabal/bin" >> $GITHUB_PATH
109− echo "LANG=C.UTF-8" >> "$GITHUB_ENV"
110− echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"
111− echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
112− HCDIR=/opt/$HCKIND/$HCVER
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"
118− echo "HCPKG=$HCPKG" >> "$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"
126− echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
127− fi
128−
73+ echo "LANG=C.UTF-8" >> $GITHUB_ENV
74+ echo "CABAL_DIR=$HOME/.cabal" >> $GITHUB_ENV
75+ echo "CABAL_CONFIG=$HOME/.cabal/config" >> $GITHUB_ENV
76+ HCDIR=$(echo "/opt/$CC" | sed 's/-/\//')
77+ HCNAME=ghc
78+ HC=$HCDIR/bin/$HCNAME
79+ echo "HC=$HC" >> $GITHUB_ENV
80+ echo "HCPKG=$HCDIR/bin/$HCNAME-pkg" >> $GITHUB_ENV
81+ echo "HADDOCK=$HCDIR/bin/haddock" >> $GITHUB_ENV
82+ echo "CABAL=/opt/cabal/3.4/bin/cabal -vnormal+nowrap" >> $GITHUB_ENV
12983 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"
131− echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"
132− echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"
133− echo "HEADHACKAGE=false" >> "$GITHUB_ENV"
134− echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"
135− echo "GHCJSARITH=0" >> "$GITHUB_ENV"
84+ echo "HCNUMVER=$HCNUMVER" >> $GITHUB_ENV
85+ echo "ARG_TESTS=--enable-tests" >> $GITHUB_ENV
86+ echo "ARG_BENCH=--enable-benchmarks" >> $GITHUB_ENV
87+ echo "HEADHACKAGE=false" >> $GITHUB_ENV
88+ echo "ARG_COMPILER=--$HCNAME --with-compiler=$HC" >> $GITHUB_ENV
89+ echo "GHCJSARITH=0" >> $GITHUB_ENV
13690 env:
137− HCKIND: ${{ matrix.compilerKind }}
138− HCNAME: ${{ matrix.compiler }}
139− HCVER: ${{ matrix.compilerVersion }}
91+ CC: ${{ matrix.compiler }}
14092 - name: env
14193 run: |
14294 env
@@ -159,10 +111,6 @@ jobs:
159111 repository hackage.haskell.org
160112 url: http://hackage.haskell.org/
161113 EOF
162− cat >> $CABAL_CONFIG <<EOF
163− program-default-options
164− ghc-options: $GHCJOBS +RTS -M3G -RTS
165− EOF
166114 cat $CABAL_CONFIG
167115 - name: versions
168116 run: |
@@ -175,14 +123,14 @@ jobs:
175123 - name: install cabal-plan
176124 run: |
177125 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
179− echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c -
126+ 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
127+ echo 'de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz' | sha256sum -c -
180128 xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan
181129 rm -f cabal-plan.xz
182130 chmod a+x $HOME/.cabal/bin/cabal-plan
183131 cabal-plan --version
184132 - name: checkout
185− uses: actions/checkout@v3
133+ uses: actions/checkout@v2
186134 with:
187135 path: source
188136 - name: initial cabal.project for sdist
@@ -201,13 +149,12 @@ jobs:
201149 - name: generate cabal.project
202150 run: |
203151 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"
205− rm -f cabal.project cabal.project.local
152+ echo "PKGDIR_postgresql_simple=${PKGDIR_postgresql_simple}" >> $GITHUB_ENV
206153 touch cabal.project
207154 touch cabal.project.local
208155 echo "packages: ${PKGDIR_postgresql_simple}" >> cabal.project
209− echo "package postgresql-simple" >> cabal.project
210− echo " ghc-options: -Werror=missing-methods" >> cabal.project
156+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package postgresql-simple" >> cabal.project ; fi
157+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi
211158 cat >> cabal.project <<EOF
212159 allow-newer: cryptohash-md5-0.11.100.1:base
213160 EOF
@@ -218,8 +165,8 @@ jobs:
218165 run: |
219166 $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all
220167 cabal-plan
221− - name: restore cache
222− uses: actions/cache/restore@v3
168+ - name: cache
169+ uses: actions/cache@v2
223170 with:
224171 key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
225172 path: ~/.cabal/store
@@ -243,14 +190,8 @@ jobs:
243190 ${CABAL} -vnormal check
244191 - name: haddock
245192 run: |
246− $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
193+ $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
247194 - name: unconstrained build
248195 run: |
249196 rm -f cabal.project.local
250197 $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−
191### Version 0.6.4 (2021-01-06)
202
213 * Add foldCopyData helper function
@@ -271,7 +253,7 @@
271253 support UTF8 except for Mule Internal Code, the Multilingual
272254 Extensions for Emacs. An exception should be raised upon
273255 connecting to a database by the backend if the backend cannot
274− accommodate this requirement.
256+ accomodate this requirement.
275257
276258 * Added `Eq` and `Typeable` instances for `Connection`.
277259
@@ -409,7 +391,7 @@
409391
410392 * Changed the Identifier and QualifiedIdentifier to use Text in
411393 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.
413395
414396 * Removed non-exhaustive cases in the ToField instance for Values,
415397 and tweaked error messages.
@@ -569,7 +551,7 @@
569551
570552 * Added a brand new TypeInfo system that gives FromField instances
571553 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
573555 support postgres array types. Thanks to Bas van Dijk for his
574556 work on this feature.
575557
@@ -661,7 +643,7 @@
661643 now the preferred way of dealing with `timestamp` (without time zone).
662644
663645 * `Database.PostgreSQL.Simple.Time` is a new module that offers types
664− that accommodate PostgreSQL's infinities.
646+ that accomodate PostgreSQL's infinities.
665647
666648 * All time-related `FromField`/`ToField` instances are now based on new,
667649 higher-speed parsers and printers instead of those provided by the
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
postgresql-simple.cabal+48−26
@@ -1,7 +1,7 @@
11cabal-version: 1.12
22name: postgresql-simple
3−version: 0.7.0.0
4−x-revision: 1
3+version: 0.6.4
4+x-revision: 6
55synopsis: Mid-Level PostgreSQL client library
66description:
77 Mid-Level PostgreSQL client library, forked from mysql-simple.
@@ -24,14 +24,17 @@ extra-source-files:
2424 test/results/unique-constraint-violation.expected
2525
2626tested-with:
27− GHC ==8.6.5
27+ GHC ==7.6.3
28+ || ==7.8.4
29+ || ==7.10.3
30+ || ==8.0.2
31+ || ==8.2.2
32+ || ==8.4.4
33+ || ==8.6.5
2834 || ==8.8.4
2935 || ==8.10.7
30− || ==9.0.2
31− || ==9.2.8
32− || ==9.4.8
33− || ==9.6.3
34− || ==9.8.1
36+ || ==9.0.1
37+ || ==9.2.1
3538
3639library
3740 default-language: Haskell2010
@@ -77,25 +80,34 @@ library
7780
7881 -- GHC bundled libs
7982 build-depends:
80− base >=4.12.0.0 && <4.20
81− , bytestring >=0.10.8.2 && <0.13
82− , containers >=0.6.0.1 && <0.7
83− , template-haskell >=2.14.0.0 && <2.22
84− , text >=1.2.3.0 && <1.3 || >=2.0 && <2.2
83+ base >=4.6.0.0 && <4.17
84+ , bytestring >=0.10.0.0 && <0.12
85+ , containers >=0.5.0.0 && <0.7
86+ , template-haskell >=2.8.0.0 && <2.19
87+ , text >=1.2.3.0 && <1.3 || >=2.0 && <2.1
8588 , time-compat >=1.9.5 && <1.12
86− , transformers >=0.5.6.2 && <0.7
89+ , transformers >=0.3.0.0 && <0.7
8790
8891 -- Other dependencies
8992 build-depends:
90− aeson >=2.1.2.1 && <2.3
91− , attoparsec >=0.14.4 && <0.15
92− , case-insensitive >=1.2.1.0 && <1.3
93− , hashable >=1.4.3.0 && <1.5
94− , Only >=0.1 && <0.1.1
95− , postgresql-libpq >=0.10.0.0 && <0.11
96− , scientific >=0.3.7.0 && <0.4
97− , uuid-types >=1.0.5 && <1.1
98− , vector >=0.13.0.0 && <0.14
93+ aeson >=1.4.1.0 && <1.6 || >=2.0.0.0 && <2.1
94+ , attoparsec >=0.13.2.2 && <0.15
95+ , bytestring-builder >=0.10.8.1.0 && <0.11
96+ , case-insensitive >=1.2.0.11 && <1.3
97+ , hashable >=1.2.7.0 && <1.5
98+ , Only >=0.1 && <0.1.1
99+ , postgresql-libpq >=0.9.4.3 && <0.10
100+ , scientific >=0.3.6.2 && <0.4
101+ , uuid-types >=1.0.3 && <1.1
102+ , vector >=0.12.0.1 && <0.13
103+
104+ if !impl(ghc >=8.0)
105+ build-depends:
106+ fail >=4.9.0.0 && <4.10
107+ , semigroups >=0.18.5 && <0.21
108+
109+ if !impl(ghc >=7.6)
110+ build-depends: ghc-prim
99111
100112 default-extensions:
101113 BangPatterns
@@ -110,14 +122,22 @@ source-repository head
110122 type: git
111123 location: http://github.com/haskellari/postgresql-simple
112124
125+source-repository this
126+ type: git
127+ location: http://github.com/haskellari/postgresql-simple
128+ tag: v0.6.3
129+
113130test-suite inspection
131+ if !impl(ghc >=8.0)
132+ buildable: False
133+
114134 default-language: Haskell2010
115135 type: exitcode-stdio-1.0
116136 hs-source-dirs: test
117137 main-is: Inspection.hs
118138 build-depends:
119139 base
120− , inspection-testing >=0.4.1.1 && <0.6
140+ , inspection-testing >=0.4.1.1 && <0.5
121141 , postgresql-libpq
122142 , postgresql-simple
123143 , tasty
@@ -130,11 +150,10 @@ test-suite test
130150 main-is: Main.hs
131151 other-modules:
132152 Common
133− Exception
134− Interval
135153 Notify
136154 Serializable
137155 Time
156+ Interval
138157
139158 ghc-options: -threaded
140159 ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-unused-do-bind
@@ -164,6 +183,9 @@ test-suite test
164183 , time-compat
165184 , vector
166185
186+ if !impl(ghc >=7.6)
187+ build-depends: ghc-prim
188+
167189benchmark select
168190 default-language: Haskell2010
169191 type: exitcode-stdio-1.0
src/Database/PostgreSQL/Simple.hs+1−3
@@ -64,7 +64,6 @@ module Database.PostgreSQL.Simple
6464 , Only(..)
6565 , (:.)(..)
6666 -- ** Exceptions
67− , SomePostgreSqlException(..)
6867 , SqlError(..)
6968 , PQ.ExecStatus(..)
7069 , FormatError(..)
@@ -74,7 +73,6 @@ module Database.PostgreSQL.Simple
7473 , Base.connectPostgreSQL
7574 , Base.close
7675 , Base.connect
77− , Base.withConnect
7876 , Base.ConnectInfo(..)
7977 , Base.defaultConnectInfo
8078 , Base.postgreSQLConnectionString
@@ -902,7 +900,7 @@ forEachWith_ parser conn template = foldWith_ parser conn template () . const
902900-- all values of the given PostgreSQL type is considered \"compatible\".
903901-- For instance, you can always extract a PostgreSQL 16-bit @SMALLINT@
904902-- 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.
906904--
907905-- * A numeric compatibility check is based only on the type of a
908906-- 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
1212 ) where
1313
1414import qualified Control.Exception as E
15+import Data.Monoid
1516import Data.ByteString (ByteString)
17+#if MIN_VERSION_bytestring(0,10,0)
1618import Data.ByteString.Lazy (toStrict)
19+#else
20+import qualified Data.ByteString as B
21+import Data.ByteString.Lazy (toChunks)
22+#endif
1723import Data.ByteString.Builder (Builder, toLazyByteString)
24+
25+#if MIN_VERSION_scientific(0,3,0)
1826import Data.Text.Lazy.Builder.Scientific (scientificBuilder)
27+#else
28+import Data.Scientific (scientificBuilder)
29+#endif
30+
31+#if __GLASGOW_HASKELL__ >= 702
1932import System.IO.Unsafe (unsafeDupablePerformIO)
33+#elif __GLASGOW_HASKELL__ >= 611
34+import GHC.IO (unsafeDupablePerformIO)
35+#else
36+import GHC.IOBase (unsafeDupablePerformIO)
37+#endif
38+
2039import Data.Fixed (Pico)
40+#if MIN_VERSION_base(4,7,0)
2141import Data.Fixed (Fixed(MkFixed))
42+#else
43+import Unsafe.Coerce (unsafeCoerce)
44+#endif
2245
2346-- | Like 'E.mask', but backported to base before version 4.3.0.
2447--
@@ -28,14 +51,44 @@ import Data.Fixed (Fixed(MkFixed))
2851-- 'withTransactionMode' function calls the restore callback only once, so we
2952-- don't need that polymorphism.
3053mask :: ((IO a -> IO a) -> IO b) -> IO b
54+#if MIN_VERSION_base(4,3,0)
3155mask 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
3261{-# INLINE mask #-}
3362
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+
3471toByteString :: Builder -> ByteString
72+#if MIN_VERSION_bytestring(0,10,0)
3573toByteString 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)
3679
3780toPico :: Integer -> Pico
3881toPico = MkFixed
3982
4083fromPico :: Pico -> Integer
4184fromPico (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)
5555-- | Issue a @COPY FROM STDIN@ or @COPY TO STDOUT@ query. In the former
5656-- case, the connection's state will change to @CopyIn@; in the latter,
5757-- @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.
5959
6060copy :: ( ToRow params ) => Connection -> Query -> params -> IO ()
6161copy conn template qs = do
@@ -86,8 +86,12 @@ doCopy funcName conn template q = do
8686 PQ.TuplesOk -> err
8787 PQ.CopyOut -> return ()
8888 PQ.CopyIn -> return ()
89+#if MIN_VERSION_postgresql_libpq(0,9,3)
8990 PQ.CopyBoth -> errMsg "COPY BOTH is not supported"
91+#endif
92+#if MIN_VERSION_postgresql_libpq(0,9,2)
9093 PQ.SingleTuple -> errMsg "single-row mode is not supported"
94+#endif
9195 PQ.BadResponse -> throwResultError funcName result status
9296 PQ.NonfatalError -> throwResultError funcName result status
9397 PQ.FatalError -> throwResultError funcName result status
src/Database/PostgreSQL/Simple/Errors.hs+3−4
@@ -25,6 +25,7 @@ module Database.PostgreSQL.Simple.Errors
2525 )
2626 where
2727
28+import Control.Applicative
2829import Control.Exception as E
2930
3031import Data.Attoparsec.ByteString.Char8
@@ -59,13 +60,11 @@ data ConstraintViolation
5960 deriving (Show, Eq, Ord, Typeable)
6061
6162-- Default instance should be enough
62−instance Exception ConstraintViolation where
63− toException = postgresqlExceptionToException
64− fromException = postgresqlExceptionFromException
63+instance Exception ConstraintViolation
6564
6665
6766-- | 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.
6968--
7069-- > createUser = handleJust constraintViolation handler $ execute conn ...
7170-- > where
src/Database/PostgreSQL/Simple/FromField.hs+5−7
@@ -118,8 +118,10 @@ module Database.PostgreSQL.Simple.FromField
118118
119119import Control.Applicative ( Const(Const), (<|>), (<$>), pure, (*>), (<*) )
120120import Control.Concurrent.MVar (MVar, newMVar)
121−import Control.Exception (Exception (toException, fromException))
121+import Control.Exception (Exception)
122122import qualified Data.Aeson as JSON
123+import qualified Data.Aeson.Internal as JSON
124+import qualified Data.Aeson.Parser as JSON (value')
123125import Data.Attoparsec.ByteString.Char8 hiding (Result)
124126import Data.ByteString (ByteString)
125127import qualified Data.ByteString.Char8 as B
@@ -154,8 +156,6 @@ import qualified Data.UUID.Types as UUID
154156import Data.Scientific (Scientific)
155157import GHC.Real (infinity, notANumber)
156158
157−import qualified Data.Aeson.Types as JSON
158−
159159-- | Exception thrown if conversion from a SQL value to a Haskell
160160-- value fails.
161161data ResultError = Incompatible { errSQLType :: String
@@ -182,9 +182,7 @@ data ResultError = Incompatible { errSQLType :: String
182182 -- between metadata and actual data in a row).
183183 deriving (Eq, Show, Typeable)
184184
185−instance Exception ResultError where
186− toException = postgresqlExceptionToException
187− fromException = postgresqlExceptionFromException
185+instance Exception ResultError
188186
189187left :: Exception a => a -> Conversion b
190188left = conversionError
@@ -576,7 +574,7 @@ instance FromField UUID where
576574-- | json, jsonb
577575instance FromField JSON.Value where
578576 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
580578 Left err -> returnError ConversionFailed f err
581579 Right val -> pure val
582580
src/Database/PostgreSQL/Simple/HStore/Implementation.hs+6
@@ -22,6 +22,9 @@ import Data.ByteString.Builder (Builder, byteString, char8)
2222import qualified Data.ByteString.Builder as BU
2323import Data.ByteString.Internal (c2w, w2c)
2424import 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
2528import Data.Map(Map)
2629import qualified Data.Map as Map
2730import Data.Text(Text)
@@ -66,6 +69,9 @@ instance Semigroup HStoreBuilder where
6669
6770instance Monoid HStoreBuilder where
6871 mempty = Empty
72+#if !(MIN_VERSION_base(4,11,0))
73+ mappend = (<>)
74+#endif
6975
7076class ToHStoreText a where
7177 toHStoreText :: a -> HStoreText
src/Database/PostgreSQL/Simple/Internal.hs+7−37
@@ -1,8 +1,6 @@
11{-# LANGUAGE CPP, BangPatterns, DoAndIfThenElse, RecordWildCards #-}
22{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
33{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4−{-# LANGUAGE ExistentialQuantification #-}
5−{-# LANGUAGE InstanceSigs #-}
64
75------------------------------------------------------------------------------
86-- |
@@ -36,6 +34,7 @@ import Data.Int (Int64)
3634import qualified Data.IntMap as IntMap
3735import Data.IORef
3836import Data.Maybe(fromMaybe)
37+import Data.Monoid
3938import Data.String
4039import qualified Data.Text as T
4140import qualified Data.Text.Encoding as TE
@@ -83,25 +82,6 @@ data Connection = Connection {
8382instance Eq Connection where
8483 x == y = connectionHandle x == connectionHandle y
8584
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−
10585data SqlError = SqlError {
10686 sqlState :: ByteString
10787 , sqlExecStatus :: ExecStatus
@@ -113,10 +93,7 @@ data SqlError = SqlError {
11393fatalError :: ByteString -> SqlError
11494fatalError msg = SqlError "" FatalError msg "" ""
11595
116−instance Exception SqlError where
117− toException = postgresqlExceptionToException
118− fromException = postgresqlExceptionFromException
119−
96+instance Exception SqlError
12097
12198-- | Exception thrown if 'query' is used to perform an @INSERT@-like
12299-- operation, or 'execute' is used to perform a @SELECT@-like operation.
@@ -125,9 +102,7 @@ data QueryError = QueryError {
125102 , qeQuery :: Query
126103 } deriving (Eq, Show, Typeable)
127104
128−instance Exception QueryError where
129− toException = postgresqlExceptionToException
130− fromException = postgresqlExceptionFromException
105+instance Exception QueryError
131106
132107-- | Exception thrown if a 'Query' could not be formatted correctly.
133108-- This may occur if the number of \'@?@\' characters in the query
@@ -138,9 +113,7 @@ data FormatError = FormatError {
138113 , fmtParams :: [ByteString]
139114 } deriving (Eq, Show, Typeable)
140115
141−instance Exception FormatError where
142− toException = postgresqlExceptionToException
143− fromException = postgresqlExceptionFromException
116+instance Exception FormatError
144117
145118data ConnectInfo = ConnectInfo {
146119 connectHost :: String
@@ -182,12 +155,6 @@ defaultConnectInfo = ConnectInfo {
182155connect :: ConnectInfo -> IO Connection
183156connect = connectPostgreSQL . postgreSQLConnectionString
184157
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−
191158-- | Attempt to make a connection based on a libpq connection string.
192159-- See <https://www.postgresql.org/docs/9.5/static/libpq-connect.html#LIBPQ-CONNSTRING>
193160-- for more information. Also note that environment variables also affect
@@ -517,6 +484,9 @@ instance Alternative Conversion where
517484 Errors _ -> (oka <|>) <$> runConversion mb conn
518485
519486instance Monad Conversion where
487+#if !(MIN_VERSION_base(4,8,0))
488+ return = pure
489+#endif
520490 m >>= f = Conversion $ \conn -> do
521491 oka <- runConversion m conn
522492 case oka of
src/Database/PostgreSQL/Simple/Internal/PQResultUtils.hs+4
@@ -76,8 +76,12 @@ finishQueryWith' q result k = do
7676 PQ.CommandOk -> queryErr "query resulted in a command response (did you mean to use `execute` or forget a RETURNING?)"
7777 PQ.CopyOut -> queryErr "query: COPY TO is not supported"
7878 PQ.CopyIn -> queryErr "query: COPY FROM is not supported"
79+#if MIN_VERSION_postgresql_libpq(0,9,3)
7980 PQ.CopyBoth -> queryErr "query: COPY BOTH is not supported"
81+#endif
82+#if MIN_VERSION_postgresql_libpq(0,9,2)
8083 PQ.SingleTuple -> queryErr "query: single-row mode is not supported"
84+#endif
8185 PQ.BadResponse -> throwResultError "query" result status
8286 PQ.NonfatalError -> throwResultError "query" result status
8387 PQ.FatalError -> throwResultError "query" result status
src/Database/PostgreSQL/Simple/Notification.hs+17
@@ -47,6 +47,8 @@ import GHC.IO.Exception ( ioe_location )
4747
4848#if defined(mingw32_HOST_OS)
4949import Control.Concurrent ( threadDelay )
50+#elif !MIN_VERSION_base(4,7,0)
51+import Control.Concurrent ( threadWaitRead )
5052#else
5153import GHC.Conc ( atomically )
5254import Control.Concurrent ( threadWaitReadSTM )
@@ -92,6 +94,21 @@ getNotification conn = join $ withConnection conn fetch
9294 -- with async exceptions, whereas threadDelay can.
9395 Just _fd -> do
9496 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
95112#else
96113 -- This case fixes the race condition above. By registering
97114 -- 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
7272 mplus = (<|>)
7373
7474instance Monad Ok where
75+#if !(MIN_VERSION_base(4,8,0))
76+ return = pure
77+#endif
78+
7579 Errors es >>= _ = Errors es
7680 Ok a >>= f = f a
7781
src/Database/PostgreSQL/Simple/ToField.hs+4
@@ -59,7 +59,11 @@ import qualified Data.Vector as V
5959import qualified Database.PostgreSQL.LibPQ as PQ
6060import Database.PostgreSQL.Simple.Time
6161import Data.Scientific (Scientific)
62+#if MIN_VERSION_scientific(0,3,0)
6263import Data.Text.Lazy.Builder.Scientific (scientificBuilder)
64+#else
65+import Data.Scientific (scientificBuilder)
66+#endif
6367import Foreign.C.Types (CUInt(..))
6468
6569-- | How to render an element when substituting it into a query.
src/Database/PostgreSQL/Simple/Types.hs+7
@@ -50,6 +50,10 @@ import Database.PostgreSQL.Simple.Compat (toByteString)
5050data Null = Null
5151 deriving (Read, Show, Typeable)
5252
53+instance Eq Null where
54+ _ == _ = False
55+ _ /= _ = False
56+
5357-- | A placeholder for the PostgreSQL @DEFAULT@ value.
5458data Default = Default
5559 deriving (Read, Show, Typeable)
@@ -93,6 +97,9 @@ instance Semigroup Query where
9397
9498instance Monoid Query where
9599 mempty = Query B.empty
100+#if !(MIN_VERSION_base(4,11,0))
101+ mappend = (<>)
102+#endif
96103
97104-- | Wrap a list of values for use in an @IN@ clause. Replaces a
98105-- 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
5555import Serializable
5656import Time
5757import Interval
58−import Exception (testExceptions)
5958
6059tests :: TestEnv -> TestTree
6160tests env = testGroup "tests"
@@ -85,7 +84,6 @@ tests env = testGroup "tests"
8584 , testCase "2-ary generic" . testGeneric2
8685 , testCase "3-ary generic" . testGeneric3
8786 , testCase "Timeout" . testTimeout
88− , testCase "Exceptions" . testExceptions
8987 ]
9088
9189testBytea :: TestEnv -> TestTree
@@ -139,7 +137,7 @@ testFold TestEnv{..} = do
139137 xs <- readIORef ref
140138 writeIORef ref $! (a,b):xs
141139 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]]
143141
144142 -- Make sure fold propagates our exception.
145143 ref <- newIORef []
@@ -474,13 +472,12 @@ testCopyFailures env = testGroup "Copy failures"
474472
475473goldenTest :: TestName -> IO BL.ByteString -> TestTree
476474goldenTest testName =
477− goldenVsStringDiff testName diff (resultsDir </> fileName<.>"expected")
475+ goldenVsString testName (resultsDir </> fileName<.>"expected")
478476 where
479477 resultsDir = "test" </> "results"
480478 fileName = map normalize testName
481479 normalize c | not (isAlpha c) = '-'
482480 | otherwise = c
483− diff ref new = ["diff", "-u", ref, new]
484481
485482-- | Test that we provide a sensible error message on failure
486483testCopyUniqueConstraintError :: TestEnv -> TestTree
test/results/malformed-input.expected+1−1
@@ -1,4 +1,4 @@
11user 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"
33CONTEXT: COPY copy_unique_constraint_error_test, line 3, column x: "z"
44)