postgresql-simple-interpolate 0.1 → 0.1.1.0
raw patch · 3 files changed
+91/−16 lines, 3 filesdep +criteriondep +postgresql-simple-interpolatedep ~basedep ~mtldep ~postgresql-simplenew-uploaderPVP ok
version bump matches the API change (PVP)
Dependencies added: criterion, postgresql-simple-interpolate
Dependency ranges changed: base, mtl, postgresql-simple
API changes (from Hackage documentation)
+ Database.PostgreSQL.Simple.SqlQQ.Interpolated: iexecute :: QuasiQuoter
+ Database.PostgreSQL.Simple.SqlQQ.Interpolated: iexecute_ :: QuasiQuoter
+ Database.PostgreSQL.Simple.SqlQQ.Interpolated: iquery :: QuasiQuoter
Files
- benchmarks/Benchmarks.hs +44/−0
- postgresql-simple-interpolate.cabal +16/−4
- src/Database/PostgreSQL/Simple/SqlQQ/Interpolated.hs +31/−12
+ benchmarks/Benchmarks.hs view
@@ -0,0 +1,44 @@+module Benchmarks where++import Database.PostgreSQL.Simple.SqlQQ.Interpolated+import Database.PostgreSQL.Simple.SqlQQ.Interpolated.Parser++import Data.List (foldl')+import Criterion+import Criterion.Main+import Language.Haskell.TH++main = defaultMain+ [ bench "combineParts foldl' length 2" $+ nf combinePartsL' sql2+ , bench "combineParts foldl' length 100" $+ nf combinePartsL' sql100+ , bench "combineParts foldr length 2" $ nf combinePartsR sql2+ , bench "combineParts foldr length 100" $ nf combinePartsR sql100+ ]+++sql2 :: [Either String Int]+sql2 =+ [ Left "SELECT field FROM table WHERE name = "+ , Right 1+ , Left " LIMIT "+ , Right 2+ ]++sql100 :: [Either String Int]+sql100 = concat [ [Left " ", Right n ] | n <- [1..100]]++-- | The same as combineParts in the library, using foldl'+combinePartsL' :: [Either String Int] -> (String, [Int])+combinePartsL' = foldl' step ("", [])+ where+ step (s, exprs) subExpr = case subExpr of+ Left str -> (s <> str, exprs)+ Right e -> (s <> "?", exprs <> [e]) -- TODO: Make this not slow++combinePartsR :: [Either String Int] -> (String, [Int])+combinePartsR = foldr step ("", [])+ where step subExpr (s, exprs) = case subExpr of+ Left str -> (str <> s, exprs)+ Right e -> ("?" <> s, e : exprs)
postgresql-simple-interpolate.cabal view
@@ -1,5 +1,5 @@ name: postgresql-simple-interpolate-version: 0.1+version: 0.1.1.0 synopsis: Interpolated SQL queries via quasiquotation description: Interpolated SQL queries via quasiquotation license: BSD3@@ -10,7 +10,7 @@ homepage: https://github.com/3noch/postgresql-simple-interpolate category: Database build-type: Simple-cabal-version: >=1.8+cabal-version: >=1.10 source-repository head type: git@@ -24,8 +24,20 @@ build-depends: base >= 4.5 && < 5, haskell-src-meta >= 0.6 && < 0.9,- mtl >=2.1 && < 2.3,+ mtl >=2.1 && < 2.4, parsec ==3.1.*,- postgresql-simple,+ postgresql-simple >= 0.1, template-haskell ghc-options: -Wall -O2+ default-language: Haskell2010++benchmark criterion+ hs-source-dirs: benchmarks+ main-is: Benchmarks.hs+ ghc-options: -O2 -Wall -rtsopts+ build-depends: postgresql-simple-interpolate+ , base+ , criterion+ , template-haskell+ default-language: Haskell2010+ type: exitcode-stdio-1.0
src/Database/PostgreSQL/Simple/SqlQQ/Interpolated.hs view
@@ -1,14 +1,20 @@ {-# LANGUAGE TemplateHaskell #-} -- | Interpolated SQL queries-module Database.PostgreSQL.Simple.SqlQQ.Interpolated (isql, quoteInterpolatedSql) where+module Database.PostgreSQL.Simple.SqlQQ.Interpolated+ ( isql+ , quoteInterpolatedSql+ , iquery+ , iexecute+ , iexecute_+ ) where import Language.Haskell.TH (Exp, Q, appE, listE, sigE, tupE, varE) import Language.Haskell.TH.Quote (QuasiQuoter (..))-import Data.List (foldl') import Database.PostgreSQL.Simple.ToField (Action, toField) import Database.PostgreSQL.Simple.SqlQQ (sql) import Text.Parsec (ParseError)+import Database.PostgreSQL.Simple import Database.PostgreSQL.Simple.SqlQQ.Interpolated.Parser (StringPart (..), parseInterpolated) @@ -48,12 +54,12 @@ } combineParts :: [StringPart] -> (String, [Q Exp])-combineParts = foldl' step ("", [])+combineParts = foldr step ("", []) where- step (s, exprs) subExpr = case subExpr of- Lit str -> (s <> str, exprs)- Esc c -> (s <> [c], exprs)- Anti e -> (s <> "?", exprs <> [e]) -- TODO: Make this not slow+ step subExpr (s, exprs) = case subExpr of+ Lit str -> (str <> s, exprs)+ Esc c -> (c : s, exprs)+ Anti e -> ('?' : s, e : exprs) applySql :: [StringPart] -> Q Exp applySql parts =@@ -67,8 +73,21 @@ quoteInterpolatedSql s = either (handleError s) applySql (parseInterpolated s) handleError :: String -> ParseError -> Q Exp-handleError expStr parseError = error $- "Failed to parse interpolated expression in string: "- ++ expStr- ++ "\n"- ++ show parseError+handleError expStr parseError = error $ mconcat+ [ "Failed to parse interpolated expression in string: "+ , expStr+ , "\n"+ , show parseError+ ]++-- | Invokes 'query' with arguments provided by 'isql'+iquery :: QuasiQuoter+iquery = isql { quoteExp = appE [| uncurry query |] . quoteInterpolatedSql }++-- | Invokes 'execute' with arguments provided by 'isql'+iexecute :: QuasiQuoter+iexecute = isql { quoteExp = appE [| uncurry execute |] . quoteInterpolatedSql }++-- | Invokes 'execute_' with arguments provided by 'isql'+iexecute_ :: QuasiQuoter+iexecute_ = isql { quoteExp = appE [| uncurry execute_ |] . quoteInterpolatedSql }