{-# language FlexibleContexts #-}
{-# language MonoLocalBinds #-}

module Rel8.Statement.View
  ( createView
  )
where

-- base
import Prelude

-- hasql
import qualified Hasql.Decoders as Hasql
import qualified Hasql.Encoders as Hasql
import qualified Hasql.Statement as Hasql

-- rel8
import Rel8.Query ( Query )
import Rel8.Schema.Name ( Selects )
import Rel8.Schema.Table ( TableSchema )
import Rel8.Statement.Insert ( ppInto )
import Rel8.Statement.Select ( ppSelect )

-- pretty
import Text.PrettyPrint ( Doc, (<+>), ($$), text )

-- text
import qualified Data.Text as Text
import Data.Text.Encoding ( encodeUtf8 )


-- | Given a 'TableSchema' and 'Query', @createView@ runs a @CREATE VIEW@
-- statement that will save the given query as a view. This can be useful if
-- you want to share Rel8 queries with other applications.
createView :: Selects names exprs
  => TableSchema names -> Query exprs -> Hasql.Statement () ()
createView :: TableSchema names -> Query exprs -> Statement () ()
createView TableSchema names
schema Query exprs
query = ByteString -> Params () -> Result () -> Bool -> Statement () ()
forall a b.
ByteString -> Params a -> Result b -> Bool -> Statement a b
Hasql.Statement ByteString
bytes Params ()
params Result ()
decode Bool
prepare
  where
    bytes :: ByteString
bytes = Text -> ByteString
encodeUtf8 (String -> Text
Text.pack String
sql)
    params :: Params ()
params = Params ()
Hasql.noParams
    decode :: Result ()
decode = Result ()
Hasql.noResult
    prepare :: Bool
prepare = Bool
False
    sql :: String
sql = Doc -> String
forall a. Show a => a -> String
show Doc
doc
    doc :: Doc
doc = TableSchema names -> Query exprs -> Doc
forall names exprs.
Selects names exprs =>
TableSchema names -> Query exprs -> Doc
ppCreateView TableSchema names
schema Query exprs
query


ppCreateView :: Selects names exprs
  => TableSchema names -> Query exprs -> Doc
ppCreateView :: TableSchema names -> Query exprs -> Doc
ppCreateView TableSchema names
schema Query exprs
query =
  String -> Doc
text String
"CREATE VIEW" Doc -> Doc -> Doc
<+>
  TableSchema names -> Doc
forall a. Table Name a => TableSchema a -> Doc
ppInto TableSchema names
schema Doc -> Doc -> Doc
$$
  String -> Doc
text String
"AS" Doc -> Doc -> Doc
<+>
  Query exprs -> Doc
forall a. Table Expr a => Query a -> Doc
ppSelect Query exprs
query