packages feed

hasql-mapping (empty) → 0.1

raw patch · 6 files changed

+270/−0 lines, 6 filesdep +aesondep +basedep +bytestring

Dependencies added: aeson, base, bytestring, hasql, iproute, scientific, text, time, uuid

Files

+ 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,8 @@+# hasql-mapping++[![Hackage](https://img.shields.io/hackage/v/hasql-mapping.svg)](https://hackage.haskell.org/package/hasql-mapping)+[![Continuous Haddock](https://img.shields.io/badge/haddock-master-blue)](https://nikita-volkov.github.io/hasql-mapping/)++SDK for defining mappings between Haskell and PostgreSQL.++The central piece of this library is the `IsStatement` typeclass, which is used for declaring type-safe mappings to particular SQL statements.
+ hasql-mapping.cabal view
@@ -0,0 +1,64 @@+cabal-version: 3.0+name: hasql-mapping+version: 0.1+synopsis: SDK for defining modular mappings to databases on top of Hasql+description:+  SDK for defining mappings to databases using Hasql that promotes modular design.++  It avoids exporting abstractions unrelated to mapping, ensuring more stable versioning.++homepage: https://github.com/nikita-volkov/hasql-mapping+bug-reports: https://github.com/nikita-volkov/hasql-mapping/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-mapping++common base+  default-language: Haskell2010+  default-extensions:+    ApplicativeDo+    BlockArguments+    DefaultSignatures+    DeriveFunctor+    DerivingStrategies+    DerivingVia+    DuplicateRecordFields+    FlexibleContexts+    FlexibleInstances+    FunctionalDependencies+    GeneralizedNewtypeDeriving+    LambdaCase+    MultiParamTypeClasses+    NoImplicitPrelude+    OverloadedStrings+    ScopedTypeVariables+    TypeApplications+    TypeFamilies++library+  import: base+  hs-source-dirs: src/library+  exposed-modules:+    Hasql.Mapping+    Hasql.Mapping.IsScalar+    Hasql.Mapping.IsStatement++  build-depends:+    aeson >=2.0 && <3,+    base >=4.12 && <5,+    bytestring >=0.10 && <0.13,+    hasql ^>=1.10.1,+    iproute >=1.7 && <2,+    scientific >=0.3 && <0.4,+    text >=1.2 && <3,+    time >=1.9 && <2,+    uuid >=1.3 && <2,
+ src/library/Hasql/Mapping.hs view
@@ -0,0 +1,11 @@+-- | Reexports of classes without methods.+--+-- To access the methods import the class-specific modules preferably qualified.+module Hasql.Mapping+  ( IsScalar,+    IsStatement,+  )+where++import Hasql.Mapping.IsScalar (IsScalar)+import Hasql.Mapping.IsStatement (IsStatement)
+ src/library/Hasql/Mapping/IsScalar.hs view
@@ -0,0 +1,110 @@+module Hasql.Mapping.IsScalar where++import qualified Data.Aeson as Aeson+import Data.ByteString (ByteString)+import Data.Functor.Contravariant ((>$<))+import Data.IP (IPRange)+import Data.Int (Int16, Int32, Int64)+import Data.Scientific (Scientific)+import Data.Text (Text)+import Data.Time (Day, DiffTime, LocalTime, TimeOfDay, TimeZone, UTCTime)+import Data.UUID (UUID)+import Data.Word (Word8)+import qualified Hasql.Decoders as Decoders+import qualified Hasql.Encoders as Encoders+import Prelude++-- | Mapping to a scalar value. Anything but array.+--+-- The current Hasql API doesn't provide a typesafe boundary to enforce the value being scalar,+-- so consider this to be a part of the contract to not define instances for array mappings using this class.+class IsScalar a where+  encoder :: Encoders.Value a+  decoder :: Decoders.Value a++-- Numeric types+instance IsScalar Bool where+  encoder = Encoders.bool+  decoder = Decoders.bool++instance IsScalar Int16 where+  encoder = Encoders.int2+  decoder = Decoders.int2++instance IsScalar Int32 where+  encoder = Encoders.int4+  decoder = Decoders.int4++instance IsScalar Int64 where+  encoder = Encoders.int8+  decoder = Decoders.int8++instance IsScalar Int where+  encoder = fromIntegral >$< Encoders.int8+  decoder = fromIntegral <$> Decoders.int8++instance IsScalar Float where+  encoder = Encoders.float4+  decoder = Decoders.float4++instance IsScalar Double where+  encoder = Encoders.float8+  decoder = Decoders.float8++instance IsScalar Scientific where+  encoder = Encoders.numeric+  decoder = Decoders.numeric++-- Text types+instance IsScalar Text where+  encoder = Encoders.text+  decoder = Decoders.text++-- Binary types+instance IsScalar ByteString where+  encoder = Encoders.bytea+  decoder = Decoders.bytea++-- Date/Time types+instance IsScalar Day where+  encoder = Encoders.date+  decoder = Decoders.date++instance IsScalar LocalTime where+  encoder = Encoders.timestamp+  decoder = Decoders.timestamp++instance IsScalar UTCTime where+  encoder = Encoders.timestamptz+  decoder = Decoders.timestamptz++instance IsScalar TimeOfDay where+  encoder = Encoders.time+  decoder = Decoders.time++instance IsScalar (TimeOfDay, TimeZone) where+  encoder = Encoders.timetz+  decoder = Decoders.timetz++instance IsScalar DiffTime where+  encoder = Encoders.interval+  decoder = Decoders.interval++-- UUID+instance IsScalar UUID where+  encoder = Encoders.uuid+  decoder = Decoders.uuid++-- Network types+instance IsScalar IPRange where+  encoder = Encoders.inet+  decoder = Decoders.inet++instance IsScalar (Word8, Word8, Word8, Word8, Word8, Word8) where+  encoder = Encoders.macaddr+  decoder = Decoders.macaddr++-- JSON types+instance IsScalar Aeson.Value where+  encoder = Encoders.jsonb+  decoder = Decoders.jsonb
+ src/library/Hasql/Mapping/IsStatement.hs view
@@ -0,0 +1,55 @@+module Hasql.Mapping.IsStatement where++import qualified Hasql.Statement as Statement++-- |+-- Evidence that a data-structure models statement parameters determining the statement and its result type.+--+-- Supports a modularisation pattern, where you define everything related to one statement in an isolated module.+-- This pattern leads to high code cohesion and low coupling.+--+-- ==== __Example of such a module__+--+-- > module MusicCatalogueDb.Statements.SelectArtistIdsByName where+-- >+-- > import Data.Functor.Contravariant+-- > import Data.Text (Text)+-- > import Data.UUID (UUID)+-- > import Data.Vector (Vector)+-- > import qualified Hasql.Decoders as Decoders+-- > import qualified Hasql.Encoders as Encoders+-- > import Hasql.Mapping.IsStatement+-- > import Prelude+-- >+-- > data SelectArtistIdsByName = SelectArtistIdsByName+-- >   { name :: Text+-- >   }+-- >+-- > type SelectArtistIdsByNameResult = Vector SelectArtistIdsByNameResultRow+-- >+-- > data SelectArtistIdsByNameResultRow = SelectArtistIdsByNameResultRow+-- >   { id :: UUID+-- >   }+-- >+-- > instance IsStatement SelectArtistIdsByName where+-- >   type Result SelectArtistIdsByName = SelectArtistIdsByNameResult+-- >   statement =+-- >     Statement.preparable sql encoder decoder+-- >     where+-- >       sql =+-- >         "select id from artist\n\+-- >         \where name = $1\n\+-- >         \limit 1"+-- >       encoder =+-- >         mconcat+-- >           [ (\(SelectArtistIdsByName x) -> x)+-- >               >$< Encoders.param (Encoders.nonNullable Encoders.text)+-- >           ]+-- >       decoder =+-- >         Decoders.rowVector+-- >           ( SelectArtistIdsByNameResultRow+-- >               <$> Decoders.column (Decoders.nonNullable Decoders.uuid)+-- >           )+class IsStatement a where+  type Result a+  statement :: Statement.Statement a (Result a)