{- |
Module: Squeal.PostgreSQL.Definition.Constraint
Description: comments
Copyright: (c) Eitan Chatav, 2020
Maintainer: eitan@morphism.tech
Stability: experimental
 
comments
-}

{-# LANGUAGE
    AllowAmbiguousTypes
  , ConstraintKinds
  , DeriveAnyClass
  , DeriveGeneric
  , DerivingStrategies
  , FlexibleContexts
  , FlexibleInstances
  , GADTs
  , LambdaCase
  , MultiParamTypeClasses
  , OverloadedLabels
  , OverloadedStrings
  , RankNTypes
  , ScopedTypeVariables
  , TypeApplications
  , TypeInType
  , TypeOperators
  , UndecidableSuperClasses
  #-}

module Squeal.PostgreSQL.Definition.Comment
  ( commentOnTable
  , commentOnType
  , commentOnView
  , commentOnFunction
  , commentOnIndex
  , commentOnColumn
  , commentOnSchema
  ) where

import Squeal.PostgreSQL.Definition
import Squeal.PostgreSQL.Type.Alias
import Squeal.PostgreSQL.Render
import Squeal.PostgreSQL.Type.Schema
import GHC.TypeLits (KnownSymbol)
import Data.Text (Text)

{-----------------------------------------
COMMENT statements
-----------------------------------------}

{- |
When a user views a table in the database (i.e. with \d+ <table>), it is useful
to be able to read a description of the table.
-}
commentOnTable
  :: ( KnownSymbol sch
     , KnownSymbol tab
     , Has sch db schema
     , Has tab schema ('Table table)
     )
  => QualifiedAlias sch tab -- ^ table
  -> Text -- ^ comment
  -> Definition db db
commentOnTable :: QualifiedAlias sch tab -> Text -> Definition db db
commentOnTable QualifiedAlias sch tab
alias Text
comm = ByteString -> Definition db db
forall (db0 :: SchemasType) (db1 :: SchemasType).
ByteString -> Definition db0 db1
UnsafeDefinition (ByteString -> Definition db db) -> ByteString -> Definition db db
forall a b. (a -> b) -> a -> b
$
  ByteString
"COMMENT ON TABLE" ByteString -> ByteString -> ByteString
<+> QualifiedAlias sch tab -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL QualifiedAlias sch tab
alias ByteString -> ByteString -> ByteString
<+> ByteString
"IS" ByteString -> ByteString -> ByteString
<+> Text -> ByteString
singleQuotedText Text
comm ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
";"

{- |
When a user views a type in the database (i.e with \dT <type>), it is useful to
be able to read a description of the type.
-}
commentOnType
  :: ( KnownSymbol sch
     , KnownSymbol typ
     , Has sch db schema
     , Has typ schema ('Typedef type_)
     )
  => QualifiedAlias sch typ -- ^ type
  -> Text -- ^ comment
  -> Definition db db
commentOnType :: QualifiedAlias sch typ -> Text -> Definition db db
commentOnType QualifiedAlias sch typ
alias Text
comm = ByteString -> Definition db db
forall (db0 :: SchemasType) (db1 :: SchemasType).
ByteString -> Definition db0 db1
UnsafeDefinition (ByteString -> Definition db db) -> ByteString -> Definition db db
forall a b. (a -> b) -> a -> b
$
  ByteString
"COMMENT ON TYPE" ByteString -> ByteString -> ByteString
<+> QualifiedAlias sch typ -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL QualifiedAlias sch typ
alias ByteString -> ByteString -> ByteString
<+> ByteString
"IS" ByteString -> ByteString -> ByteString
<+> Text -> ByteString
singleQuotedText Text
comm ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
";"

{- |
When a user views a view in the database (i.e. with \dv <view>), it is useful
to be able to read a description of the view.
-}
commentOnView
  :: ( KnownSymbol sch
     , KnownSymbol vie
     , Has sch db schema
     , Has vie schema ('View view)
     )
  => QualifiedAlias sch vie -- ^ view
  -> Text -- ^ comment
  -> Definition db db
commentOnView :: QualifiedAlias sch vie -> Text -> Definition db db
commentOnView QualifiedAlias sch vie
alias Text
comm = ByteString -> Definition db db
forall (db0 :: SchemasType) (db1 :: SchemasType).
ByteString -> Definition db0 db1
UnsafeDefinition (ByteString -> Definition db db) -> ByteString -> Definition db db
forall a b. (a -> b) -> a -> b
$
  ByteString
"COMMENT ON VIEW" ByteString -> ByteString -> ByteString
<+> QualifiedAlias sch vie -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL QualifiedAlias sch vie
alias ByteString -> ByteString -> ByteString
<+> ByteString
"IS" ByteString -> ByteString -> ByteString
<+> Text -> ByteString
singleQuotedText Text
comm ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
";"

{- |
When a user views an index in the database (i.e. with \di+ <index>), it is
useful to be able to read a description of the index.
-}
commentOnIndex
  :: ( KnownSymbol sch
     , KnownSymbol ind
     , Has sch db schema
     , Has ind schema ('Index index)
     )
  => QualifiedAlias sch ind -- ^ index
  -> Text -- ^ comment
  -> Definition db db
commentOnIndex :: QualifiedAlias sch ind -> Text -> Definition db db
commentOnIndex QualifiedAlias sch ind
alias Text
comm = ByteString -> Definition db db
forall (db0 :: SchemasType) (db1 :: SchemasType).
ByteString -> Definition db0 db1
UnsafeDefinition (ByteString -> Definition db db) -> ByteString -> Definition db db
forall a b. (a -> b) -> a -> b
$
  ByteString
"COMMENT ON INDEX" ByteString -> ByteString -> ByteString
<+> QualifiedAlias sch ind -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL QualifiedAlias sch ind
alias ByteString -> ByteString -> ByteString
<+> ByteString
"IS" ByteString -> ByteString -> ByteString
<+> Text -> ByteString
singleQuotedText Text
comm ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
";"

{- |
When a user views a function in the database (i.e. with \df+ <function>), it is
useful to be able to read a description of the function.
-}
commentOnFunction
  :: ( KnownSymbol sch
     , KnownSymbol fun
     , Has sch db schema
     , Has fun schema ('Function function)
     )
  => QualifiedAlias sch fun -- ^ function
  -> Text -- ^ comment
  -> Definition db db
commentOnFunction :: QualifiedAlias sch fun -> Text -> Definition db db
commentOnFunction QualifiedAlias sch fun
alias Text
comm = ByteString -> Definition db db
forall (db0 :: SchemasType) (db1 :: SchemasType).
ByteString -> Definition db0 db1
UnsafeDefinition (ByteString -> Definition db db) -> ByteString -> Definition db db
forall a b. (a -> b) -> a -> b
$
  ByteString
"COMMENT ON FUNCTION" ByteString -> ByteString -> ByteString
<+> QualifiedAlias sch fun -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL QualifiedAlias sch fun
alias ByteString -> ByteString -> ByteString
<+> ByteString
"IS" ByteString -> ByteString -> ByteString
<+> Text -> ByteString
singleQuotedText Text
comm ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
";"

{- |
When a user views a table in the database (i.e. with \d+ <table>), it is useful
to be able to view descriptions of the columns in that table.
-}
commentOnColumn
  :: ( KnownSymbol sch
     , KnownSymbol tab
     , KnownSymbol col
     , Has sch db schema
     , Has tab schema ('Table '(cons, cols))
     , Has col cols '(def, nulltyp)
     )
  => QualifiedAlias sch tab -- ^ table
  -> Alias col -- ^ column
  -> Text -- ^ comment
  -> Definition db db
commentOnColumn :: QualifiedAlias sch tab -> Alias col -> Text -> Definition db db
commentOnColumn QualifiedAlias sch tab
table Alias col
col Text
comm = ByteString -> Definition db db
forall (db0 :: SchemasType) (db1 :: SchemasType).
ByteString -> Definition db0 db1
UnsafeDefinition (ByteString -> Definition db db) -> ByteString -> Definition db db
forall a b. (a -> b) -> a -> b
$
  ByteString
"COMMENT ON COLUMN" ByteString -> ByteString -> ByteString
<+> QualifiedAlias sch tab -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL QualifiedAlias sch tab
table ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"." ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> Alias col -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL Alias col
col ByteString -> ByteString -> ByteString
<+> ByteString
"IS"
  ByteString -> ByteString -> ByteString
<+> Text -> ByteString
singleQuotedText Text
comm ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
";"

{- |
When a user views a schema in the database (i.e. with \dn+ <schema>), it is
useful to be able to read a description.
-}
commentOnSchema
  :: ( KnownSymbol sch
     , Has sch db schema
     )
  => Alias sch -- ^ schema
  -> Text -- ^ comment
  -> Definition db db
commentOnSchema :: Alias sch -> Text -> Definition db db
commentOnSchema Alias sch
schema Text
comm = ByteString -> Definition db db
forall (db0 :: SchemasType) (db1 :: SchemasType).
ByteString -> Definition db0 db1
UnsafeDefinition (ByteString -> Definition db db) -> ByteString -> Definition db db
forall a b. (a -> b) -> a -> b
$
  ByteString
"COMMENT ON SCHEMA" ByteString -> ByteString -> ByteString
<+> Alias sch -> ByteString
forall sql. RenderSQL sql => sql -> ByteString
renderSQL Alias sch
schema ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"IS" ByteString -> ByteString -> ByteString
<+> Text -> ByteString
singleQuotedText Text
comm ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
";"