hasql-postgresql-types (empty) → 0.1
raw patch · 4 files changed
+216/−0 lines, 4 filesdep +basedep +hasqldep +postgresql-types-algebra
Dependencies added: base, hasql, postgresql-types-algebra, ptr-peeker, ptr-poker, tagged, text-builder
Files
- LICENSE +22/−0
- README.md +24/−0
- hasql-postgresql-types.cabal +102/−0
- src/library/Hasql/PostgresqlTypes.hs +68/−0
+ LICENSE view
@@ -0,0 +1,22 @@+Copyright (c) 2026, Nikita Volkov++Permission is hereby granted, free of charge, to any person+obtaining a copy of this software and associated documentation+files (the "Software"), to deal in the Software without+restriction, including without limitation the rights to use,+copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the+Software is furnished to do so, subject to the following+conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,24 @@+# hasql-postgresql-types++[](https://hackage.haskell.org/package/hasql-postgresql-types)+[](https://nikita-volkov.github.io/hasql-postgresql-types/)++Integration of ["hasql"](https://github.com/nikita-volkov/hasql) with ["postgresql-types"](https://github.com/nikita-volkov/postgresql-types) via the `IsScalar` typeclass from ["postgresql-types-algebra"](https://github.com/nikita-volkov/postgresql-types-algebra).+Provides automatic encoder and decoder generation for precise PostgreSQL scalar types.++## Usage++```haskell+import Hasql.PostgresqlTypes (encoder, decoder)+import qualified PostgresqlTypes as Pt+import qualified Hasql.Statement as Statement+import qualified Hasql.Encoders as Encoders+import qualified Hasql.Decoders as Decoders++myStatement :: Statement.Statement Pt.Timestamptz [Pt.Timestamptz]+myStatement = Statement.preparable sql enc dec+ where+ sql = "SELECT $1::timestamptz"+ enc = Encoders.param (Encoders.nonNullable encoder)+ dec = Decoders.rowList (Decoders.column (Decoders.nonNullable decoder))+```
+ hasql-postgresql-types.cabal view
@@ -0,0 +1,102 @@+cabal-version: 3.0+name: hasql-postgresql-types+version: 0.1+category: PostgreSQL, Codecs, Hasql+synopsis: Integration of "hasql" with "postgresql-types"+description:+ Provides automatic encoder and decoder generation for ["hasql"](https://hackage.haskell.org/package/hasql),+ supporting all PostgreSQL standard types defined in the ["postgresql-types"](https://hackage.haskell.org/package/postgresql-types) package.++homepage: https://github.com/nikita-volkov/hasql-postgresql-types+bug-reports: https://github.com/nikita-volkov/hasql-postgresql-types/issues+author: Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>+copyright: (c) 2026, Nikita Volkov+license: MIT+license-file: LICENSE+extra-doc-files:+ LICENSE+ README.md++source-repository head+ type: git+ location: https://github.com/nikita-volkov/hasql-postgresql-types++common base+ default-language: Haskell2010+ default-extensions:+ ApplicativeDo+ BangPatterns+ BinaryLiterals+ BlockArguments+ ConstraintKinds+ DataKinds+ DefaultSignatures+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveTraversable+ DerivingStrategies+ DerivingVia+ DuplicateRecordFields+ EmptyDataDecls+ FlexibleContexts+ FlexibleInstances+ FunctionalDependencies+ GADTs+ GeneralizedNewtypeDeriving+ LambdaCase+ LiberalTypeSynonyms+ MagicHash+ MultiParamTypeClasses+ MultiWayIf+ NamedFieldPuns+ NoImplicitPrelude+ NoMonomorphismRestriction+ NumericUnderscores+ OverloadedStrings+ ParallelListComp+ PatternGuards+ QuasiQuotes+ RankNTypes+ RecordWildCards+ ScopedTypeVariables+ StandaloneDeriving+ StrictData+ TemplateHaskell+ TupleSections+ TypeApplications+ TypeFamilies+ TypeOperators+ UnboxedTuples+ ViewPatterns++common executable+ import: base+ ghc-options:+ -O2+ -threaded+ -with-rtsopts=-N+ -rtsopts+ -funbox-strict-fields++common test+ import: base+ ghc-options:+ -threaded+ -with-rtsopts=-N++library+ import: base+ hs-source-dirs: src/library+ exposed-modules:+ Hasql.PostgresqlTypes++ build-depends:+ base >=4.11 && <5,+ hasql ^>=1.10.1,+ postgresql-types-algebra ^>=0.1,+ ptr-peeker ^>=0.1.0.1,+ ptr-poker ^>=0.1.3,+ tagged ^>=0.8.9,+ text-builder ^>=1.0.0.4,
+ src/library/Hasql/PostgresqlTypes.hs view
@@ -0,0 +1,68 @@+-- |+-- This module provides a bridge between the types defined in the ["postgresql-types"](https://hackage.haskell.org/package/postgresql-types) and the ["hasql"](https://hackage.haskell.org/package/hasql) library,+-- offering automatic encoder and decoder generation for types that implement the 'IsScalar' constraint.+--+-- == Usage Example+--+-- > import Hasql.PostgresqlTypes (encoder, decoder)+-- > import qualified PostgresqlTypes as Pt+-- > import qualified Hasql.Statement as Statement+-- > import qualified Hasql.Encoders as Encoders+-- > import qualified Hasql.Decoders as Decoders+-- >+-- > myStatement :: Statement.Statement Pt.Timestamptz [Pt.Timestamptz]+-- > myStatement = Statement.preparable sql enc dec+-- > where+-- > sql = "SELECT $1::timestamptz"+-- > enc = Encoders.param (Encoders.nonNullable encoder)+-- > dec = Decoders.rowList (Decoders.column (Decoders.nonNullable decoder))+--+-- The 'encoder' and 'decoder' functions work with any type having an 'IsScalar' instance,+-- automatically handling binary encoding/decoding and OID resolution.+module Hasql.PostgresqlTypes+ ( encoder,+ decoder,+ )+where++import Data.String (fromString)+import Data.Tagged (untag)+import qualified Hasql.Decoders as Decoders+import qualified Hasql.Encoders as Encoders+import PostgresqlTypes.Algebra (IsScalar (..))+import qualified PtrPeeker+import qualified PtrPoker.Write as Write+import qualified TextBuilder+import Prelude++-- | Hasql value encoder for a PostgreSQL standard type.+--+-- Generates a Hasql value encoder for any type implementing 'IsScalar'.+-- The encoder handles type resolution, and binary encoding automatically.+encoder :: forall a. (IsScalar a) => Encoders.Value a+encoder =+ Encoders.custom+ Nothing+ (untag (typeName @a))+ ((,) <$> untag (baseOid @a) <*> untag (arrayOid @a))+ []+ (\_ value -> Write.toByteString (binaryEncoder value))+ (TextBuilder.toText . textualEncoder)++-- | Hasql value decoder for a PostgreSQL standard type.+--+-- Generates a Hasql value decoder for any type implementing 'IsScalar'.+-- The decoder handles type resolution, and binary decoding with proper error handling.+decoder :: forall a. (IsScalar a) => Decoders.Value a+decoder =+ Decoders.custom+ Nothing+ (untag (typeName @a))+ ((,) <$> untag (baseOid @a) <*> untag (arrayOid @a))+ []+ ( \_ bytes ->+ case PtrPeeker.runVariableOnByteString binaryDecoder bytes of+ Left bytesUnconsumed -> Left ("Binary decoder did not consume all input bytes, unconsumed bytes: " <> fromString (show bytesUnconsumed))+ Right (Left err) -> Left (fromString (show err))+ Right (Right value) -> Right value+ )