{- |
Copyright : Flipstone Technology Partners 2023
License   : MIT
Stability : Stable

@since 1.0.0.0
-}
module Orville.PostgreSQL.PgCatalog.PgAttributeDefault
  ( PgAttributeDefault (..)
  , pgAttributeDefaultTable
  , attributeDefaultRelationOidField
  )
where

import qualified Data.Text as T
import qualified Database.PostgreSQL.LibPQ as LibPQ

import qualified Orville.PostgreSQL as Orville
import Orville.PostgreSQL.PgCatalog.OidField (oidField, oidTypeField)
import Orville.PostgreSQL.PgCatalog.PgAttribute (AttributeNumber, attributeNumberTypeField)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql
import qualified Orville.PostgreSQL.Raw.SqlValue as SqlValue

{- |
  The Haskell representation of data read from the @pg_catalog.pg_attrdef@
  table.

@since 1.0.0.0
-}
data PgAttributeDefault = PgAttributeDefault
  { PgAttributeDefault -> Oid
pgAttributeDefaultOid :: LibPQ.Oid
  -- ^ The PostgreSQL @oid@ for the default value.
  , PgAttributeDefault -> Oid
pgAttributeDefaultRelationOid :: LibPQ.Oid
  -- ^ The PostgreSQL @oid@ for the relation that this
  -- attribute belongs to. References @pg_class.oid@.
  , PgAttributeDefault -> AttributeNumber
pgAttributeDefaultAttributeNumber :: AttributeNumber
  -- ^ The PostgreSQL attribute number for the column that this
  -- default belongs to. References @pg_attribute.attnum@.
  , PgAttributeDefault -> Text
pgAttributeDefaultExpression :: T.Text
  -- ^ The PostgreSQL default value expression, as decompiled from the
  -- @adbin@ column using the PostgreSQL @pg_get_expr@ function.
  }

{- |
  An Orville 'Orville.TableDefinition' for querying the
  @pg_catalog.pg_attrdef@ table.

@since 1.0.0.0
-}
pgAttributeDefaultTable :: Orville.TableDefinition Orville.NoKey PgAttributeDefault PgAttributeDefault
pgAttributeDefaultTable :: TableDefinition NoKey PgAttributeDefault PgAttributeDefault
pgAttributeDefaultTable =
  String
-> TableDefinition NoKey PgAttributeDefault PgAttributeDefault
-> TableDefinition NoKey PgAttributeDefault PgAttributeDefault
forall key writeEntity readEntity.
String
-> TableDefinition key writeEntity readEntity
-> TableDefinition key writeEntity readEntity
Orville.setTableSchema String
"pg_catalog" (TableDefinition NoKey PgAttributeDefault PgAttributeDefault
 -> TableDefinition NoKey PgAttributeDefault PgAttributeDefault)
-> TableDefinition NoKey PgAttributeDefault PgAttributeDefault
-> TableDefinition NoKey PgAttributeDefault PgAttributeDefault
forall a b. (a -> b) -> a -> b
$
    String
-> SqlMarshaller PgAttributeDefault PgAttributeDefault
-> TableDefinition NoKey PgAttributeDefault PgAttributeDefault
forall writeEntity readEntity.
String
-> SqlMarshaller writeEntity readEntity
-> TableDefinition NoKey writeEntity readEntity
Orville.mkTableDefinitionWithoutKey
      String
"pg_attrdef"
      SqlMarshaller PgAttributeDefault PgAttributeDefault
pgAttributeDefaultMarshaller

pgAttributeDefaultMarshaller :: Orville.SqlMarshaller PgAttributeDefault PgAttributeDefault
pgAttributeDefaultMarshaller :: SqlMarshaller PgAttributeDefault PgAttributeDefault
pgAttributeDefaultMarshaller =
  Oid -> Oid -> AttributeNumber -> Text -> PgAttributeDefault
PgAttributeDefault
    (Oid -> Oid -> AttributeNumber -> Text -> PgAttributeDefault)
-> SqlMarshaller PgAttributeDefault Oid
-> SqlMarshaller
     PgAttributeDefault
     (Oid -> AttributeNumber -> Text -> PgAttributeDefault)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (PgAttributeDefault -> Oid)
-> FieldDefinition NotNull Oid
-> SqlMarshaller PgAttributeDefault Oid
forall writeEntity fieldValue nullability.
(writeEntity -> fieldValue)
-> FieldDefinition nullability fieldValue
-> SqlMarshaller writeEntity fieldValue
Orville.marshallField PgAttributeDefault -> Oid
pgAttributeDefaultOid FieldDefinition NotNull Oid
oidField
    SqlMarshaller
  PgAttributeDefault
  (Oid -> AttributeNumber -> Text -> PgAttributeDefault)
-> SqlMarshaller PgAttributeDefault Oid
-> SqlMarshaller
     PgAttributeDefault (AttributeNumber -> Text -> PgAttributeDefault)
forall a b.
SqlMarshaller PgAttributeDefault (a -> b)
-> SqlMarshaller PgAttributeDefault a
-> SqlMarshaller PgAttributeDefault b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (PgAttributeDefault -> Oid)
-> FieldDefinition NotNull Oid
-> SqlMarshaller PgAttributeDefault Oid
forall writeEntity fieldValue nullability.
(writeEntity -> fieldValue)
-> FieldDefinition nullability fieldValue
-> SqlMarshaller writeEntity fieldValue
Orville.marshallField PgAttributeDefault -> Oid
pgAttributeDefaultRelationOid FieldDefinition NotNull Oid
attributeDefaultRelationOidField
    SqlMarshaller
  PgAttributeDefault (AttributeNumber -> Text -> PgAttributeDefault)
-> SqlMarshaller PgAttributeDefault AttributeNumber
-> SqlMarshaller PgAttributeDefault (Text -> PgAttributeDefault)
forall a b.
SqlMarshaller PgAttributeDefault (a -> b)
-> SqlMarshaller PgAttributeDefault a
-> SqlMarshaller PgAttributeDefault b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (PgAttributeDefault -> AttributeNumber)
-> FieldDefinition NotNull AttributeNumber
-> SqlMarshaller PgAttributeDefault AttributeNumber
forall writeEntity fieldValue nullability.
(writeEntity -> fieldValue)
-> FieldDefinition nullability fieldValue
-> SqlMarshaller writeEntity fieldValue
Orville.marshallField PgAttributeDefault -> AttributeNumber
pgAttributeDefaultAttributeNumber FieldDefinition NotNull AttributeNumber
attributeDefaultAttributeNumberField
    SqlMarshaller PgAttributeDefault (Text -> PgAttributeDefault)
-> SqlMarshaller PgAttributeDefault Text
-> SqlMarshaller PgAttributeDefault PgAttributeDefault
forall a b.
SqlMarshaller PgAttributeDefault (a -> b)
-> SqlMarshaller PgAttributeDefault a
-> SqlMarshaller PgAttributeDefault b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SyntheticField Text -> SqlMarshaller PgAttributeDefault Text
forall fieldValue writeEntity.
SyntheticField fieldValue -> SqlMarshaller writeEntity fieldValue
Orville.marshallSyntheticField SyntheticField Text
attributeDefaultExpressionField

{- |
  The @adrelid@ column of the @pg_catalog.pg_attrdef@ table.

@since 1.0.0.0
-}
attributeDefaultRelationOidField :: Orville.FieldDefinition Orville.NotNull LibPQ.Oid
attributeDefaultRelationOidField :: FieldDefinition NotNull Oid
attributeDefaultRelationOidField =
  String -> FieldDefinition NotNull Oid
oidTypeField String
"adrelid"

{- |
  The @adnum@ column of the @pg_catalog.pg_attrdef@ table.

@since 1.0.0.0
-}
attributeDefaultAttributeNumberField :: Orville.FieldDefinition Orville.NotNull AttributeNumber
attributeDefaultAttributeNumberField :: FieldDefinition NotNull AttributeNumber
attributeDefaultAttributeNumberField =
  String -> FieldDefinition NotNull AttributeNumber
attributeNumberTypeField String
"adnum"

{- |
  A syntheticField for selecting the default expression by decompiling the
  @adbin@ column of the @pg_catalog.pg_attrdef@ table. The @pg_node_tree@ found
  in the column is decompiled by selecting the expression
  @pg_get_expr(adbin,adrelid)@.

@since 1.0.0.0
-}
attributeDefaultExpressionField :: Orville.SyntheticField T.Text
attributeDefaultExpressionField :: SyntheticField Text
attributeDefaultExpressionField =
  ValueExpression
-> String
-> (SqlValue -> Either String Text)
-> SyntheticField Text
forall a.
ValueExpression
-> String -> (SqlValue -> Either String a) -> SyntheticField a
Orville.syntheticField
    (String -> ValueExpression
forall a. SqlExpression a => String -> a
RawSql.unsafeSqlExpression String
"pg_get_expr(adbin,adrelid)")
    String
"expression"
    SqlValue -> Either String Text
SqlValue.toText