git.iko.soy/typeable/postgresql-simple
on master help sign in
Add a rudimentary SQL quasiquoter
commit4451159ae6fb9ead3797d4a0362efbab1126f510 authorLeon P Smith <leon@melding-monads.com> dateWed 28 Dec 2011, 13:29 (15 years ago) parent1d5a622
2 files changed+55−1
postgresql-simple.cabal+3−1 src/Database/PostgreSQL/Simple/SqlQQ.hs+52
postgresql-simple.cabal+3−1
@@ -27,9 +27,10 @@ Library
2727 Database.PostgreSQL.Simple.LargeObjects
2828 Database.PostgreSQL.Simple.Notification
2929 Database.PostgreSQL.Simple.Param
30− Database.PostgreSQL.Simple.Result
3130 Database.PostgreSQL.Simple.QueryParams
3231 Database.PostgreSQL.Simple.QueryResults
32+ Database.PostgreSQL.Simple.Result
33+ Database.PostgreSQL.Simple.SqlQQ
3334 Database.PostgreSQL.Simple.Types
3435-- Other-modules:
3536 Database.PostgreSQL.Simple.Internal
@@ -45,6 +46,7 @@ Library
4546 postgresql-libpq >= 0.6,
4647 pcre-light,
4748 old-locale,
49+ template-haskell,
4850 text >= 0.11.0.2,
4951 time
5052 -- Modules not exported by this package.
src/Database/PostgreSQL/Simple/SqlQQ.hsnew file+52
@@ -0,0 +1,52 @@
1+------------------------------------------------------------------------------
2+-- |
3+-- Module: Database.PostgreSQL.Simple.SqlQQ
4+-- Copyright: (c) 2011 Leon P Smith
5+-- License: BSD3
6+-- Maintainer: Leon P Smith <leon@melding-monads.com>
7+-- Stability: experimental
8+--
9+------------------------------------------------------------------------------
10+
11+module Database.PostgreSQL.Simple.SqlQQ (sql) where
12+
13+import Language.Haskell.TH
14+import Language.Haskell.TH.Quote
15+import Data.Char
16+
17+-- | 'sql' is a quasiquoter that eases the syntactic burden
18+-- of writing big sql statements in Haskell source code. It attempts
19+-- to minimize whitespace. Note that this implementation is incomplete
20+-- and can mess up your syntax; it only really understands standard
21+-- sql string literals (default in PostgreSQL 9) and not the extended
22+-- escape syntax or other situations where white space should be
23+-- preserved as is.
24+
25+sql :: QuasiQuoter
26+sql = QuasiQuoter
27+ { quotePat = error "Database.PostgreSQL.Simple.SqlQQ.sql:\
28+ \ quasiquoter used in pattern context"
29+ , quoteType = error "Database.PostgreSQL.Simple.SqlQQ.sql:\
30+ \ quasiquoter used in type context"
31+ , quoteExp = sqlExp
32+ , quoteDec = error "Database.PostgreSQL.Simple.SqlQQ.sql:\
33+ \ quasiquoter used in declaration context"
34+ }
35+
36+sqlExp :: String -> Q Exp
37+sqlExp = stringE . outstring . dropSpace
38+ where
39+ dropSpace = dropWhile isSpace
40+
41+ outstring ('\'':xs) = '\'' : instring xs
42+ outstring (x:xs) | isSpace x = case dropSpace xs of
43+ [] -> []
44+ ys -> ' ' : outstring ys
45+ | otherwise = x : outstring xs
46+ outstring [] = []
47+
48+ instring ('\'':'\'':xs) = '\'':'\'': instring xs
49+ instring ('\'':xs) = '\'': outstring xs
50+ instring (x:xs) = x : instring xs
51+ instring [] = error "Database.PostgreSQL.Simple.SqlQQ.sql:\
52+ \ string literal not terminated"