{-# LANGUAGE TemplateHaskell #-}

------------------------------------------------------------------------------
-- |
-- Module:      Database.SQLite.Simple.QQ
-- Copyright:   (c) 2011-2012 Leon P Smith
--              (c) 2018 Janne Hellsten
-- License:     BSD3
-- Maintainer:  Janne Hellsten <jjhellst@gmail.com>
-- Portability: portable
--
-- The 'sql' quasiquoter, for writing large @SQL@ statements.
--
------------------------------------------------------------------------------

module Database.SQLite.Simple.QQ
     ( sql
     ) where

import           Data.String                  (fromString)
import           Database.SQLite.Simple.Types (Query)
import           Language.Haskell.TH          (Exp, Q, appE, stringE)
import           Language.Haskell.TH.Quote    (QuasiQuoter (..))

{- | A quasiquoter for writing big @SQL@ queries.

One should consider turning on the @-XQuasiQuotes@ pragma in that module:

@
{-# LANGUAGE QuasiQuoter #-}

myQuery = query conn [sql|
    SELECT
      *
    FROM
      users
    WHERE jobTitle = ?
    |] jobTitle
@

-}
sql :: QuasiQuoter
sql :: QuasiQuoter
sql = QuasiQuoter :: (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    { quotePat :: String -> Q Pat
quotePat  = String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Database.SQLite.Simple.QQ.sql: quasiquoter used in pattern context"
    , quoteType :: String -> Q Type
quoteType = String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Database.SQLite.Simple.QQ.sql: quasiquoter used in type context"
    , quoteDec :: String -> Q [Dec]
quoteDec  = String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Database.SQLite.Simple.QQ.sql: quasiquoter used in declaration context"
    , quoteExp :: String -> Q Exp
quoteExp  = String -> Q Exp
sqlExp
    }

sqlExp :: String -> Q Exp
sqlExp :: String -> Q Exp
sqlExp = Q Exp -> Q Exp -> Q Exp
appE [| fromString :: String -> Query |] (Q Exp -> Q Exp) -> (String -> Q Exp) -> String -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Q Exp
stringE