Skip to content

Commit

Permalink
Format
Browse files Browse the repository at this point in the history
  • Loading branch information
nikita-volkov authored and github-actions[bot] committed Jan 21, 2024
1 parent cff779f commit dd62238
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 215 deletions.
130 changes: 95 additions & 35 deletions hasql-dynamic-statements.cabal
Original file line number Diff line number Diff line change
@@ -1,57 +1,117 @@
name: hasql-dynamic-statements
version: 0.3.1.2
synopsis: Toolkit for constructing Hasql statements dynamically
name: hasql-dynamic-statements
version: 0.3.1.2
synopsis: Toolkit for constructing Hasql statements dynamically
description:
This library introduces into the Hasql ecosystem a new abstraction named Snippet,
which makes it trivial to construct SQL, while injecting values.
It is intended to be used when the SQL of your statement depends on the parameters,
that you want to pass in.
homepage: https://github.com/nikita-volkov/hasql-dynamic-statements
bug-reports: https://github.com/nikita-volkov/hasql-dynamic-statements/issues
author: Nikita Volkov <nikita.y.volkov@mail.ru>
maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>
copyright: (c) 2019, Nikita Volkov
license: MIT
license-file: LICENSE
build-type: Simple

homepage: https://github.com/nikita-volkov/hasql-dynamic-statements
bug-reports:
https://github.com/nikita-volkov/hasql-dynamic-statements/issues

author: Nikita Volkov <nikita.y.volkov@mail.ru>
maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>
copyright: (c) 2019, Nikita Volkov
license: MIT
license-file: LICENSE
build-type: Simple
cabal-version: >=1.10

source-repository head
type: git
type: git
location: git://github.com/nikita-volkov/hasql-dynamic-statements.git

library
hs-source-dirs: library
default-extensions: BangPatterns, DeriveDataTypeable, DeriveGeneric, DeriveFunctor, DeriveTraversable, GeneralizedNewtypeDeriving, FlexibleContexts, FlexibleInstances, LambdaCase, NoImplicitPrelude, OverloadedStrings, RankNTypes, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeFamilies
ghc-options: -funbox-strict-fields
default-language: Haskell2010
hs-source-dirs: library
default-extensions:
NoImplicitPrelude
BangPatterns
DeriveDataTypeable
DeriveFunctor
DeriveGeneric
DeriveTraversable
FlexibleContexts
FlexibleInstances
GeneralizedNewtypeDeriving
LambdaCase
OverloadedStrings
RankNTypes
ScopedTypeVariables
StandaloneDeriving
TypeApplications
TypeFamilies

ghc-options: -funbox-strict-fields
default-language: Haskell2010
exposed-modules:
Hasql.DynamicStatements.Session
Hasql.DynamicStatements.Snippet
Hasql.DynamicStatements.Statement

other-modules:
Hasql.DynamicStatements.Prelude
Hasql.DynamicStatements.Snippet.Defs

build-depends:
base >=4.12 && <5,
bytestring >=0.10 && <0.13,
containers >=0.6 && <0.7,
hasql >=1.6 && <1.7,
hasql-implicits >=0.1 && <0.2,
ptr >=0.16.7.2 && <0.17
base >=4.12 && <5
, bytestring >=0.10 && <0.13
, containers >=0.6 && <0.7
, hasql >=1.6 && <1.7
, hasql-implicits >=0.1 && <0.2
, ptr >=0.16.7.2 && <0.17

test-suite test
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Main.hs
default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeApplications, TypeFamilies, TypeOperators, UnboxedTuples
default-language: Haskell2010
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Main.hs
default-extensions:
NoImplicitPrelude
NoMonomorphismRestriction
Arrows
BangPatterns
ConstraintKinds
DataKinds
DefaultSignatures
DeriveDataTypeable
DeriveFoldable
DeriveFunctor
DeriveGeneric
DeriveTraversable
EmptyDataDecls
FlexibleContexts
FlexibleInstances
FunctionalDependencies
GADTs
GeneralizedNewtypeDeriving
LambdaCase
LiberalTypeSynonyms
MagicHash
MultiParamTypeClasses
MultiWayIf
OverloadedStrings
ParallelListComp
PatternGuards
QuasiQuotes
RankNTypes
RecordWildCards
ScopedTypeVariables
StandaloneDeriving
TemplateHaskell
TupleSections
TypeApplications
TypeFamilies
TypeOperators
UnboxedTuples

default-language: Haskell2010
build-depends:
hasql,
hasql-dynamic-statements,
QuickCheck >=2.8.1 && <3,
quickcheck-instances >=0.3.11 && <0.4,
rerebase <2,
tasty >=0.12 && <2,
tasty-hunit >=0.9 && <0.11,
tasty-quickcheck >=0.9 && <0.11
hasql
, hasql-dynamic-statements
, QuickCheck >=2.8.1 && <3
, quickcheck-instances >=0.3.11 && <0.4
, rerebase <2
, tasty >=0.12 && <2
, tasty-hunit >=0.9 && <0.11
, tasty-quickcheck >=0.9 && <0.11
47 changes: 22 additions & 25 deletions library/Hasql/DynamicStatements/Prelude.hs
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
module Hasql.DynamicStatements.Prelude
(
module Exports,
)
( module Exports,
)
where


-- base
-------------------------
import Control.Applicative as Exports
import Control.Arrow as Exports
import Control.Category as Exports
import Control.Concurrent as Exports
import Control.Exception as Exports
import Control.Monad as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)
import Control.Monad.IO.Class as Exports
import Control.Monad as Exports hiding (fail, forM, forM_, mapM, mapM_, msum, sequence, sequence_)
import Control.Monad.Fail as Exports
import Control.Monad.Fix as Exports hiding (fix)
import Control.Monad.IO.Class as Exports
import Control.Monad.ST as Exports
import Data.Bits as Exports
import Data.Bool as Exports
-- containers
-------------------------

-- bytestring
-------------------------
import Data.ByteString as Exports (ByteString)
import Data.Char as Exports
import Data.Coerce as Exports
import Data.Complex as Exports
Expand All @@ -31,17 +35,18 @@ import Data.Function as Exports hiding (id, (.))
import Data.Functor as Exports hiding (unzip)
import Data.Functor.Contravariant as Exports
import Data.Functor.Identity as Exports
import Data.Int as Exports
import Data.IORef as Exports
import Data.Int as Exports
import Data.Ix as Exports
import Data.List as Exports hiding (sortOn, isSubsequenceOf, uncons, concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')
import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, isSubsequenceOf, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sortOn, sum, uncons)
import Data.Maybe as Exports
import Data.Monoid as Exports hiding (Last(..), First(..), (<>))
import Data.Monoid as Exports hiding (First (..), Last (..), (<>))
import Data.Ord as Exports
import Data.Proxy as Exports
import Data.Ratio as Exports
import Data.Semigroup as Exports
import Data.STRef as Exports
import Data.Semigroup as Exports
import Data.Sequence as Exports (Seq)
import Data.String as Exports
import Data.Traversable as Exports
import Data.Tuple as Exports
Expand All @@ -52,13 +57,12 @@ import Debug.Trace as Exports
import Foreign.ForeignPtr as Exports
import Foreign.Ptr as Exports
import Foreign.StablePtr as Exports
import Foreign.Storable as Exports hiding (sizeOf, alignment)
import GHC.Conc as Exports hiding (withMVar, threadWaitWriteSTM, threadWaitWrite, threadWaitReadSTM, threadWaitRead)
import GHC.Exts as Exports (lazy, inline, sortWith, groupWith, IsList(..))
import Foreign.Storable as Exports hiding (alignment, sizeOf)
import GHC.Conc as Exports hiding (threadWaitRead, threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, withMVar)
import GHC.Exts as Exports (IsList (..), groupWith, inline, lazy, sortWith)
import GHC.Generics as Exports (Generic, Generic1)
import GHC.IO.Exception as Exports
import Numeric as Exports
import Prelude as Exports hiding (fail, concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, id, (.))
import System.Environment as Exports
import System.Exit as Exports
import System.IO as Exports
Expand All @@ -68,15 +72,8 @@ import System.Mem as Exports
import System.Mem.StableName as Exports
import System.Timeout as Exports
import Text.ParserCombinators.ReadP as Exports (ReadP, ReadS, readP_to_S, readS_to_P)
import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readPrec_to_P, readP_to_Prec, readPrec_to_S, readS_to_Prec)
import Text.Printf as Exports (printf, hPrintf)
import Text.Read as Exports (Read(..), readMaybe, readEither)
import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readP_to_Prec, readPrec_to_P, readPrec_to_S, readS_to_Prec)
import Text.Printf as Exports (hPrintf, printf)
import Text.Read as Exports (Read (..), readEither, readMaybe)
import Unsafe.Coerce as Exports

-- containers
-------------------------
import Data.Sequence as Exports (Seq)

-- bytestring
-------------------------
import Data.ByteString as Exports (ByteString)
import Prelude as Exports hiding (all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.))
19 changes: 9 additions & 10 deletions library/Hasql/DynamicStatements/Session.hs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
module Hasql.DynamicStatements.Session where

import qualified Hasql.Decoders as Decoders
import Hasql.DynamicStatements.Prelude
import Hasql.Session
import qualified Hasql.DynamicStatements.Snippet.Defs as SnippetDefs
import qualified Hasql.DynamicStatements.Statement as Statement
import qualified Hasql.Decoders as Decoders
import Hasql.Session
import qualified Hasql.Session as Session

{-|
Execute a dynamically parameterized statement, providing a result decoder.
This is merely a shortcut, which immediately embeds
@Hasql.DynamicStatements.Statement.'Statement.dynamicallyParameterized'@
in @Session@.
For details see the docs on that function.
-}
-- |
-- Execute a dynamically parameterized statement, providing a result decoder.
--
-- This is merely a shortcut, which immediately embeds
-- @Hasql.DynamicStatements.Statement.'Statement.dynamicallyParameterized'@
-- in @Session@.
-- For details see the docs on that function.
dynamicallyParameterizedStatement :: SnippetDefs.Snippet -> Decoders.Result result -> Bool -> Session result
dynamicallyParameterizedStatement snippet decoder prepared =
Session.statement () (Statement.dynamicallyParameterized snippet decoder prepared)
11 changes: 5 additions & 6 deletions library/Hasql/DynamicStatements/Snippet.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module Hasql.DynamicStatements.Snippet
(
Snippet,
param,
encoderAndParam,
sql,
)
( Snippet,
param,
encoderAndParam,
sql,
)
where

import Hasql.DynamicStatements.Snippet.Defs
70 changes: 33 additions & 37 deletions library/Hasql/DynamicStatements/Snippet/Defs.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,52 @@ import Hasql.DynamicStatements.Prelude
import qualified Hasql.Encoders as Encoders
import qualified Hasql.Implicits.Encoders as Encoders


{-|
Composable SQL snippet with parameters injected.
Abstracts over placeholders and matching of encoders.
It has an instance of `IsString`, so having the @OverloadedStrings@ extension enabled
you can construct it directly from string literals.
Here's an example:
@
selectSubstring :: Text -> Maybe Int32 -> Maybe Int32 -> 'Snippet'
selectSubstring string from to =
"select substring(" <> 'param' string <>
'foldMap' (\\ x -> " from " <> 'param' x) from <>
'foldMap' (\\ x -> " for " <> 'param' x) to <>
")"
@
Having a decoder you can lift it into 'Hasql.Statement.Statement' using
'Hasql.DynamicStatements.Statement.dynamicallyParameterized' or directly execute it in
'Hasql.Session.Session' using
'Hasql.DynamicStatements.Session.dynamicallyParameterizedStatement'.
-}
-- |
-- Composable SQL snippet with parameters injected.
-- Abstracts over placeholders and matching of encoders.
--
-- It has an instance of `IsString`, so having the @OverloadedStrings@ extension enabled
-- you can construct it directly from string literals.
--
-- Here's an example:
--
-- @
-- selectSubstring :: Text -> Maybe Int32 -> Maybe Int32 -> 'Snippet'
-- selectSubstring string from to =
-- "select substring(" <> 'param' string <>
-- 'foldMap' (\\ x -> " from " <> 'param' x) from <>
-- 'foldMap' (\\ x -> " for " <> 'param' x) to <>
-- ")"
-- @
--
-- Having a decoder you can lift it into 'Hasql.Statement.Statement' using
-- 'Hasql.DynamicStatements.Statement.dynamicallyParameterized' or directly execute it in
-- 'Hasql.Session.Session' using
-- 'Hasql.DynamicStatements.Session.dynamicallyParameterizedStatement'.
newtype Snippet = Snippet (Seq SnippetChunk)

data SnippetChunk =
StringSnippetChunk ByteString |
ParamSnippetChunk (Encoders.Params ())
data SnippetChunk
= StringSnippetChunk ByteString
| ParamSnippetChunk (Encoders.Params ())

deriving instance Semigroup Snippet

deriving instance Monoid Snippet

instance IsString Snippet where
fromString x = Snippet (pure (StringSnippetChunk (fromString x)))

{-|
SQL chunk in ASCII.
-}
-- |
-- SQL chunk in ASCII.
sql :: ByteString -> Snippet
sql x = Snippet (pure (StringSnippetChunk x))

{-|
Parameter encoded using an implicitly derived encoder from the type.
-}
param :: Encoders.DefaultParamEncoder param => param -> Snippet
-- |
-- Parameter encoded using an implicitly derived encoder from the type.
param :: (Encoders.DefaultParamEncoder param) => param -> Snippet
param = encoderAndParam Encoders.defaultParam

{-|
Parameter with an explicitly defined encoder.
-}
-- |
-- Parameter with an explicitly defined encoder.
encoderAndParam :: Encoders.NullableOrNot Encoders.Value param -> param -> Snippet
encoderAndParam encoder param = Snippet (pure (ParamSnippetChunk (param >$ Encoders.param encoder)))

0 comments on commit dd62238

Please sign in to comment.