{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}

module Opaleye.SQLite.Sql where

import qualified Opaleye.SQLite.Internal.HaskellDB.PrimQuery as HPQ

import qualified Opaleye.SQLite.Internal.Unpackspec as U
import qualified Opaleye.SQLite.Internal.Sql as Sql
import qualified Opaleye.SQLite.Internal.Print as Pr
import qualified Opaleye.SQLite.Internal.PrimQuery as PQ
import qualified Opaleye.SQLite.Internal.Optimize as Op
import           Opaleye.SQLite.Internal.Helpers ((.:))
import qualified Opaleye.SQLite.Internal.QueryArr as Q
import qualified Opaleye.SQLite.Internal.Tag as T

import qualified Data.Profunctor.Product.Default as D

-- | Example type specialization:
--
-- @
-- showSqlForPostgres :: Query (Column a, Column b) -> String
-- @
--
-- Assuming the @makeAdaptorAndInstance@ splice has been run for the
-- product type @Foo@:
--
-- @
-- showSqlForPostgres :: Query (Foo (Column a) (Column b) (Column c)) -> String
-- @
showSqlForPostgres :: forall columns . D.Default U.Unpackspec columns columns =>
                      Q.Query columns -> String
showSqlForPostgres :: Query columns -> String
showSqlForPostgres = Unpackspec columns columns -> Query columns -> String
forall columns b. Unpackspec columns b -> Query columns -> String
showSqlForPostgresExplicit (Unpackspec columns columns
forall (p :: * -> * -> *) a b. Default p a b => p a b
D.def :: U.Unpackspec columns columns)

showSqlForPostgresUnopt :: forall columns . D.Default U.Unpackspec columns columns =>
                           Q.Query columns -> String
showSqlForPostgresUnopt :: Query columns -> String
showSqlForPostgresUnopt = Unpackspec columns columns -> Query columns -> String
forall columns b. Unpackspec columns b -> Query columns -> String
showSqlForPostgresUnoptExplicit (Unpackspec columns columns
forall (p :: * -> * -> *) a b. Default p a b => p a b
D.def :: U.Unpackspec columns columns)

showSqlForPostgresExplicit :: U.Unpackspec columns b -> Q.Query columns -> String
showSqlForPostgresExplicit :: Unpackspec columns b -> Query columns -> String
showSqlForPostgresExplicit = ([PrimExpr], PrimQuery, Tag) -> String
formatAndShowSQL
                             (([PrimExpr], PrimQuery, Tag) -> String)
-> (([PrimExpr], PrimQuery, Tag) -> ([PrimExpr], PrimQuery, Tag))
-> ([PrimExpr], PrimQuery, Tag)
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\([PrimExpr]
x, PrimQuery
y, Tag
z) -> ([PrimExpr]
x, PrimQuery -> PrimQuery
Op.optimize PrimQuery
y, Tag
z))
                             (([PrimExpr], PrimQuery, Tag) -> String)
-> (Unpackspec columns b
    -> Query columns -> ([PrimExpr], PrimQuery, Tag))
-> Unpackspec columns b
-> Query columns
-> String
forall r z a b. (r -> z) -> (a -> b -> r) -> a -> b -> z
.: Unpackspec columns b
-> Query columns -> ([PrimExpr], PrimQuery, Tag)
forall a b.
Unpackspec a b -> Query a -> ([PrimExpr], PrimQuery, Tag)
Q.runQueryArrUnpack

showSqlForPostgresUnoptExplicit :: U.Unpackspec columns b -> Q.Query columns -> String
showSqlForPostgresUnoptExplicit :: Unpackspec columns b -> Query columns -> String
showSqlForPostgresUnoptExplicit = ([PrimExpr], PrimQuery, Tag) -> String
formatAndShowSQL (([PrimExpr], PrimQuery, Tag) -> String)
-> (Unpackspec columns b
    -> Query columns -> ([PrimExpr], PrimQuery, Tag))
-> Unpackspec columns b
-> Query columns
-> String
forall r z a b. (r -> z) -> (a -> b -> r) -> a -> b -> z
.: Unpackspec columns b
-> Query columns -> ([PrimExpr], PrimQuery, Tag)
forall a b.
Unpackspec a b -> Query a -> ([PrimExpr], PrimQuery, Tag)
Q.runQueryArrUnpack

formatAndShowSQL :: ([HPQ.PrimExpr], PQ.PrimQuery, T.Tag) -> String
formatAndShowSQL :: ([PrimExpr], PrimQuery, Tag) -> String
formatAndShowSQL = Doc -> String
forall a. Show a => a -> String
show (Doc -> String)
-> (([PrimExpr], PrimQuery, Tag) -> Doc)
-> ([PrimExpr], PrimQuery, Tag)
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Select -> Doc
Pr.ppSql (Select -> Doc)
-> (([PrimExpr], PrimQuery, Tag) -> Select)
-> ([PrimExpr], PrimQuery, Tag)
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([PrimExpr], PrimQuery, Tag) -> Select
Sql.sql