{-# language FlexibleContexts #-} {-# language MonoLocalBinds #-} module Rel8.Statement.View ( createView , createOrReplaceView ) where -- base import Prelude -- hasql import qualified Hasql.Decoders as Hasql import qualified Hasql.Encoders as Hasql import qualified Hasql.Statement as Hasql -- opaleye import qualified Opaleye.Internal.Tag as Opaleye -- pretty import Text.PrettyPrint ( Doc, (<+>), ($$), text ) -- 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 ) -- text import qualified Data.Text as Text import Data.Text.Encoding ( encodeUtf8 ) -- transformers import Control.Monad.Trans.State.Strict (evalState) data CreateView = Create | CreateOrReplace -- | 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 = createViewGeneric Create -- | Given a 'TableSchema' and 'Query', @createOrReplaceView@ runs a -- @CREATE OR REPLACE VIEW@ statement that will save the given query -- as a view, replacing the current view definition if it exists and -- adheres to the restrictions in place for replacing a view in -- PostgreSQL. createOrReplaceView :: Selects names exprs => TableSchema names -> Query exprs -> Hasql.Statement () () createOrReplaceView = createViewGeneric CreateOrReplace createViewGeneric :: Selects names exprs => CreateView -> TableSchema names -> Query exprs -> Hasql.Statement () () createViewGeneric replace schema query = Hasql.Statement bytes params decode prepare where bytes = encodeUtf8 (Text.pack sql) params = Hasql.noParams decode = Hasql.noResult prepare = False sql = show doc doc = ppCreateView schema query replace ppCreateView :: Selects names exprs => TableSchema names -> Query exprs -> CreateView -> Doc ppCreateView schema query replace = createOrReplace replace <+> ppInto schema $$ text "AS" <+> evalState (ppSelect query) Opaleye.start where createOrReplace Create = text "CREATE VIEW" createOrReplace CreateOrReplace = text "CREATE OR REPLACE VIEW"