{-# LANGUAGE GeneralizedNewtypeDeriving #-}

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

@since 1.0.0.0
-}
module Orville.PostgreSQL.Expr.TableDefinition
  ( CreateTableExpr
  , createTableExpr
  , PrimaryKeyExpr
  , primaryKeyExpr
  , AlterTableExpr
  , alterTableExpr
  , AlterTableAction
  , addColumn
  , dropColumn
  , addConstraint
  , dropConstraint
  , alterColumnType
  , alterColumnSetDefault
  , alterColumnDropDefault
  , UsingClause
  , usingCast
  , alterColumnNullability
  , AlterNotNull
  , setNotNull
  , dropNotNull
  , DropTableExpr
  , dropTableExpr
  )
where

import Data.List.NonEmpty (NonEmpty)
import Data.Maybe (catMaybes, maybeToList)

import Orville.PostgreSQL.Expr.ColumnDefinition (ColumnDefinition)
import Orville.PostgreSQL.Expr.DataType (DataType)
import Orville.PostgreSQL.Expr.IfExists (IfExists)
import Orville.PostgreSQL.Expr.Name (ColumnName, ConstraintName, Qualified, TableName)
import Orville.PostgreSQL.Expr.TableConstraint (TableConstraint)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql

{- |
Type to represent a @CREATE TABLE@ statement. E.G.

> CREATE TABLE foo (id integer)

'CreateTableExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.

@since 1.0.0.0
-}
newtype CreateTableExpr
  = CreateTableExpr RawSql.RawSql
  deriving (RawSql -> CreateTableExpr
CreateTableExpr -> RawSql
(CreateTableExpr -> RawSql)
-> (RawSql -> CreateTableExpr) -> SqlExpression CreateTableExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: CreateTableExpr -> RawSql
toRawSql :: CreateTableExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> CreateTableExpr
unsafeFromRawSql :: RawSql -> CreateTableExpr
RawSql.SqlExpression)

{- |
  Constructs a 'CreateTableExpr' with the given options.

  @since 1.0.0.0
-}
createTableExpr ::
  -- | The name to be used for the table.
  Qualified TableName ->
  -- | The columns to include in the table.
  [ColumnDefinition] ->
  -- | A primary key expression for the table.
  Maybe PrimaryKeyExpr ->
  -- | Any table constraints to include with the table.
  [TableConstraint] ->
  CreateTableExpr
createTableExpr :: Qualified TableName
-> [ColumnDefinition]
-> Maybe PrimaryKeyExpr
-> [TableConstraint]
-> CreateTableExpr
createTableExpr Qualified TableName
tableName [ColumnDefinition]
columnDefs Maybe PrimaryKeyExpr
mbPrimaryKey [TableConstraint]
constraints =
  let
    columnDefsSql :: [RawSql]
columnDefsSql =
      (ColumnDefinition -> RawSql) -> [ColumnDefinition] -> [RawSql]
forall a b. (a -> b) -> [a] -> [b]
map ColumnDefinition -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql [ColumnDefinition]
columnDefs

    constraintsSql :: [RawSql]
constraintsSql =
      (TableConstraint -> RawSql) -> [TableConstraint] -> [RawSql]
forall a b. (a -> b) -> [a] -> [b]
map TableConstraint -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql [TableConstraint]
constraints

    tableElementsSql :: [RawSql]
tableElementsSql =
      case Maybe PrimaryKeyExpr
mbPrimaryKey of
        Maybe PrimaryKeyExpr
Nothing ->
          [RawSql]
columnDefsSql [RawSql] -> [RawSql] -> [RawSql]
forall a. Semigroup a => a -> a -> a
<> [RawSql]
constraintsSql
        Just PrimaryKeyExpr
primaryKey ->
          PrimaryKeyExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql PrimaryKeyExpr
primaryKey RawSql -> [RawSql] -> [RawSql]
forall a. a -> [a] -> [a]
: ([RawSql]
columnDefsSql [RawSql] -> [RawSql] -> [RawSql]
forall a. Semigroup a => a -> a -> a
<> [RawSql]
constraintsSql)
  in
    RawSql -> CreateTableExpr
CreateTableExpr (RawSql -> CreateTableExpr) -> RawSql -> CreateTableExpr
forall a b. (a -> b) -> a -> b
$
      [RawSql] -> RawSql
forall a. Monoid a => [a] -> a
mconcat
        [ String -> RawSql
RawSql.fromString String
"CREATE TABLE "
        , Qualified TableName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Qualified TableName
tableName
        , RawSql
RawSql.space
        , RawSql
RawSql.leftParen
        , RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate RawSql
RawSql.comma [RawSql]
tableElementsSql
        , RawSql
RawSql.rightParen
        ]

{- |
Type to represent the primary key of a table. E.G.

> PRIMARY KEY (id)

'PrimaryKeyExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.

@since 1.0.0.0
-}
newtype PrimaryKeyExpr
  = PrimaryKeyExpr RawSql.RawSql
  deriving (RawSql -> PrimaryKeyExpr
PrimaryKeyExpr -> RawSql
(PrimaryKeyExpr -> RawSql)
-> (RawSql -> PrimaryKeyExpr) -> SqlExpression PrimaryKeyExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: PrimaryKeyExpr -> RawSql
toRawSql :: PrimaryKeyExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> PrimaryKeyExpr
unsafeFromRawSql :: RawSql -> PrimaryKeyExpr
RawSql.SqlExpression)

{- |
  Constructs a 'PrimaryKeyExpr' with the given columns.

  @since 1.0.0.0
-}
primaryKeyExpr :: NonEmpty ColumnName -> PrimaryKeyExpr
primaryKeyExpr :: NonEmpty ColumnName -> PrimaryKeyExpr
primaryKeyExpr NonEmpty ColumnName
columnNames =
  RawSql -> PrimaryKeyExpr
PrimaryKeyExpr (RawSql -> PrimaryKeyExpr) -> RawSql -> PrimaryKeyExpr
forall a b. (a -> b) -> a -> b
$
    [RawSql] -> RawSql
forall a. Monoid a => [a] -> a
mconcat
      [ String -> RawSql
RawSql.fromString String
"PRIMARY KEY "
      , RawSql
RawSql.leftParen
      , RawSql -> NonEmpty ColumnName -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate RawSql
RawSql.comma NonEmpty ColumnName
columnNames
      , RawSql
RawSql.rightParen
      ]

{- |
Type to represent an @ALTER TABLE@ statement. E.G.

> ALTER TABLE foo ADD COLUMN bar integer

'AlterTableExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.

@since 1.0.0.0
-}
newtype AlterTableExpr
  = AlterTableExpr RawSql.RawSql
  deriving (RawSql -> AlterTableExpr
AlterTableExpr -> RawSql
(AlterTableExpr -> RawSql)
-> (RawSql -> AlterTableExpr) -> SqlExpression AlterTableExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: AlterTableExpr -> RawSql
toRawSql :: AlterTableExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> AlterTableExpr
unsafeFromRawSql :: RawSql -> AlterTableExpr
RawSql.SqlExpression)

{- |
  Constructs an 'AlterTableExpr' with the given alter table actions.

  @since 1.0.0.0
-}
alterTableExpr :: Qualified TableName -> NonEmpty AlterTableAction -> AlterTableExpr
alterTableExpr :: Qualified TableName -> NonEmpty AlterTableAction -> AlterTableExpr
alterTableExpr Qualified TableName
tableName NonEmpty AlterTableAction
actions =
  RawSql -> AlterTableExpr
AlterTableExpr (RawSql -> AlterTableExpr) -> RawSql -> AlterTableExpr
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"ALTER TABLE "
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> Qualified TableName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Qualified TableName
tableName
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> RawSql
RawSql.space
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> RawSql -> NonEmpty AlterTableAction -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate RawSql
RawSql.commaSpace NonEmpty AlterTableAction
actions

{- |
Type to represent an action as part of an @ALTER TABLE@ statement. E.G.

> ADD COLUMN bar integer

'AlterTableAction' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.

@since 1.0.0.0
-}
newtype AlterTableAction
  = AlterTableAction RawSql.RawSql
  deriving (RawSql -> AlterTableAction
AlterTableAction -> RawSql
(AlterTableAction -> RawSql)
-> (RawSql -> AlterTableAction) -> SqlExpression AlterTableAction
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: AlterTableAction -> RawSql
toRawSql :: AlterTableAction -> RawSql
$cunsafeFromRawSql :: RawSql -> AlterTableAction
unsafeFromRawSql :: RawSql -> AlterTableAction
RawSql.SqlExpression)

{- |
  Constructs an 'AlterTableAction' that will add the specified column to the
  table.

  @since 1.0.0.0
-}
addColumn :: ColumnDefinition -> AlterTableAction
addColumn :: ColumnDefinition -> AlterTableAction
addColumn ColumnDefinition
columnDef =
  RawSql -> AlterTableAction
AlterTableAction (RawSql -> AlterTableAction) -> RawSql -> AlterTableAction
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"ADD COLUMN " RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> ColumnDefinition -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ColumnDefinition
columnDef

{- |
  Constructs an 'AlterTableAction' that will drop the specified column from the
  table.

  @since 1.0.0.0
-}
dropColumn :: ColumnName -> AlterTableAction
dropColumn :: ColumnName -> AlterTableAction
dropColumn ColumnName
columnName =
  RawSql -> AlterTableAction
AlterTableAction (RawSql -> AlterTableAction) -> RawSql -> AlterTableAction
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"DROP COLUMN " RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> ColumnName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ColumnName
columnName

{- |
  Constructs an 'AlterTableAction' that will add the specified constraint to the
  table.

  @since 1.0.0.0
-}
addConstraint :: TableConstraint -> AlterTableAction
addConstraint :: TableConstraint -> AlterTableAction
addConstraint TableConstraint
constraint =
  RawSql -> AlterTableAction
AlterTableAction (RawSql -> AlterTableAction) -> RawSql -> AlterTableAction
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"ADD " RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> TableConstraint -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql TableConstraint
constraint

{- |
  Constructs an 'AlterTableAction' that will drop the specified constraint from the
  table.

  @since 1.0.0.0
-}
dropConstraint :: ConstraintName -> AlterTableAction
dropConstraint :: ConstraintName -> AlterTableAction
dropConstraint ConstraintName
constraintName =
  RawSql -> AlterTableAction
AlterTableAction (RawSql -> AlterTableAction) -> RawSql -> AlterTableAction
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"DROP CONSTRAINT " RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> ConstraintName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ConstraintName
constraintName

{- |
  Constructs an 'AlterTableAction' that will alter the type of the specified
  column.

  @since 1.0.0.0
-}
alterColumnType ::
  -- | The name of the column whose type will be altered.
  ColumnName ->
  -- | The new type to use for the column.
  DataType ->
  -- | An optional 'UsingClause' to indicate to the database how data from the
  -- old type should be converted to the new type.
  Maybe UsingClause ->
  AlterTableAction
alterColumnType :: ColumnName -> DataType -> Maybe UsingClause -> AlterTableAction
alterColumnType ColumnName
columnName DataType
dataType Maybe UsingClause
maybeUsingClause =
  RawSql -> AlterTableAction
AlterTableAction (RawSql -> AlterTableAction) -> RawSql -> AlterTableAction
forall a b. (a -> b) -> a -> b
$
    RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate
      RawSql
RawSql.space
      ( String -> RawSql
RawSql.fromString String
"ALTER COLUMN"
          RawSql -> [RawSql] -> [RawSql]
forall a. a -> [a] -> [a]
: ColumnName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ColumnName
columnName
          RawSql -> [RawSql] -> [RawSql]
forall a. a -> [a] -> [a]
: String -> RawSql
RawSql.fromString String
"TYPE"
          RawSql -> [RawSql] -> [RawSql]
forall a. a -> [a] -> [a]
: DataType -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql DataType
dataType
          RawSql -> [RawSql] -> [RawSql]
forall a. a -> [a] -> [a]
: Maybe RawSql -> [RawSql]
forall a. Maybe a -> [a]
maybeToList ((UsingClause -> RawSql) -> Maybe UsingClause -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap UsingClause -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe UsingClause
maybeUsingClause)
      )

{- |
Type to represent a @USING@ clause as part of an @ALTER COLUMN@ when changing
the type of a column. E.G.

> USING id :: integer

'UsingClause' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.

@since 1.0.0.0
-}
newtype UsingClause
  = UsingClause RawSql.RawSql
  deriving (RawSql -> UsingClause
UsingClause -> RawSql
(UsingClause -> RawSql)
-> (RawSql -> UsingClause) -> SqlExpression UsingClause
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: UsingClause -> RawSql
toRawSql :: UsingClause -> RawSql
$cunsafeFromRawSql :: RawSql -> UsingClause
unsafeFromRawSql :: RawSql -> UsingClause
RawSql.SqlExpression)

{- |
  Constructs a 'UsingClause' that will cast the column to the specified type.

  @since 1.0.0.0
-}
usingCast :: ColumnName -> DataType -> UsingClause
usingCast :: ColumnName -> DataType -> UsingClause
usingCast ColumnName
columnName DataType
dataType =
  RawSql -> UsingClause
UsingClause (RawSql -> UsingClause) -> RawSql -> UsingClause
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"USING "
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> ColumnName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ColumnName
columnName
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> RawSql
RawSql.doubleColon
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> DataType -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql DataType
dataType

{- |
  Constructs an 'AlterTableAction' that will alter the nullability of the
  column.

  @since 1.0.0.0
-}
alterColumnNullability :: ColumnName -> AlterNotNull -> AlterTableAction
alterColumnNullability :: ColumnName -> AlterNotNull -> AlterTableAction
alterColumnNullability ColumnName
columnName AlterNotNull
alterNotNull =
  RawSql -> AlterTableAction
AlterTableAction (RawSql -> AlterTableAction) -> RawSql -> AlterTableAction
forall a b. (a -> b) -> a -> b
$
    RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate
      RawSql
RawSql.space
      [ String -> RawSql
RawSql.fromString String
"ALTER COLUMN"
      , ColumnName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ColumnName
columnName
      , AlterNotNull -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql AlterNotNull
alterNotNull
      ]

{- |
Type to represent an action to alter the nullability of a column. E.G.

> SET NOT NULL

'AlterNotNull' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.

@since 1.0.0.0
-}
newtype AlterNotNull
  = AlterNotNull RawSql.RawSql
  deriving (RawSql -> AlterNotNull
AlterNotNull -> RawSql
(AlterNotNull -> RawSql)
-> (RawSql -> AlterNotNull) -> SqlExpression AlterNotNull
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: AlterNotNull -> RawSql
toRawSql :: AlterNotNull -> RawSql
$cunsafeFromRawSql :: RawSql -> AlterNotNull
unsafeFromRawSql :: RawSql -> AlterNotNull
RawSql.SqlExpression)

{- |
  Sets the column to not null via @SET NOT NULL@.

  @since 1.0.0.0
-}
setNotNull :: AlterNotNull
setNotNull :: AlterNotNull
setNotNull =
  RawSql -> AlterNotNull
AlterNotNull (RawSql -> AlterNotNull) -> RawSql -> AlterNotNull
forall a b. (a -> b) -> a -> b
$ String -> RawSql
RawSql.fromString String
"SET NOT NULL"

{- |
  Sets the column to allow null via @DROP NOT NULL@.

  @since 1.0.0.0
-}
dropNotNull :: AlterNotNull
dropNotNull :: AlterNotNull
dropNotNull =
  RawSql -> AlterNotNull
AlterNotNull (RawSql -> AlterNotNull) -> RawSql -> AlterNotNull
forall a b. (a -> b) -> a -> b
$ String -> RawSql
RawSql.fromString String
"DROP NOT NULL"

{- |
  Constructs an 'AlterTableAction' that will use @DROP DEFAULT@ to drop the
  default value of the specified column.

  @since 1.0.0.0
-}
alterColumnDropDefault :: ColumnName -> AlterTableAction
alterColumnDropDefault :: ColumnName -> AlterTableAction
alterColumnDropDefault ColumnName
columnName =
  RawSql -> AlterTableAction
AlterTableAction (RawSql -> AlterTableAction) -> RawSql -> AlterTableAction
forall a b. (a -> b) -> a -> b
$
    RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate
      RawSql
RawSql.space
      [ String -> RawSql
RawSql.fromString String
"ALTER COLUMN"
      , ColumnName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ColumnName
columnName
      , String -> RawSql
RawSql.fromString String
"DROP DEFAULT"
      ]

{- |
  Constructs an 'AlterTableAction' that will use @SET DEFAULT@ to set the
  default value of the specified column.

  @since 1.0.0.0
-}
alterColumnSetDefault ::
  RawSql.SqlExpression valueExpression =>
  ColumnName ->
  valueExpression ->
  AlterTableAction
alterColumnSetDefault :: forall valueExpression.
SqlExpression valueExpression =>
ColumnName -> valueExpression -> AlterTableAction
alterColumnSetDefault ColumnName
columnName valueExpression
defaultValue =
  RawSql -> AlterTableAction
AlterTableAction (RawSql -> AlterTableAction) -> RawSql -> AlterTableAction
forall a b. (a -> b) -> a -> b
$
    RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate
      RawSql
RawSql.space
      [ String -> RawSql
RawSql.fromString String
"ALTER COLUMN"
      , ColumnName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql ColumnName
columnName
      , String -> RawSql
RawSql.fromString String
"SET DEFAULT"
      , valueExpression -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql valueExpression
defaultValue
      ]

{- |
Type to represent a @DROP TABLE@ statement. E.G.

> DROP TABLE FOO

'DropTableExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.

@since 1.0.0.0
-}
newtype DropTableExpr
  = DropTableExpr RawSql.RawSql
  deriving (RawSql -> DropTableExpr
DropTableExpr -> RawSql
(DropTableExpr -> RawSql)
-> (RawSql -> DropTableExpr) -> SqlExpression DropTableExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: DropTableExpr -> RawSql
toRawSql :: DropTableExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> DropTableExpr
unsafeFromRawSql :: RawSql -> DropTableExpr
RawSql.SqlExpression)

{- |
  Constructs a 'DropTableExpr' that will drop the specified table.

  @since 1.0.0.0
-}
dropTableExpr :: Maybe IfExists -> Qualified TableName -> DropTableExpr
dropTableExpr :: Maybe IfExists -> Qualified TableName -> DropTableExpr
dropTableExpr Maybe IfExists
maybeIfExists Qualified TableName
tableName =
  RawSql -> DropTableExpr
DropTableExpr (RawSql -> DropTableExpr) -> RawSql -> DropTableExpr
forall a b. (a -> b) -> a -> b
$
    RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate
      RawSql
RawSql.space
      ( [Maybe RawSql] -> [RawSql]
forall a. [Maybe a] -> [a]
catMaybes
          [ RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (String -> RawSql
RawSql.fromString String
"DROP TABLE")
          , (IfExists -> RawSql) -> Maybe IfExists -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IfExists -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe IfExists
maybeIfExists
          , RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (Qualified TableName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Qualified TableName
tableName)
          ]
      )