packages feed

postgresql-types-algebra (empty) → 0.0.1

raw patch · 4 files changed

+309/−0 lines, 4 filesdep +attoparsecdep +basedep +bytestring

Dependencies added: attoparsec, base, bytestring, ptr-peeker, ptr-poker, tagged, text, text-builder

Files

+ LICENSE view
@@ -0,0 +1,22 @@+Copyright (c) 2025, 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,61 @@+# postgresql-types-algebra++[![Hackage](https://img.shields.io/hackage/v/postgresql-types-algebra.svg)](https://hackage.haskell.org/package/postgresql-types-algebra)+[![Continuous Haddock](https://img.shields.io/badge/haddock-master-blue)](https://nikita-volkov.github.io/postgresql-types-algebra/)++Core type classes and algebra for PostgreSQL type mappings, extracted from ["postgresql-types"](https://github.com/nikita-volkov/postgresql-types).++## Overview++This package provides the fundamental abstractions for mapping Haskell types to PostgreSQL types:++- **Type classes** defining the algebra for PostgreSQL type mappings+- **Error types** for decoding failures+- **Metadata support** for type names, OIDs, and parameters+- **No concrete implementations** - just the algebra++## Type Classes++### `IsScalar`++The core type class for types that map to PostgreSQL values:++```haskell+class IsScalar a where+  -- Type metadata+  typeName :: Tagged a Text+  baseOid :: Tagged a (Maybe Word32)+  arrayOid :: Tagged a (Maybe Word32)+  typeParams :: Tagged a [Text]+  typeSignature :: Tagged a Text+  +  -- Binary format+  binaryEncoder :: a -> Write.Write+  binaryDecoder :: PtrPeeker.Variable (Either DecodingError a)+  +  -- Textual format+  textualEncoder :: a -> TextBuilder.TextBuilder+  textualDecoder :: Attoparsec.Parser a+```++This class enables:+- **Binary encoding/decoding** using PostgreSQL's native binary format+- **Textual encoding/decoding** using PostgreSQL's text representation  +- **Type metadata** including OIDs and type signatures for parameterized types+- **Round-trip fidelity** through all encoding combinations++## Use Cases++### For Library Authors++Use this package to:+- Define custom PostgreSQL type mappings compatible with the "postgresql-types" ecosystem+- Create adapter libraries for different PostgreSQL client libraries+- Build generic tools that work with any `IsScalar` instance++### For Application Developers++This package is typically used indirectly through:+- ["postgresql-types"](https://github.com/nikita-volkov/postgresql-types) - Concrete type implementations+- ["hasql-postgresql-types"](https://github.com/nikita-volkov/hasql-postgresql-types) - "hasql" integration+- ["postgresql-simple-postgresql-types"](https://github.com/nikita-volkov/postgresql-simple-postgresql-types) - "postgresql-simple" integration
+ postgresql-types-algebra.cabal view
@@ -0,0 +1,109 @@+cabal-version: 3.0+name: postgresql-types-algebra+version: 0.0.1+category: PostgreSQL, Codecs+synopsis: Type classes for PostgreSQL type mappings+description:+  Core type classes and algebra extracted from the postgresql-types library.++  Defines the fundamental abstractions for mapping Haskell types to PostgreSQL types,+  including binary and textual encoding/decoding, type metadata, and error handling.++  This package provides the type class algebra without concrete type implementations,+  making it suitable as a lightweight dependency for libraries that want to define+  their own PostgreSQL type mappings or work with the postgresql-types ecosystem.++homepage: https://github.com/nikita-volkov/postgresql-types-algebra+bug-reports: https://github.com/nikita-volkov/postgresql-types-algebra/issues+author: Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>+copyright: (c) 2025, Nikita Volkov+license: MIT+license-file: LICENSE+extra-doc-files:+  LICENSE+  README.md++source-repository head+  type: git+  location: https://github.com/nikita-volkov/postgresql-types-algebra++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:+    PostgresqlTypes.Algebra++  build-depends:+    attoparsec >=0.14 && <0.19,+    base >=4.11 && <5,+    bytestring >=0.10 && <0.13,+    ptr-peeker ^>=0.1,+    ptr-poker ^>=0.1.2.16,+    tagged ^>=0.8.9,+    text >=1.2 && <3,+    text-builder ^>=1.0.0.4,
+ src/library/PostgresqlTypes/Algebra.hs view
@@ -0,0 +1,117 @@+module PostgresqlTypes.Algebra where++import qualified Data.Attoparsec.Text as Attoparsec+import Data.ByteString (ByteString)+import Data.Tagged (Tagged (..), untag)+import Data.Text (Text)+import Data.Word (Word32)+import qualified PtrPeeker+import qualified PtrPoker.Write as Write+import TextBuilder (TextBuilder)+import qualified TextBuilder+import Prelude++-- | Evidence that a type maps to a PostgreSQL scalar value.+class IsScalar a where+  -- | PostgreSQL schema name, if applicable.+  schemaName :: Tagged a (Maybe Text)++  -- | PostgreSQL type name.+  typeName :: Tagged a Text++  -- | PostgreSQL type OID, if known at compile time.+  baseOid :: Tagged a (Maybe Word32)+  baseOid = Tagged Nothing++  -- | PostgreSQL array type OID, if known at compile time.+  arrayOid :: Tagged a (Maybe Word32)+  arrayOid = Tagged Nothing++  -- | Static type parameters. E.g., the @n@ in @char(n)@.+  typeParams :: Tagged a [Text]+  typeParams = Tagged []++  -- | Get the PostgreSQL type signature for a given Haskell type.+  --+  -- In case of parameterized types, the type parameters are included in the signature.+  -- For example, for @'PostgresqlTypes.Types.Bpchar.Bpchar' 10@, the signature will be @bpchar(10)@.+  typeSignature :: Tagged a Text+  typeSignature =+    let params = untag (typeParams @a)+        name = untag (typeName @a)+     in Tagged+          if null params+            then name+            else+              TextBuilder.toText+                ( mconcat+                    [ TextBuilder.text name,+                      "(",+                      TextBuilder.intercalateMap ", " TextBuilder.text params,+                      ")"+                    ]+                )++  -- | Encode the value in PostgreSQL binary format.+  binaryEncoder :: a -> Write.Write++  -- | Decode the value from PostgreSQL binary format.+  binaryDecoder :: PtrPeeker.Variable (Either DecodingError a)++  -- | Represent the value in PostgreSQL textual format.+  textualEncoder :: a -> TextBuilder.TextBuilder++  -- | Decode the value from PostgreSQL textual format.+  textualDecoder :: Attoparsec.Parser a++-- | Evidence that a type can be used as an element of a PostgreSQL range type.+class (IsScalar a, Ord a) => IsRangeElement a where+  -- | PostgreSQL range type name.+  rangeTypeName :: Tagged a Text++  -- | Statically known OID for the range type.+  rangeBaseOid :: Tagged a (Maybe Word32)++  -- | Statically known OID for the range array-type.+  rangeArrayOid :: Tagged a (Maybe Word32)++-- | Evidence that a type can be used as an element of a PostgreSQL multirange type.+class (IsRangeElement a) => IsMultirangeElement a where+  -- | PostgreSQL multirange type name.+  multirangeTypeName :: Tagged a Text++  -- | Statically known OID for the multirange type.+  multirangeBaseOid :: Tagged a (Maybe Word32)++  -- | Statically known OID for the multirange array-type.+  multirangeArrayOid :: Tagged a (Maybe Word32)++data DecodingError = DecodingError+  { location :: [Text],+    reason :: DecodingErrorReason+  }+  deriving stock (Show, Eq)++data DecodingErrorReason+  = ParsingDecodingErrorReason+      -- | Details.+      Text+      -- | Input.+      ByteString+  | UnexpectedValueDecodingErrorReason+      -- | Expected.+      Text+      -- | Actual.+      Text+  | -- | Unsupported server-side value.+    --+    -- Useful for defining decoders on a narrower type than the underlying PostgreSQL type.+    --+    -- This one does not signal a problem with the data itself, but rather that the data does not meet+    -- the additional constraints imposed by the refinement.+    UnsupportedValueDecodingErrorReason+      -- | Details.+      Text+      -- | Value.+      Text+  deriving stock (Show, Eq)