hasql 2.0.0.1 → 2.0.0.2
raw patch · 7 files changed
+198/−23 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- README.md +26/−6
- hasql.cabal +27/−8
- src/library-tests/Integration/Sharing/SpecHook.hs +4/−5
- src/library/Hasql/Connection.hs +20/−0
- src/library/Hasql/Decoders.hs +57/−3
- src/library/Hasql/Encoders.hs +60/−1
CHANGELOG.md view
@@ -1,3 +1,7 @@+# v2.0.0.2++Work around the bugs in Cabal/Haddock that cause missing documentation for two-hop reexported internal modules.+ # v2.0.0.1 Support for `pqi-1.1`.
README.md view
@@ -6,19 +6,27 @@ PostgreSQL driver for Haskell, that prioritizes: - Performance-- Typesafety+- Reliability - Flexibility # Status Hasql is production-ready, actively maintained and the API is moderately stable. It's used by many companies and most notably by the [Postgrest](https://github.com/PostgREST/postgrest) project. -# A New Era: Pluggable Transport+# Pluggable Transport -Hasql's transport is now pluggable via [`pqi`](https://github.com/nikita-volkov/pqi). `Hasql.Connection.acquire` takes an adapter explicitly:+Hasql's transport is pluggable via [`pqi`](https://github.com/nikita-volkov/pqi). Hasql itself carries no C dependency. It programs against the `pqi` interface, and you pick the adapter that implements it. That means you depend on two packages, not one: +```cabal+build-depends:+ hasql,+ pqi-ffi, -- or pqi-native+```++`Hasql.Connection.acquire` then takes the adapter explicitly, as its first argument:+ ```haskell-import Pqi.Ffi qualified -- the existing C-backed libpq transport+import Pqi.Ffi qualified -- the C-backed libpq transport import Pqi.Native qualified -- alpha: pure-Haskell, no C dependency, interchangeable with Pqi.Ffi connection <- Hasql.Connection.acquire Pqi.Ffi.adapter settings@@ -26,8 +34,10 @@ connection <- Hasql.Connection.acquire Pqi.Native.adapter settings ``` -[`pqi-native`](https://github.com/nikita-volkov/pqi-native) is the goal of this new era: a from-scratch, pure-Haskell implementation of the Postgres wire protocol, verified byte-for-byte against `libpq` via [`pqi-conformance`](https://github.com/nikita-volkov/pqi-conformance). **It's alpha** - not yet proven at production scale - while [`pqi-ffi`](https://github.com/nikita-volkov/pqi-ffi) remains the stable, production-proven default. The two adapters are fully interchangeable: swapping between them is a one-line change (a different `Adapter` value, nothing else), so early adopters can try `pqi-native` today with no lock-in and no rewrite to fall back if needed. Feedback welcome on [GitHub Discussions](https://github.com/nikita-volkov/hasql/discussions).+[`pqi-ffi`](https://github.com/nikita-volkov/pqi-ffi) is the stable, production-proven default. It binds the C `libpq` library, so it requires `libpq` of at least version 14 to be installed to compile - which typically just means having a recent PostgreSQL distro installed. Through it Hasql is tested against a wide range of PostgreSQL servers, starting from version 9. +[`pqi-native`](https://github.com/nikita-volkov/pqi-native) is a from-scratch, pure-Haskell implementation of the Postgres wire protocol, with no C dependency at all. It is thoroughly tested: [`pqi-conformance`](https://github.com/nikita-volkov/pqi-conformance) runs it side by side with `libpq` on the same inputs and checks that the results agree, and the test-suites of `hasql`, [`hasql-pool`](https://github.com/nikita-volkov/hasql-pool) and [`hasql-transaction`](https://github.com/nikita-volkov/hasql-transaction) now run against both adapters, so the whole stack above the transport is exercised on `pqi-native` too. **It's still labelled alpha** - not yet proven at production scale. The two adapters are fully interchangeable: swapping between them is a one-line change (a different `Adapter` value, nothing else), so you can try `pqi-native` today with no lock-in and no rewrite to fall back if needed.+ # Ecosystem Hasql is not just a single library, it is a granular ecosystem of composable libraries, each isolated to perform its own task and stay simple.@@ -60,6 +70,16 @@ <sup>Want to list your package or correct something here? Make a PR.</sup> +## Transport adapters++Unlike the extension libraries above, which are optional, a transport adapter is mandatory: Hasql needs one to talk to the server at all. See [Pluggable Transport](#pluggable-transport) for how to pick one.++- ["pqi"](https://github.com/nikita-volkov/pqi) - the driver-agnostic interface that Hasql programs against. Pulled in automatically. You don't depend on it directly.++- ["pqi-ffi"](https://github.com/nikita-volkov/pqi-ffi) - the stable adapter, backed by the C `libpq` library.++- ["pqi-native"](https://github.com/nikita-volkov/pqi-native) - an alpha pure-Haskell adapter speaking the PostgreSQL wire protocol directly, with no C dependency.+ ## Why make it an ecosystem? - **Focus.**@@ -107,7 +127,7 @@ import qualified Hasql.Encoders as Encoders import qualified Hasql.Session as Session import qualified Hasql.Statement as Statement-import qualified Pqi.Ffi -- from "pqi-ffi" (stable); swap for "Pqi.Native" from "pqi-native" (alpha, fully interchangeable) to try the pure-Haskell backend+import qualified Pqi.Ffi -- from "pqi-ffi" (stable). Swap for "Pqi.Native" from "pqi-native" (alpha, fully interchangeable) to try the pure-Haskell backend main :: IO () main = do
hasql.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: hasql-version: 2.0.0.1+version: 2.0.0.2 category: Hasql, Database, PostgreSQL synopsis: Fast PostgreSQL driver with a flexible mapping API description:@@ -9,15 +9,34 @@ Extended functionality such as pooling, transactions and compile-time checking of SQL is provided by extension libraries. For more details and tutorials see <https://github.com/nikita-volkov/hasql the readme>. - The API comes free from all kinds of exceptions.- All error-reporting is explicit and is presented using the 'Either' type.+ All error-reporting is explicit:+ database, protocol and connection failures are reported via the 'Either' type+ instead of being thrown as exceptions. - \"hasql\" requires you to have the \"libpq\" C-library of at least version 14 installed to compile.- \"libpq\" comes distributed with PostgreSQL,- so typically all you need is just to install the latest PostgreSQL distro.+ The transport layer is pluggable via <https://hackage.haskell.org/package/pqi pqi>,+ so \"hasql\" itself carries no C dependency.+ To compile an application you need to depend on \"hasql\" together with one adapter package+ and pass that adapter to @Hasql.Connection.acquire@ as its first argument.+ Two adapters are available: - Despite the mentioned requirements for \"libpq\" \"hasql\" is thoroughly tested to be compatible- with a wide range of PostgreSQL servers starting from version 9.+ * <https://hackage.haskell.org/package/pqi-ffi pqi-ffi> -+ the stable, production-proven adapter, backed by the C \"libpq\" library.+ It requires \"libpq\" of at least version 14 to be installed to compile.+ \"libpq\" comes distributed with PostgreSQL,+ so typically all you need is just to install the latest PostgreSQL distro.+ Via this adapter \"hasql\" is thoroughly tested to be compatible+ with a wide range of PostgreSQL servers starting from version 9.++ * <https://hackage.haskell.org/package/pqi-native pqi-native> -+ a pure-Haskell adapter, which speaks the PostgreSQL wire protocol directly+ and thus requires no C dependency at all.+ It is thoroughly tested:+ <https://github.com/nikita-volkov/pqi-conformance pqi-conformance> runs it+ side by side with \"libpq\" on the same inputs and checks that the results agree,+ and the test-suites of \"hasql\", \"hasql-pool\" and \"hasql-transaction\"+ run against both adapters.+ It is still labelled __alpha__, but is fully interchangeable with \"pqi-ffi\":+ switching between the two is a one-line change. homepage: https://github.com/nikita-volkov/hasql bug-reports: https://github.com/nikita-volkov/hasql/issues
src/library-tests/Integration/Sharing/SpecHook.hs view
@@ -10,10 +10,9 @@ type HookedSpec = SpecWith Scripts.ScopeParams hook :: HookedSpec -> SpecWith Pqi.Adapter-hook hookedSpec =- parallel do- byDistro "postgres:9"- byDistro "postgres:18"+hook hookedSpec = do+ byDistro "postgres:9"+ byDistro "postgres:18" where byDistro tagName = describe (toList tagName)@@ -27,4 +26,4 @@ } (\(host, port) -> action (adapter, host, port)) )- hookedSpec+ (parallel hookedSpec)
src/library/Hasql/Connection.hs view
@@ -28,6 +28,26 @@ -- | -- Establish a connection according to the provided settings.+--+-- The first argument is a 'Pqi.Adapter', which defines the backend+-- implementation used to talk to PostgreSQL (for example, libpq via the+-- <https://hackage.haskell.org/package/pqi-ffi pqi-ffi> package, or a pure+-- Haskell implementation via the+-- <https://hackage.haskell.org/package/pqi-native pqi-native> package).+--+-- This is the only place in the library where users choose the adapter.+--+-- Typical usage is to pass the application's default adapter.+--+-- This function:+--+-- - Opens a PostgreSQL connection using the constructed connection string.+-- - Validates that the connection is healthy.+-- - Checks the server version for compatibility.+-- - Initializes session-level settings (encoding and message verbosity).+--+-- On success, returns a 'Connection' wrapped in 'Right'.+-- On failure, returns a classified 'ConnectionError' in 'Left'. acquire :: Adapter -> Settings.Settings ->
src/library/Hasql/Decoders.hs view
@@ -86,6 +86,60 @@ ) where -import Hasql.Codecs.Decoders-import Hasql.Engine.Decoders.Result-import Hasql.Engine.Decoders.Row+-- Every identifier below is imported directly from the module it's+-- actually declared in, rather than from an intermediate re-export+-- module. Haddock has a bug where docs of an identifier re-exported+-- through more than one hop (declaration site -> intermediate re-export+-- -> here) silently render blank on Hackage; importing straight from the+-- declaration site keeps this a single hop.+import Hasql.Codecs.Decoders (array, composite, listArray, record, vectorArray)+import Hasql.Codecs.Decoders.Array (Array, dimension, element)+import Hasql.Codecs.Decoders.Composite (Composite, field)+import Hasql.Codecs.Decoders.NullableOrNot (NullableOrNot, nonNullable, nullable)+import Hasql.Codecs.Decoders.Value+ ( Value,+ bool,+ bpchar,+ bytea,+ char,+ citext,+ custom,+ date,+ datemultirange,+ daterange,+ enum,+ float4,+ float8,+ hstore,+ inet,+ int2,+ int4,+ int4multirange,+ int4range,+ int8,+ int8multirange,+ int8range,+ interval,+ json,+ jsonBytes,+ jsonb,+ jsonbBytes,+ macaddr,+ numeric,+ nummultirange,+ numrange,+ refine,+ text,+ time,+ timestamp,+ timestamptz,+ timetz,+ tsmultirange,+ tsrange,+ tstzmultirange,+ tstzrange,+ uuid,+ varchar,+ )+import Hasql.Engine.Decoders.Result (Result, foldlRows, foldrRows, noResult, rowList, rowMaybe, rowVector, rowsAffected, singleRow)+import Hasql.Engine.Decoders.Row (Row, column)
src/library/Hasql/Encoders.hs view
@@ -77,4 +77,63 @@ ) where -import Hasql.Codecs.Encoders+-- Every identifier below is imported directly from the module it's+-- actually declared in, rather than from "Hasql.Codecs.Encoders" (which+-- merely re-exports them). Haddock has a bug where docs of an identifier+-- re-exported through more than one hop (declaration site -> intermediate+-- re-export -> here) silently render blank on Hackage; importing straight+-- from the declaration site keeps this a single hop.+import Hasql.Codecs.Encoders (array, composite, foldableArray)+import Hasql.Codecs.Encoders.Array (Array, dimension, element)+import Hasql.Codecs.Encoders.Composite (Composite, field)+import Hasql.Codecs.Encoders.NullableOrNot (NullableOrNot, nonNullable, nullable)+import Hasql.Codecs.Encoders.Params (Params, noParams, param)+import Hasql.Codecs.Encoders.Value+ ( Value,+ bool,+ bpchar,+ bytea,+ char,+ citext,+ custom,+ date,+ datemultirange,+ daterange,+ enum,+ float4,+ float8,+ hstore,+ inet,+ int2,+ int4,+ int4multirange,+ int4range,+ int8,+ int8multirange,+ int8range,+ interval,+ json,+ jsonBytes,+ jsonLazyBytes,+ jsonb,+ jsonbBytes,+ jsonbLazyBytes,+ macaddr,+ name,+ numeric,+ nummultirange,+ numrange,+ oid,+ text,+ time,+ timestamp,+ timestamptz,+ timetz,+ tsmultirange,+ tsrange,+ tstzmultirange,+ tstzrange,+ unknown,+ uuid,+ varchar,+ )