{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneDeriving #-}

module Database.Beam.AutoMigrate.Types where

import Control.DeepSeq
import Control.Exception
import Data.ByteString.Lazy (ByteString)
import Data.Map (Map)
import Data.Maybe (fromMaybe)
import Data.Set (Set)
import Data.String
import Data.String.Conv (toS)
import Data.Text (Text)
import qualified Data.Text as T
import Data.Typeable
import Database.Beam.Backend.SQL (BeamSqlBackendSyntax)
import qualified Database.Beam.Backend.SQL.AST as AST
import Database.Beam.Postgres (Pg, Postgres)
import qualified Database.Beam.Postgres.Syntax as Syntax
import GHC.Generics hiding (to)
import Numeric.Natural (Natural)
import Lens.Micro (Lens', lens, to, _Right)
import Lens.Micro.Extras (preview)

--
-- Types (sketched)
--

data Schema = Schema
  { Schema -> Tables
schemaTables :: Tables,
    Schema -> Enumerations
schemaEnumerations :: Enumerations,
    Schema -> Sequences
schemaSequences :: Sequences
  }
  deriving (Int -> Schema -> ShowS
[Schema] -> ShowS
Schema -> String
(Int -> Schema -> ShowS)
-> (Schema -> String) -> ([Schema] -> ShowS) -> Show Schema
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Schema] -> ShowS
$cshowList :: [Schema] -> ShowS
show :: Schema -> String
$cshow :: Schema -> String
showsPrec :: Int -> Schema -> ShowS
$cshowsPrec :: Int -> Schema -> ShowS
Show, Schema -> Schema -> Bool
(Schema -> Schema -> Bool)
-> (Schema -> Schema -> Bool) -> Eq Schema
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Schema -> Schema -> Bool
$c/= :: Schema -> Schema -> Bool
== :: Schema -> Schema -> Bool
$c== :: Schema -> Schema -> Bool
Eq, (forall x. Schema -> Rep Schema x)
-> (forall x. Rep Schema x -> Schema) -> Generic Schema
forall x. Rep Schema x -> Schema
forall x. Schema -> Rep Schema x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Schema x -> Schema
$cfrom :: forall x. Schema -> Rep Schema x
Generic)

instance NFData Schema

--
-- Enumerations
--

type Enumerations = Map EnumerationName Enumeration

newtype EnumerationName = EnumerationName
  { EnumerationName -> Text
enumName :: Text
  }
  deriving (Int -> EnumerationName -> ShowS
[EnumerationName] -> ShowS
EnumerationName -> String
(Int -> EnumerationName -> ShowS)
-> (EnumerationName -> String)
-> ([EnumerationName] -> ShowS)
-> Show EnumerationName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EnumerationName] -> ShowS
$cshowList :: [EnumerationName] -> ShowS
show :: EnumerationName -> String
$cshow :: EnumerationName -> String
showsPrec :: Int -> EnumerationName -> ShowS
$cshowsPrec :: Int -> EnumerationName -> ShowS
Show, EnumerationName -> EnumerationName -> Bool
(EnumerationName -> EnumerationName -> Bool)
-> (EnumerationName -> EnumerationName -> Bool)
-> Eq EnumerationName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EnumerationName -> EnumerationName -> Bool
$c/= :: EnumerationName -> EnumerationName -> Bool
== :: EnumerationName -> EnumerationName -> Bool
$c== :: EnumerationName -> EnumerationName -> Bool
Eq, Eq EnumerationName
Eq EnumerationName
-> (EnumerationName -> EnumerationName -> Ordering)
-> (EnumerationName -> EnumerationName -> Bool)
-> (EnumerationName -> EnumerationName -> Bool)
-> (EnumerationName -> EnumerationName -> Bool)
-> (EnumerationName -> EnumerationName -> Bool)
-> (EnumerationName -> EnumerationName -> EnumerationName)
-> (EnumerationName -> EnumerationName -> EnumerationName)
-> Ord EnumerationName
EnumerationName -> EnumerationName -> Bool
EnumerationName -> EnumerationName -> Ordering
EnumerationName -> EnumerationName -> EnumerationName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EnumerationName -> EnumerationName -> EnumerationName
$cmin :: EnumerationName -> EnumerationName -> EnumerationName
max :: EnumerationName -> EnumerationName -> EnumerationName
$cmax :: EnumerationName -> EnumerationName -> EnumerationName
>= :: EnumerationName -> EnumerationName -> Bool
$c>= :: EnumerationName -> EnumerationName -> Bool
> :: EnumerationName -> EnumerationName -> Bool
$c> :: EnumerationName -> EnumerationName -> Bool
<= :: EnumerationName -> EnumerationName -> Bool
$c<= :: EnumerationName -> EnumerationName -> Bool
< :: EnumerationName -> EnumerationName -> Bool
$c< :: EnumerationName -> EnumerationName -> Bool
compare :: EnumerationName -> EnumerationName -> Ordering
$ccompare :: EnumerationName -> EnumerationName -> Ordering
$cp1Ord :: Eq EnumerationName
Ord, (forall x. EnumerationName -> Rep EnumerationName x)
-> (forall x. Rep EnumerationName x -> EnumerationName)
-> Generic EnumerationName
forall x. Rep EnumerationName x -> EnumerationName
forall x. EnumerationName -> Rep EnumerationName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep EnumerationName x -> EnumerationName
$cfrom :: forall x. EnumerationName -> Rep EnumerationName x
Generic)

newtype Enumeration = Enumeration
  { Enumeration -> [Text]
enumValues :: [Text]
  }
  deriving (Int -> Enumeration -> ShowS
[Enumeration] -> ShowS
Enumeration -> String
(Int -> Enumeration -> ShowS)
-> (Enumeration -> String)
-> ([Enumeration] -> ShowS)
-> Show Enumeration
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Enumeration] -> ShowS
$cshowList :: [Enumeration] -> ShowS
show :: Enumeration -> String
$cshow :: Enumeration -> String
showsPrec :: Int -> Enumeration -> ShowS
$cshowsPrec :: Int -> Enumeration -> ShowS
Show, Enumeration -> Enumeration -> Bool
(Enumeration -> Enumeration -> Bool)
-> (Enumeration -> Enumeration -> Bool) -> Eq Enumeration
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Enumeration -> Enumeration -> Bool
$c/= :: Enumeration -> Enumeration -> Bool
== :: Enumeration -> Enumeration -> Bool
$c== :: Enumeration -> Enumeration -> Bool
Eq, Eq Enumeration
Eq Enumeration
-> (Enumeration -> Enumeration -> Ordering)
-> (Enumeration -> Enumeration -> Bool)
-> (Enumeration -> Enumeration -> Bool)
-> (Enumeration -> Enumeration -> Bool)
-> (Enumeration -> Enumeration -> Bool)
-> (Enumeration -> Enumeration -> Enumeration)
-> (Enumeration -> Enumeration -> Enumeration)
-> Ord Enumeration
Enumeration -> Enumeration -> Bool
Enumeration -> Enumeration -> Ordering
Enumeration -> Enumeration -> Enumeration
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Enumeration -> Enumeration -> Enumeration
$cmin :: Enumeration -> Enumeration -> Enumeration
max :: Enumeration -> Enumeration -> Enumeration
$cmax :: Enumeration -> Enumeration -> Enumeration
>= :: Enumeration -> Enumeration -> Bool
$c>= :: Enumeration -> Enumeration -> Bool
> :: Enumeration -> Enumeration -> Bool
$c> :: Enumeration -> Enumeration -> Bool
<= :: Enumeration -> Enumeration -> Bool
$c<= :: Enumeration -> Enumeration -> Bool
< :: Enumeration -> Enumeration -> Bool
$c< :: Enumeration -> Enumeration -> Bool
compare :: Enumeration -> Enumeration -> Ordering
$ccompare :: Enumeration -> Enumeration -> Ordering
$cp1Ord :: Eq Enumeration
Ord, (forall x. Enumeration -> Rep Enumeration x)
-> (forall x. Rep Enumeration x -> Enumeration)
-> Generic Enumeration
forall x. Rep Enumeration x -> Enumeration
forall x. Enumeration -> Rep Enumeration x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Enumeration x -> Enumeration
$cfrom :: forall x. Enumeration -> Rep Enumeration x
Generic)

instance NFData EnumerationName

instance NFData Enumeration

--
-- Sequences
--

type Sequences = Map SequenceName Sequence

newtype SequenceName = SequenceName
  { SequenceName -> Text
seqName :: Text
  }
  deriving (Int -> SequenceName -> ShowS
[SequenceName] -> ShowS
SequenceName -> String
(Int -> SequenceName -> ShowS)
-> (SequenceName -> String)
-> ([SequenceName] -> ShowS)
-> Show SequenceName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SequenceName] -> ShowS
$cshowList :: [SequenceName] -> ShowS
show :: SequenceName -> String
$cshow :: SequenceName -> String
showsPrec :: Int -> SequenceName -> ShowS
$cshowsPrec :: Int -> SequenceName -> ShowS
Show, SequenceName -> SequenceName -> Bool
(SequenceName -> SequenceName -> Bool)
-> (SequenceName -> SequenceName -> Bool) -> Eq SequenceName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SequenceName -> SequenceName -> Bool
$c/= :: SequenceName -> SequenceName -> Bool
== :: SequenceName -> SequenceName -> Bool
$c== :: SequenceName -> SequenceName -> Bool
Eq, Eq SequenceName
Eq SequenceName
-> (SequenceName -> SequenceName -> Ordering)
-> (SequenceName -> SequenceName -> Bool)
-> (SequenceName -> SequenceName -> Bool)
-> (SequenceName -> SequenceName -> Bool)
-> (SequenceName -> SequenceName -> Bool)
-> (SequenceName -> SequenceName -> SequenceName)
-> (SequenceName -> SequenceName -> SequenceName)
-> Ord SequenceName
SequenceName -> SequenceName -> Bool
SequenceName -> SequenceName -> Ordering
SequenceName -> SequenceName -> SequenceName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SequenceName -> SequenceName -> SequenceName
$cmin :: SequenceName -> SequenceName -> SequenceName
max :: SequenceName -> SequenceName -> SequenceName
$cmax :: SequenceName -> SequenceName -> SequenceName
>= :: SequenceName -> SequenceName -> Bool
$c>= :: SequenceName -> SequenceName -> Bool
> :: SequenceName -> SequenceName -> Bool
$c> :: SequenceName -> SequenceName -> Bool
<= :: SequenceName -> SequenceName -> Bool
$c<= :: SequenceName -> SequenceName -> Bool
< :: SequenceName -> SequenceName -> Bool
$c< :: SequenceName -> SequenceName -> Bool
compare :: SequenceName -> SequenceName -> Ordering
$ccompare :: SequenceName -> SequenceName -> Ordering
$cp1Ord :: Eq SequenceName
Ord, (forall x. SequenceName -> Rep SequenceName x)
-> (forall x. Rep SequenceName x -> SequenceName)
-> Generic SequenceName
forall x. Rep SequenceName x -> SequenceName
forall x. SequenceName -> Rep SequenceName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SequenceName x -> SequenceName
$cfrom :: forall x. SequenceName -> Rep SequenceName x
Generic)

-- For now this type is isomorphic to unit as we don't need to support anything other than plain
-- sequences.
data Sequence = Sequence
  { Sequence -> TableName
seqTable :: TableName,
    Sequence -> ColumnName
seqColumn :: ColumnName
  }
  deriving (Int -> Sequence -> ShowS
[Sequence] -> ShowS
Sequence -> String
(Int -> Sequence -> ShowS)
-> (Sequence -> String) -> ([Sequence] -> ShowS) -> Show Sequence
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Sequence] -> ShowS
$cshowList :: [Sequence] -> ShowS
show :: Sequence -> String
$cshow :: Sequence -> String
showsPrec :: Int -> Sequence -> ShowS
$cshowsPrec :: Int -> Sequence -> ShowS
Show, Sequence -> Sequence -> Bool
(Sequence -> Sequence -> Bool)
-> (Sequence -> Sequence -> Bool) -> Eq Sequence
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Sequence -> Sequence -> Bool
$c/= :: Sequence -> Sequence -> Bool
== :: Sequence -> Sequence -> Bool
$c== :: Sequence -> Sequence -> Bool
Eq, Eq Sequence
Eq Sequence
-> (Sequence -> Sequence -> Ordering)
-> (Sequence -> Sequence -> Bool)
-> (Sequence -> Sequence -> Bool)
-> (Sequence -> Sequence -> Bool)
-> (Sequence -> Sequence -> Bool)
-> (Sequence -> Sequence -> Sequence)
-> (Sequence -> Sequence -> Sequence)
-> Ord Sequence
Sequence -> Sequence -> Bool
Sequence -> Sequence -> Ordering
Sequence -> Sequence -> Sequence
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Sequence -> Sequence -> Sequence
$cmin :: Sequence -> Sequence -> Sequence
max :: Sequence -> Sequence -> Sequence
$cmax :: Sequence -> Sequence -> Sequence
>= :: Sequence -> Sequence -> Bool
$c>= :: Sequence -> Sequence -> Bool
> :: Sequence -> Sequence -> Bool
$c> :: Sequence -> Sequence -> Bool
<= :: Sequence -> Sequence -> Bool
$c<= :: Sequence -> Sequence -> Bool
< :: Sequence -> Sequence -> Bool
$c< :: Sequence -> Sequence -> Bool
compare :: Sequence -> Sequence -> Ordering
$ccompare :: Sequence -> Sequence -> Ordering
$cp1Ord :: Eq Sequence
Ord, (forall x. Sequence -> Rep Sequence x)
-> (forall x. Rep Sequence x -> Sequence) -> Generic Sequence
forall x. Rep Sequence x -> Sequence
forall x. Sequence -> Rep Sequence x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Sequence x -> Sequence
$cfrom :: forall x. Sequence -> Rep Sequence x
Generic)

instance NFData SequenceName

instance NFData Sequence

mkSequenceName :: TableName -> ColumnName -> SequenceName
mkSequenceName :: TableName -> ColumnName -> SequenceName
mkSequenceName TableName
tname ColumnName
cname = Text -> SequenceName
SequenceName (TableName -> Text
tableName TableName
tname Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"___" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ColumnName -> Text
columnName ColumnName
cname Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"___seq")

parseSequenceName :: SequenceName -> Maybe (TableName, ColumnName)
parseSequenceName :: SequenceName -> Maybe (TableName, ColumnName)
parseSequenceName (SequenceName Text
sName) = case Text -> Text -> [Text]
T.splitOn Text
"___" Text
sName of
  [Text
tName, Text
cName, Text
"seq"] -> (TableName, ColumnName) -> Maybe (TableName, ColumnName)
forall a. a -> Maybe a
Just (Text -> TableName
TableName Text
tName, Text -> ColumnName
ColumnName Text
cName)
  [Text]
_ -> Maybe (TableName, ColumnName)
forall a. Maybe a
Nothing

--
-- Tables
--

type Tables = Map TableName Table

newtype TableName = TableName
  { TableName -> Text
tableName :: Text
  }
  deriving (Int -> TableName -> ShowS
[TableName] -> ShowS
TableName -> String
(Int -> TableName -> ShowS)
-> (TableName -> String)
-> ([TableName] -> ShowS)
-> Show TableName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TableName] -> ShowS
$cshowList :: [TableName] -> ShowS
show :: TableName -> String
$cshow :: TableName -> String
showsPrec :: Int -> TableName -> ShowS
$cshowsPrec :: Int -> TableName -> ShowS
Show, TableName -> TableName -> Bool
(TableName -> TableName -> Bool)
-> (TableName -> TableName -> Bool) -> Eq TableName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TableName -> TableName -> Bool
$c/= :: TableName -> TableName -> Bool
== :: TableName -> TableName -> Bool
$c== :: TableName -> TableName -> Bool
Eq, Eq TableName
Eq TableName
-> (TableName -> TableName -> Ordering)
-> (TableName -> TableName -> Bool)
-> (TableName -> TableName -> Bool)
-> (TableName -> TableName -> Bool)
-> (TableName -> TableName -> Bool)
-> (TableName -> TableName -> TableName)
-> (TableName -> TableName -> TableName)
-> Ord TableName
TableName -> TableName -> Bool
TableName -> TableName -> Ordering
TableName -> TableName -> TableName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TableName -> TableName -> TableName
$cmin :: TableName -> TableName -> TableName
max :: TableName -> TableName -> TableName
$cmax :: TableName -> TableName -> TableName
>= :: TableName -> TableName -> Bool
$c>= :: TableName -> TableName -> Bool
> :: TableName -> TableName -> Bool
$c> :: TableName -> TableName -> Bool
<= :: TableName -> TableName -> Bool
$c<= :: TableName -> TableName -> Bool
< :: TableName -> TableName -> Bool
$c< :: TableName -> TableName -> Bool
compare :: TableName -> TableName -> Ordering
$ccompare :: TableName -> TableName -> Ordering
$cp1Ord :: Eq TableName
Ord, TableName -> ()
(TableName -> ()) -> NFData TableName
forall a. (a -> ()) -> NFData a
rnf :: TableName -> ()
$crnf :: TableName -> ()
NFData, (forall x. TableName -> Rep TableName x)
-> (forall x. Rep TableName x -> TableName) -> Generic TableName
forall x. Rep TableName x -> TableName
forall x. TableName -> Rep TableName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TableName x -> TableName
$cfrom :: forall x. TableName -> Rep TableName x
Generic)

instance IsString TableName where
  fromString :: String -> TableName
fromString = Text -> TableName
TableName (Text -> TableName) -> (String -> Text) -> String -> TableName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

data Table = Table
  { Table -> Set TableConstraint
tableConstraints :: Set TableConstraint,
    Table -> Columns
tableColumns :: Columns
  }
  deriving (Table -> Table -> Bool
(Table -> Table -> Bool) -> (Table -> Table -> Bool) -> Eq Table
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Table -> Table -> Bool
$c/= :: Table -> Table -> Bool
== :: Table -> Table -> Bool
$c== :: Table -> Table -> Bool
Eq, Int -> Table -> ShowS
[Table] -> ShowS
Table -> String
(Int -> Table -> ShowS)
-> (Table -> String) -> ([Table] -> ShowS) -> Show Table
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Table] -> ShowS
$cshowList :: [Table] -> ShowS
show :: Table -> String
$cshow :: Table -> String
showsPrec :: Int -> Table -> ShowS
$cshowsPrec :: Int -> Table -> ShowS
Show, (forall x. Table -> Rep Table x)
-> (forall x. Rep Table x -> Table) -> Generic Table
forall x. Rep Table x -> Table
forall x. Table -> Rep Table x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Table x -> Table
$cfrom :: forall x. Table -> Rep Table x
Generic)

instance NFData Table

type Columns = Map ColumnName Column

newtype ColumnName = ColumnName
  { ColumnName -> Text
columnName :: Text
  }
  deriving (Int -> ColumnName -> ShowS
[ColumnName] -> ShowS
ColumnName -> String
(Int -> ColumnName -> ShowS)
-> (ColumnName -> String)
-> ([ColumnName] -> ShowS)
-> Show ColumnName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ColumnName] -> ShowS
$cshowList :: [ColumnName] -> ShowS
show :: ColumnName -> String
$cshow :: ColumnName -> String
showsPrec :: Int -> ColumnName -> ShowS
$cshowsPrec :: Int -> ColumnName -> ShowS
Show, ColumnName -> ColumnName -> Bool
(ColumnName -> ColumnName -> Bool)
-> (ColumnName -> ColumnName -> Bool) -> Eq ColumnName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ColumnName -> ColumnName -> Bool
$c/= :: ColumnName -> ColumnName -> Bool
== :: ColumnName -> ColumnName -> Bool
$c== :: ColumnName -> ColumnName -> Bool
Eq, Eq ColumnName
Eq ColumnName
-> (ColumnName -> ColumnName -> Ordering)
-> (ColumnName -> ColumnName -> Bool)
-> (ColumnName -> ColumnName -> Bool)
-> (ColumnName -> ColumnName -> Bool)
-> (ColumnName -> ColumnName -> Bool)
-> (ColumnName -> ColumnName -> ColumnName)
-> (ColumnName -> ColumnName -> ColumnName)
-> Ord ColumnName
ColumnName -> ColumnName -> Bool
ColumnName -> ColumnName -> Ordering
ColumnName -> ColumnName -> ColumnName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ColumnName -> ColumnName -> ColumnName
$cmin :: ColumnName -> ColumnName -> ColumnName
max :: ColumnName -> ColumnName -> ColumnName
$cmax :: ColumnName -> ColumnName -> ColumnName
>= :: ColumnName -> ColumnName -> Bool
$c>= :: ColumnName -> ColumnName -> Bool
> :: ColumnName -> ColumnName -> Bool
$c> :: ColumnName -> ColumnName -> Bool
<= :: ColumnName -> ColumnName -> Bool
$c<= :: ColumnName -> ColumnName -> Bool
< :: ColumnName -> ColumnName -> Bool
$c< :: ColumnName -> ColumnName -> Bool
compare :: ColumnName -> ColumnName -> Ordering
$ccompare :: ColumnName -> ColumnName -> Ordering
$cp1Ord :: Eq ColumnName
Ord, ColumnName -> ()
(ColumnName -> ()) -> NFData ColumnName
forall a. (a -> ()) -> NFData a
rnf :: ColumnName -> ()
$crnf :: ColumnName -> ()
NFData, (forall x. ColumnName -> Rep ColumnName x)
-> (forall x. Rep ColumnName x -> ColumnName) -> Generic ColumnName
forall x. Rep ColumnName x -> ColumnName
forall x. ColumnName -> Rep ColumnName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ColumnName x -> ColumnName
$cfrom :: forall x. ColumnName -> Rep ColumnName x
Generic)

instance IsString ColumnName where
  fromString :: String -> ColumnName
fromString = Text -> ColumnName
ColumnName (Text -> ColumnName) -> (String -> Text) -> String -> ColumnName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

data Column = Column
  { Column -> ColumnType
columnType :: ColumnType,
    Column -> Set ColumnConstraint
columnConstraints :: Set ColumnConstraint
  }
  deriving (Int -> Column -> ShowS
[Column] -> ShowS
Column -> String
(Int -> Column -> ShowS)
-> (Column -> String) -> ([Column] -> ShowS) -> Show Column
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Column] -> ShowS
$cshowList :: [Column] -> ShowS
show :: Column -> String
$cshow :: Column -> String
showsPrec :: Int -> Column -> ShowS
$cshowsPrec :: Int -> Column -> ShowS
Show, Column -> Column -> Bool
(Column -> Column -> Bool)
-> (Column -> Column -> Bool) -> Eq Column
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Column -> Column -> Bool
$c/= :: Column -> Column -> Bool
== :: Column -> Column -> Bool
$c== :: Column -> Column -> Bool
Eq, (forall x. Column -> Rep Column x)
-> (forall x. Rep Column x -> Column) -> Generic Column
forall x. Rep Column x -> Column
forall x. Column -> Rep Column x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Column x -> Column
$cfrom :: forall x. Column -> Rep Column x
Generic)

-- Manual instance as 'AST.DataType' doesn't derive 'NFData'.
instance NFData Column where
  rnf :: Column -> ()
rnf Column
c = Set ColumnConstraint -> ()
forall a. NFData a => a -> ()
rnf (Column -> Set ColumnConstraint
columnConstraints Column
c)

-- | Basic types for columns. We piggyback on 'beam-core' SQL types for now. Albeit they are a bit more
-- specialised (i.e, SQL specific), we are less subject from their and our representation to diverge.
data ColumnType
  = -- | Standard SQL types.
    SqlStdType AST.DataType
  | -- | Postgres specific types.
    PgSpecificType PgDataType
  | -- | An enumeration implemented with text-based encoding.
    DbEnumeration EnumerationName Enumeration
  | -- | Array type.
    SqlArrayType ColumnType Word
  deriving (Int -> ColumnType -> ShowS
[ColumnType] -> ShowS
ColumnType -> String
(Int -> ColumnType -> ShowS)
-> (ColumnType -> String)
-> ([ColumnType] -> ShowS)
-> Show ColumnType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ColumnType] -> ShowS
$cshowList :: [ColumnType] -> ShowS
show :: ColumnType -> String
$cshow :: ColumnType -> String
showsPrec :: Int -> ColumnType -> ShowS
$cshowsPrec :: Int -> ColumnType -> ShowS
Show, ColumnType -> ColumnType -> Bool
(ColumnType -> ColumnType -> Bool)
-> (ColumnType -> ColumnType -> Bool) -> Eq ColumnType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ColumnType -> ColumnType -> Bool
$c/= :: ColumnType -> ColumnType -> Bool
== :: ColumnType -> ColumnType -> Bool
$c== :: ColumnType -> ColumnType -> Bool
Eq, (forall x. ColumnType -> Rep ColumnType x)
-> (forall x. Rep ColumnType x -> ColumnType) -> Generic ColumnType
forall x. Rep ColumnType x -> ColumnType
forall x. ColumnType -> Rep ColumnType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ColumnType x -> ColumnType
$cfrom :: forall x. ColumnType -> Rep ColumnType x
Generic)

data PgDataType
  = PgJson
  | PgJsonB
  | PgRangeInt4
  | PgRangeInt8
  | PgRangeNum
  | PgRangeTs
  | PgRangeTsTz
  | PgRangeDate
  | PgUuid
  | PgEnumeration EnumerationName
  | PgOid
  | PgLTree
  | PgVector (Maybe Natural)

deriving instance Show PgDataType

deriving instance Eq PgDataType

deriving instance Generic PgDataType

newtype ExtensionTypeName = ExtensionTypeName
  { ExtensionTypeName -> Text
extensionTypeName :: Text
  }
  deriving (Int -> ExtensionTypeName -> ShowS
[ExtensionTypeName] -> ShowS
ExtensionTypeName -> String
(Int -> ExtensionTypeName -> ShowS)
-> (ExtensionTypeName -> String)
-> ([ExtensionTypeName] -> ShowS)
-> Show ExtensionTypeName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExtensionTypeName] -> ShowS
$cshowList :: [ExtensionTypeName] -> ShowS
show :: ExtensionTypeName -> String
$cshow :: ExtensionTypeName -> String
showsPrec :: Int -> ExtensionTypeName -> ShowS
$cshowsPrec :: Int -> ExtensionTypeName -> ShowS
Show, ExtensionTypeName -> ExtensionTypeName -> Bool
(ExtensionTypeName -> ExtensionTypeName -> Bool)
-> (ExtensionTypeName -> ExtensionTypeName -> Bool)
-> Eq ExtensionTypeName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtensionTypeName -> ExtensionTypeName -> Bool
$c/= :: ExtensionTypeName -> ExtensionTypeName -> Bool
== :: ExtensionTypeName -> ExtensionTypeName -> Bool
$c== :: ExtensionTypeName -> ExtensionTypeName -> Bool
Eq, Eq ExtensionTypeName
Eq ExtensionTypeName
-> (ExtensionTypeName -> ExtensionTypeName -> Ordering)
-> (ExtensionTypeName -> ExtensionTypeName -> Bool)
-> (ExtensionTypeName -> ExtensionTypeName -> Bool)
-> (ExtensionTypeName -> ExtensionTypeName -> Bool)
-> (ExtensionTypeName -> ExtensionTypeName -> Bool)
-> (ExtensionTypeName -> ExtensionTypeName -> ExtensionTypeName)
-> (ExtensionTypeName -> ExtensionTypeName -> ExtensionTypeName)
-> Ord ExtensionTypeName
ExtensionTypeName -> ExtensionTypeName -> Bool
ExtensionTypeName -> ExtensionTypeName -> Ordering
ExtensionTypeName -> ExtensionTypeName -> ExtensionTypeName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ExtensionTypeName -> ExtensionTypeName -> ExtensionTypeName
$cmin :: ExtensionTypeName -> ExtensionTypeName -> ExtensionTypeName
max :: ExtensionTypeName -> ExtensionTypeName -> ExtensionTypeName
$cmax :: ExtensionTypeName -> ExtensionTypeName -> ExtensionTypeName
>= :: ExtensionTypeName -> ExtensionTypeName -> Bool
$c>= :: ExtensionTypeName -> ExtensionTypeName -> Bool
> :: ExtensionTypeName -> ExtensionTypeName -> Bool
$c> :: ExtensionTypeName -> ExtensionTypeName -> Bool
<= :: ExtensionTypeName -> ExtensionTypeName -> Bool
$c<= :: ExtensionTypeName -> ExtensionTypeName -> Bool
< :: ExtensionTypeName -> ExtensionTypeName -> Bool
$c< :: ExtensionTypeName -> ExtensionTypeName -> Bool
compare :: ExtensionTypeName -> ExtensionTypeName -> Ordering
$ccompare :: ExtensionTypeName -> ExtensionTypeName -> Ordering
$cp1Ord :: Eq ExtensionTypeName
Ord, ExtensionTypeName -> ()
(ExtensionTypeName -> ()) -> NFData ExtensionTypeName
forall a. (a -> ()) -> NFData a
rnf :: ExtensionTypeName -> ()
$crnf :: ExtensionTypeName -> ()
NFData, (forall x. ExtensionTypeName -> Rep ExtensionTypeName x)
-> (forall x. Rep ExtensionTypeName x -> ExtensionTypeName)
-> Generic ExtensionTypeName
forall x. Rep ExtensionTypeName x -> ExtensionTypeName
forall x. ExtensionTypeName -> Rep ExtensionTypeName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ExtensionTypeName x -> ExtensionTypeName
$cfrom :: forall x. ExtensionTypeName -> Rep ExtensionTypeName x
Generic)

instance IsString ExtensionTypeName where
  fromString :: String -> ExtensionTypeName
fromString = Text -> ExtensionTypeName
ExtensionTypeName (Text -> ExtensionTypeName)
-> (String -> Text) -> String -> ExtensionTypeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

-- Newtype wrapper to be able to derive appropriate 'HasDefaultSqlDataType' for /Postgres/ enum types.
newtype PgEnum a
  = PgEnum a
  deriving (Int -> PgEnum a -> ShowS
[PgEnum a] -> ShowS
PgEnum a -> String
(Int -> PgEnum a -> ShowS)
-> (PgEnum a -> String) -> ([PgEnum a] -> ShowS) -> Show (PgEnum a)
forall a. Show a => Int -> PgEnum a -> ShowS
forall a. Show a => [PgEnum a] -> ShowS
forall a. Show a => PgEnum a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgEnum a] -> ShowS
$cshowList :: forall a. Show a => [PgEnum a] -> ShowS
show :: PgEnum a -> String
$cshow :: forall a. Show a => PgEnum a -> String
showsPrec :: Int -> PgEnum a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> PgEnum a -> ShowS
Show, PgEnum a -> PgEnum a -> Bool
(PgEnum a -> PgEnum a -> Bool)
-> (PgEnum a -> PgEnum a -> Bool) -> Eq (PgEnum a)
forall a. Eq a => PgEnum a -> PgEnum a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgEnum a -> PgEnum a -> Bool
$c/= :: forall a. Eq a => PgEnum a -> PgEnum a -> Bool
== :: PgEnum a -> PgEnum a -> Bool
$c== :: forall a. Eq a => PgEnum a -> PgEnum a -> Bool
Eq, Typeable, Int -> PgEnum a
PgEnum a -> Int
PgEnum a -> [PgEnum a]
PgEnum a -> PgEnum a
PgEnum a -> PgEnum a -> [PgEnum a]
PgEnum a -> PgEnum a -> PgEnum a -> [PgEnum a]
(PgEnum a -> PgEnum a)
-> (PgEnum a -> PgEnum a)
-> (Int -> PgEnum a)
-> (PgEnum a -> Int)
-> (PgEnum a -> [PgEnum a])
-> (PgEnum a -> PgEnum a -> [PgEnum a])
-> (PgEnum a -> PgEnum a -> [PgEnum a])
-> (PgEnum a -> PgEnum a -> PgEnum a -> [PgEnum a])
-> Enum (PgEnum a)
forall a. Enum a => Int -> PgEnum a
forall a. Enum a => PgEnum a -> Int
forall a. Enum a => PgEnum a -> [PgEnum a]
forall a. Enum a => PgEnum a -> PgEnum a
forall a. Enum a => PgEnum a -> PgEnum a -> [PgEnum a]
forall a. Enum a => PgEnum a -> PgEnum a -> PgEnum a -> [PgEnum a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PgEnum a -> PgEnum a -> PgEnum a -> [PgEnum a]
$cenumFromThenTo :: forall a. Enum a => PgEnum a -> PgEnum a -> PgEnum a -> [PgEnum a]
enumFromTo :: PgEnum a -> PgEnum a -> [PgEnum a]
$cenumFromTo :: forall a. Enum a => PgEnum a -> PgEnum a -> [PgEnum a]
enumFromThen :: PgEnum a -> PgEnum a -> [PgEnum a]
$cenumFromThen :: forall a. Enum a => PgEnum a -> PgEnum a -> [PgEnum a]
enumFrom :: PgEnum a -> [PgEnum a]
$cenumFrom :: forall a. Enum a => PgEnum a -> [PgEnum a]
fromEnum :: PgEnum a -> Int
$cfromEnum :: forall a. Enum a => PgEnum a -> Int
toEnum :: Int -> PgEnum a
$ctoEnum :: forall a. Enum a => Int -> PgEnum a
pred :: PgEnum a -> PgEnum a
$cpred :: forall a. Enum a => PgEnum a -> PgEnum a
succ :: PgEnum a -> PgEnum a
$csucc :: forall a. Enum a => PgEnum a -> PgEnum a
Enum, PgEnum a
PgEnum a -> PgEnum a -> Bounded (PgEnum a)
forall a. a -> a -> Bounded a
forall a. Bounded a => PgEnum a
maxBound :: PgEnum a
$cmaxBound :: forall a. Bounded a => PgEnum a
minBound :: PgEnum a
$cminBound :: forall a. Bounded a => PgEnum a
Bounded, (forall x. PgEnum a -> Rep (PgEnum a) x)
-> (forall x. Rep (PgEnum a) x -> PgEnum a) -> Generic (PgEnum a)
forall x. Rep (PgEnum a) x -> PgEnum a
forall x. PgEnum a -> Rep (PgEnum a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (PgEnum a) x -> PgEnum a
forall a x. PgEnum a -> Rep (PgEnum a) x
$cto :: forall a x. Rep (PgEnum a) x -> PgEnum a
$cfrom :: forall a x. PgEnum a -> Rep (PgEnum a) x
Generic)

-- Newtype wrapper to be able to derive appropriate 'HasDefaultSqlDataType' for /textual/ enum types.
newtype DbEnum a
  = DbEnum a
  deriving (Int -> DbEnum a -> ShowS
[DbEnum a] -> ShowS
DbEnum a -> String
(Int -> DbEnum a -> ShowS)
-> (DbEnum a -> String) -> ([DbEnum a] -> ShowS) -> Show (DbEnum a)
forall a. Show a => Int -> DbEnum a -> ShowS
forall a. Show a => [DbEnum a] -> ShowS
forall a. Show a => DbEnum a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DbEnum a] -> ShowS
$cshowList :: forall a. Show a => [DbEnum a] -> ShowS
show :: DbEnum a -> String
$cshow :: forall a. Show a => DbEnum a -> String
showsPrec :: Int -> DbEnum a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> DbEnum a -> ShowS
Show, DbEnum a -> DbEnum a -> Bool
(DbEnum a -> DbEnum a -> Bool)
-> (DbEnum a -> DbEnum a -> Bool) -> Eq (DbEnum a)
forall a. Eq a => DbEnum a -> DbEnum a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DbEnum a -> DbEnum a -> Bool
$c/= :: forall a. Eq a => DbEnum a -> DbEnum a -> Bool
== :: DbEnum a -> DbEnum a -> Bool
$c== :: forall a. Eq a => DbEnum a -> DbEnum a -> Bool
Eq, Typeable, Int -> DbEnum a
DbEnum a -> Int
DbEnum a -> [DbEnum a]
DbEnum a -> DbEnum a
DbEnum a -> DbEnum a -> [DbEnum a]
DbEnum a -> DbEnum a -> DbEnum a -> [DbEnum a]
(DbEnum a -> DbEnum a)
-> (DbEnum a -> DbEnum a)
-> (Int -> DbEnum a)
-> (DbEnum a -> Int)
-> (DbEnum a -> [DbEnum a])
-> (DbEnum a -> DbEnum a -> [DbEnum a])
-> (DbEnum a -> DbEnum a -> [DbEnum a])
-> (DbEnum a -> DbEnum a -> DbEnum a -> [DbEnum a])
-> Enum (DbEnum a)
forall a. Enum a => Int -> DbEnum a
forall a. Enum a => DbEnum a -> Int
forall a. Enum a => DbEnum a -> [DbEnum a]
forall a. Enum a => DbEnum a -> DbEnum a
forall a. Enum a => DbEnum a -> DbEnum a -> [DbEnum a]
forall a. Enum a => DbEnum a -> DbEnum a -> DbEnum a -> [DbEnum a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: DbEnum a -> DbEnum a -> DbEnum a -> [DbEnum a]
$cenumFromThenTo :: forall a. Enum a => DbEnum a -> DbEnum a -> DbEnum a -> [DbEnum a]
enumFromTo :: DbEnum a -> DbEnum a -> [DbEnum a]
$cenumFromTo :: forall a. Enum a => DbEnum a -> DbEnum a -> [DbEnum a]
enumFromThen :: DbEnum a -> DbEnum a -> [DbEnum a]
$cenumFromThen :: forall a. Enum a => DbEnum a -> DbEnum a -> [DbEnum a]
enumFrom :: DbEnum a -> [DbEnum a]
$cenumFrom :: forall a. Enum a => DbEnum a -> [DbEnum a]
fromEnum :: DbEnum a -> Int
$cfromEnum :: forall a. Enum a => DbEnum a -> Int
toEnum :: Int -> DbEnum a
$ctoEnum :: forall a. Enum a => Int -> DbEnum a
pred :: DbEnum a -> DbEnum a
$cpred :: forall a. Enum a => DbEnum a -> DbEnum a
succ :: DbEnum a -> DbEnum a
$csucc :: forall a. Enum a => DbEnum a -> DbEnum a
Enum, DbEnum a
DbEnum a -> DbEnum a -> Bounded (DbEnum a)
forall a. a -> a -> Bounded a
forall a. Bounded a => DbEnum a
maxBound :: DbEnum a
$cmaxBound :: forall a. Bounded a => DbEnum a
minBound :: DbEnum a
$cminBound :: forall a. Bounded a => DbEnum a
Bounded, (forall x. DbEnum a -> Rep (DbEnum a) x)
-> (forall x. Rep (DbEnum a) x -> DbEnum a) -> Generic (DbEnum a)
forall x. Rep (DbEnum a) x -> DbEnum a
forall x. DbEnum a -> Rep (DbEnum a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (DbEnum a) x -> DbEnum a
forall a x. DbEnum a -> Rep (DbEnum a) x
$cto :: forall a x. Rep (DbEnum a) x -> DbEnum a
$cfrom :: forall a x. DbEnum a -> Rep (DbEnum a) x
Generic)

instance Semigroup Table where
  (Table Set TableConstraint
c1 Columns
t1) <> :: Table -> Table -> Table
<> (Table Set TableConstraint
c2 Columns
t2) = Set TableConstraint -> Columns -> Table
Table (Set TableConstraint
c1 Set TableConstraint -> Set TableConstraint -> Set TableConstraint
forall a. Semigroup a => a -> a -> a
<> Set TableConstraint
c2) (Columns
t1 Columns -> Columns -> Columns
forall a. Semigroup a => a -> a -> a
<> Columns
t2)

instance Monoid Table where
  mempty :: Table
mempty = Set TableConstraint -> Columns -> Table
Table Set TableConstraint
forall a. Monoid a => a
mempty Columns
forall a. Monoid a => a
mempty

type ConstraintName = Text

data TableConstraint
  = -- | This set of 'Column's identifies the Table's 'PrimaryKey'.
    PrimaryKey ConstraintName (Set ColumnName)
  | -- | This set of 'Column's identifies a Table's 'ForeignKey'. This is usually found in the 'tableConstraints'
    -- of the table where the foreign key is actually defined (in terms of 'REFERENCES').
    -- The set stores a (fk_column, pk_column) correspondence.
    ForeignKey ConstraintName TableName (Set (ColumnName, ColumnName)) ReferenceAction {- onDelete -} ReferenceAction {- onUpdate -}
  | Unique ConstraintName (Set ColumnName)
  deriving (Int -> TableConstraint -> ShowS
[TableConstraint] -> ShowS
TableConstraint -> String
(Int -> TableConstraint -> ShowS)
-> (TableConstraint -> String)
-> ([TableConstraint] -> ShowS)
-> Show TableConstraint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TableConstraint] -> ShowS
$cshowList :: [TableConstraint] -> ShowS
show :: TableConstraint -> String
$cshow :: TableConstraint -> String
showsPrec :: Int -> TableConstraint -> ShowS
$cshowsPrec :: Int -> TableConstraint -> ShowS
Show, TableConstraint -> TableConstraint -> Bool
(TableConstraint -> TableConstraint -> Bool)
-> (TableConstraint -> TableConstraint -> Bool)
-> Eq TableConstraint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TableConstraint -> TableConstraint -> Bool
$c/= :: TableConstraint -> TableConstraint -> Bool
== :: TableConstraint -> TableConstraint -> Bool
$c== :: TableConstraint -> TableConstraint -> Bool
Eq, Eq TableConstraint
Eq TableConstraint
-> (TableConstraint -> TableConstraint -> Ordering)
-> (TableConstraint -> TableConstraint -> Bool)
-> (TableConstraint -> TableConstraint -> Bool)
-> (TableConstraint -> TableConstraint -> Bool)
-> (TableConstraint -> TableConstraint -> Bool)
-> (TableConstraint -> TableConstraint -> TableConstraint)
-> (TableConstraint -> TableConstraint -> TableConstraint)
-> Ord TableConstraint
TableConstraint -> TableConstraint -> Bool
TableConstraint -> TableConstraint -> Ordering
TableConstraint -> TableConstraint -> TableConstraint
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TableConstraint -> TableConstraint -> TableConstraint
$cmin :: TableConstraint -> TableConstraint -> TableConstraint
max :: TableConstraint -> TableConstraint -> TableConstraint
$cmax :: TableConstraint -> TableConstraint -> TableConstraint
>= :: TableConstraint -> TableConstraint -> Bool
$c>= :: TableConstraint -> TableConstraint -> Bool
> :: TableConstraint -> TableConstraint -> Bool
$c> :: TableConstraint -> TableConstraint -> Bool
<= :: TableConstraint -> TableConstraint -> Bool
$c<= :: TableConstraint -> TableConstraint -> Bool
< :: TableConstraint -> TableConstraint -> Bool
$c< :: TableConstraint -> TableConstraint -> Bool
compare :: TableConstraint -> TableConstraint -> Ordering
$ccompare :: TableConstraint -> TableConstraint -> Ordering
$cp1Ord :: Eq TableConstraint
Ord, (forall x. TableConstraint -> Rep TableConstraint x)
-> (forall x. Rep TableConstraint x -> TableConstraint)
-> Generic TableConstraint
forall x. Rep TableConstraint x -> TableConstraint
forall x. TableConstraint -> Rep TableConstraint x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TableConstraint x -> TableConstraint
$cfrom :: forall x. TableConstraint -> Rep TableConstraint x
Generic)

instance NFData TableConstraint

data ColumnConstraint
  = NotNull
  | Default Text {- the actual default -}
  deriving (Int -> ColumnConstraint -> ShowS
[ColumnConstraint] -> ShowS
ColumnConstraint -> String
(Int -> ColumnConstraint -> ShowS)
-> (ColumnConstraint -> String)
-> ([ColumnConstraint] -> ShowS)
-> Show ColumnConstraint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ColumnConstraint] -> ShowS
$cshowList :: [ColumnConstraint] -> ShowS
show :: ColumnConstraint -> String
$cshow :: ColumnConstraint -> String
showsPrec :: Int -> ColumnConstraint -> ShowS
$cshowsPrec :: Int -> ColumnConstraint -> ShowS
Show, ColumnConstraint -> ColumnConstraint -> Bool
(ColumnConstraint -> ColumnConstraint -> Bool)
-> (ColumnConstraint -> ColumnConstraint -> Bool)
-> Eq ColumnConstraint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ColumnConstraint -> ColumnConstraint -> Bool
$c/= :: ColumnConstraint -> ColumnConstraint -> Bool
== :: ColumnConstraint -> ColumnConstraint -> Bool
$c== :: ColumnConstraint -> ColumnConstraint -> Bool
Eq, Eq ColumnConstraint
Eq ColumnConstraint
-> (ColumnConstraint -> ColumnConstraint -> Ordering)
-> (ColumnConstraint -> ColumnConstraint -> Bool)
-> (ColumnConstraint -> ColumnConstraint -> Bool)
-> (ColumnConstraint -> ColumnConstraint -> Bool)
-> (ColumnConstraint -> ColumnConstraint -> Bool)
-> (ColumnConstraint -> ColumnConstraint -> ColumnConstraint)
-> (ColumnConstraint -> ColumnConstraint -> ColumnConstraint)
-> Ord ColumnConstraint
ColumnConstraint -> ColumnConstraint -> Bool
ColumnConstraint -> ColumnConstraint -> Ordering
ColumnConstraint -> ColumnConstraint -> ColumnConstraint
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ColumnConstraint -> ColumnConstraint -> ColumnConstraint
$cmin :: ColumnConstraint -> ColumnConstraint -> ColumnConstraint
max :: ColumnConstraint -> ColumnConstraint -> ColumnConstraint
$cmax :: ColumnConstraint -> ColumnConstraint -> ColumnConstraint
>= :: ColumnConstraint -> ColumnConstraint -> Bool
$c>= :: ColumnConstraint -> ColumnConstraint -> Bool
> :: ColumnConstraint -> ColumnConstraint -> Bool
$c> :: ColumnConstraint -> ColumnConstraint -> Bool
<= :: ColumnConstraint -> ColumnConstraint -> Bool
$c<= :: ColumnConstraint -> ColumnConstraint -> Bool
< :: ColumnConstraint -> ColumnConstraint -> Bool
$c< :: ColumnConstraint -> ColumnConstraint -> Bool
compare :: ColumnConstraint -> ColumnConstraint -> Ordering
$ccompare :: ColumnConstraint -> ColumnConstraint -> Ordering
$cp1Ord :: Eq ColumnConstraint
Ord, (forall x. ColumnConstraint -> Rep ColumnConstraint x)
-> (forall x. Rep ColumnConstraint x -> ColumnConstraint)
-> Generic ColumnConstraint
forall x. Rep ColumnConstraint x -> ColumnConstraint
forall x. ColumnConstraint -> Rep ColumnConstraint x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ColumnConstraint x -> ColumnConstraint
$cfrom :: forall x. ColumnConstraint -> Rep ColumnConstraint x
Generic)

instance NFData ColumnConstraint

data ReferenceAction
  = NoAction
  | Restrict
  | Cascade
  | SetNull
  | SetDefault
  deriving (Int -> ReferenceAction -> ShowS
[ReferenceAction] -> ShowS
ReferenceAction -> String
(Int -> ReferenceAction -> ShowS)
-> (ReferenceAction -> String)
-> ([ReferenceAction] -> ShowS)
-> Show ReferenceAction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ReferenceAction] -> ShowS
$cshowList :: [ReferenceAction] -> ShowS
show :: ReferenceAction -> String
$cshow :: ReferenceAction -> String
showsPrec :: Int -> ReferenceAction -> ShowS
$cshowsPrec :: Int -> ReferenceAction -> ShowS
Show, ReferenceAction -> ReferenceAction -> Bool
(ReferenceAction -> ReferenceAction -> Bool)
-> (ReferenceAction -> ReferenceAction -> Bool)
-> Eq ReferenceAction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReferenceAction -> ReferenceAction -> Bool
$c/= :: ReferenceAction -> ReferenceAction -> Bool
== :: ReferenceAction -> ReferenceAction -> Bool
$c== :: ReferenceAction -> ReferenceAction -> Bool
Eq, Eq ReferenceAction
Eq ReferenceAction
-> (ReferenceAction -> ReferenceAction -> Ordering)
-> (ReferenceAction -> ReferenceAction -> Bool)
-> (ReferenceAction -> ReferenceAction -> Bool)
-> (ReferenceAction -> ReferenceAction -> Bool)
-> (ReferenceAction -> ReferenceAction -> Bool)
-> (ReferenceAction -> ReferenceAction -> ReferenceAction)
-> (ReferenceAction -> ReferenceAction -> ReferenceAction)
-> Ord ReferenceAction
ReferenceAction -> ReferenceAction -> Bool
ReferenceAction -> ReferenceAction -> Ordering
ReferenceAction -> ReferenceAction -> ReferenceAction
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ReferenceAction -> ReferenceAction -> ReferenceAction
$cmin :: ReferenceAction -> ReferenceAction -> ReferenceAction
max :: ReferenceAction -> ReferenceAction -> ReferenceAction
$cmax :: ReferenceAction -> ReferenceAction -> ReferenceAction
>= :: ReferenceAction -> ReferenceAction -> Bool
$c>= :: ReferenceAction -> ReferenceAction -> Bool
> :: ReferenceAction -> ReferenceAction -> Bool
$c> :: ReferenceAction -> ReferenceAction -> Bool
<= :: ReferenceAction -> ReferenceAction -> Bool
$c<= :: ReferenceAction -> ReferenceAction -> Bool
< :: ReferenceAction -> ReferenceAction -> Bool
$c< :: ReferenceAction -> ReferenceAction -> Bool
compare :: ReferenceAction -> ReferenceAction -> Ordering
$ccompare :: ReferenceAction -> ReferenceAction -> Ordering
$cp1Ord :: Eq ReferenceAction
Ord, (forall x. ReferenceAction -> Rep ReferenceAction x)
-> (forall x. Rep ReferenceAction x -> ReferenceAction)
-> Generic ReferenceAction
forall x. Rep ReferenceAction x -> ReferenceAction
forall x. ReferenceAction -> Rep ReferenceAction x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ReferenceAction x -> ReferenceAction
$cfrom :: forall x. ReferenceAction -> Rep ReferenceAction x
Generic)

instance NFData ReferenceAction

--
-- Modifying the 'Schema'
--

-- | A possible list of edits on a 'Schema'.
data EditAction
  = EditAction_Manual ManualEditAction
  | EditAction_Automatic AutomaticEditAction
  deriving (Int -> EditAction -> ShowS
[EditAction] -> ShowS
EditAction -> String
(Int -> EditAction -> ShowS)
-> (EditAction -> String)
-> ([EditAction] -> ShowS)
-> Show EditAction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EditAction] -> ShowS
$cshowList :: [EditAction] -> ShowS
show :: EditAction -> String
$cshow :: EditAction -> String
showsPrec :: Int -> EditAction -> ShowS
$cshowsPrec :: Int -> EditAction -> ShowS
Show, EditAction -> EditAction -> Bool
(EditAction -> EditAction -> Bool)
-> (EditAction -> EditAction -> Bool) -> Eq EditAction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EditAction -> EditAction -> Bool
$c/= :: EditAction -> EditAction -> Bool
== :: EditAction -> EditAction -> Bool
$c== :: EditAction -> EditAction -> Bool
Eq)

data ManualEditAction
  = ColumnRenamed TableName ColumnName {- old name -} ColumnName {- new name -}
  deriving (Int -> ManualEditAction -> ShowS
[ManualEditAction] -> ShowS
ManualEditAction -> String
(Int -> ManualEditAction -> ShowS)
-> (ManualEditAction -> String)
-> ([ManualEditAction] -> ShowS)
-> Show ManualEditAction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ManualEditAction] -> ShowS
$cshowList :: [ManualEditAction] -> ShowS
show :: ManualEditAction -> String
$cshow :: ManualEditAction -> String
showsPrec :: Int -> ManualEditAction -> ShowS
$cshowsPrec :: Int -> ManualEditAction -> ShowS
Show, ManualEditAction -> ManualEditAction -> Bool
(ManualEditAction -> ManualEditAction -> Bool)
-> (ManualEditAction -> ManualEditAction -> Bool)
-> Eq ManualEditAction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ManualEditAction -> ManualEditAction -> Bool
$c/= :: ManualEditAction -> ManualEditAction -> Bool
== :: ManualEditAction -> ManualEditAction -> Bool
$c== :: ManualEditAction -> ManualEditAction -> Bool
Eq)

data AutomaticEditAction
  = TableAdded TableName Table
  | TableRemoved TableName
  | TableConstraintAdded TableName TableConstraint
  | TableConstraintRemoved TableName TableConstraint
  | ColumnAdded TableName ColumnName Column
  | ColumnRemoved TableName ColumnName
  | ColumnTypeChanged TableName ColumnName ColumnType {- old type -} ColumnType {- new type -}
  | ColumnConstraintAdded TableName ColumnName ColumnConstraint
  | ColumnConstraintRemoved TableName ColumnName ColumnConstraint
  | EnumTypeAdded EnumerationName Enumeration
  | EnumTypeRemoved EnumerationName
  | EnumTypeValueAdded EnumerationName Text {- added value -} InsertionOrder Text {- insertion point -}
  | SequenceAdded SequenceName Sequence
  | SequenceRemoved SequenceName
  deriving (Int -> AutomaticEditAction -> ShowS
[AutomaticEditAction] -> ShowS
AutomaticEditAction -> String
(Int -> AutomaticEditAction -> ShowS)
-> (AutomaticEditAction -> String)
-> ([AutomaticEditAction] -> ShowS)
-> Show AutomaticEditAction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AutomaticEditAction] -> ShowS
$cshowList :: [AutomaticEditAction] -> ShowS
show :: AutomaticEditAction -> String
$cshow :: AutomaticEditAction -> String
showsPrec :: Int -> AutomaticEditAction -> ShowS
$cshowsPrec :: Int -> AutomaticEditAction -> ShowS
Show, AutomaticEditAction -> AutomaticEditAction -> Bool
(AutomaticEditAction -> AutomaticEditAction -> Bool)
-> (AutomaticEditAction -> AutomaticEditAction -> Bool)
-> Eq AutomaticEditAction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AutomaticEditAction -> AutomaticEditAction -> Bool
$c/= :: AutomaticEditAction -> AutomaticEditAction -> Bool
== :: AutomaticEditAction -> AutomaticEditAction -> Bool
$c== :: AutomaticEditAction -> AutomaticEditAction -> Bool
Eq)

-- | Safety rating for a given edit.
--
-- "Safety" is defined as some 'EditAction' that might cause data loss.
data EditSafety
  = Safe
  | PotentiallySlow
  | Unsafe
  deriving (Int -> EditSafety -> ShowS
[EditSafety] -> ShowS
EditSafety -> String
(Int -> EditSafety -> ShowS)
-> (EditSafety -> String)
-> ([EditSafety] -> ShowS)
-> Show EditSafety
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EditSafety] -> ShowS
$cshowList :: [EditSafety] -> ShowS
show :: EditSafety -> String
$cshow :: EditSafety -> String
showsPrec :: Int -> EditSafety -> ShowS
$cshowsPrec :: Int -> EditSafety -> ShowS
Show, EditSafety -> EditSafety -> Bool
(EditSafety -> EditSafety -> Bool)
-> (EditSafety -> EditSafety -> Bool) -> Eq EditSafety
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EditSafety -> EditSafety -> Bool
$c/= :: EditSafety -> EditSafety -> Bool
== :: EditSafety -> EditSafety -> Bool
$c== :: EditSafety -> EditSafety -> Bool
Eq, Eq EditSafety
Eq EditSafety
-> (EditSafety -> EditSafety -> Ordering)
-> (EditSafety -> EditSafety -> Bool)
-> (EditSafety -> EditSafety -> Bool)
-> (EditSafety -> EditSafety -> Bool)
-> (EditSafety -> EditSafety -> Bool)
-> (EditSafety -> EditSafety -> EditSafety)
-> (EditSafety -> EditSafety -> EditSafety)
-> Ord EditSafety
EditSafety -> EditSafety -> Bool
EditSafety -> EditSafety -> Ordering
EditSafety -> EditSafety -> EditSafety
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EditSafety -> EditSafety -> EditSafety
$cmin :: EditSafety -> EditSafety -> EditSafety
max :: EditSafety -> EditSafety -> EditSafety
$cmax :: EditSafety -> EditSafety -> EditSafety
>= :: EditSafety -> EditSafety -> Bool
$c>= :: EditSafety -> EditSafety -> Bool
> :: EditSafety -> EditSafety -> Bool
$c> :: EditSafety -> EditSafety -> Bool
<= :: EditSafety -> EditSafety -> Bool
$c<= :: EditSafety -> EditSafety -> Bool
< :: EditSafety -> EditSafety -> Bool
$c< :: EditSafety -> EditSafety -> Bool
compare :: EditSafety -> EditSafety -> Ordering
$ccompare :: EditSafety -> EditSafety -> Ordering
$cp1Ord :: Eq EditSafety
Ord)

defaultEditSafety :: AutomaticEditAction -> EditSafety
defaultEditSafety :: AutomaticEditAction -> EditSafety
defaultEditSafety = \case
  TableAdded {} -> EditSafety
Safe
  TableRemoved {} -> EditSafety
Unsafe
  TableConstraintAdded {} -> EditSafety
Safe
  TableConstraintRemoved {} -> EditSafety
Safe
  ColumnAdded {} -> EditSafety
Safe
  ColumnRemoved {} -> EditSafety
Unsafe
  ColumnTypeChanged {} -> EditSafety
Unsafe
  ColumnConstraintAdded {} -> EditSafety
Safe
  ColumnConstraintRemoved {} -> EditSafety
Safe
  EnumTypeAdded {} -> EditSafety
Safe
  EnumTypeRemoved {} -> EditSafety
Unsafe
  EnumTypeValueAdded {} -> EditSafety
Safe
  SequenceAdded {} -> EditSafety
Safe
  SequenceRemoved {} -> EditSafety
Unsafe

data EditCondition = EditCondition
  { EditCondition -> BeamSqlBackendSyntax Postgres
_editCondition_query :: BeamSqlBackendSyntax Postgres,
    EditCondition -> Pg EditSafety
_editCondition_check :: Pg EditSafety
  }

prettyEditConditionQuery :: EditCondition -> ByteString
prettyEditConditionQuery :: EditCondition -> ByteString
prettyEditConditionQuery = PgSyntax -> ByteString
Syntax.pgRenderSyntaxScript (PgSyntax -> ByteString)
-> (EditCondition -> PgSyntax) -> EditCondition -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgCommandSyntax -> PgSyntax
Syntax.fromPgCommand (PgCommandSyntax -> PgSyntax)
-> (EditCondition -> PgCommandSyntax) -> EditCondition -> PgSyntax
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EditCondition -> BeamSqlBackendSyntax Postgres
EditCondition -> PgCommandSyntax
_editCondition_query

instance Eq EditCondition where
  EditCondition
ec1 == :: EditCondition -> EditCondition -> Bool
== EditCondition
ec2 = EditCondition -> ByteString
prettyEditConditionQuery EditCondition
ec1 ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== EditCondition -> ByteString
prettyEditConditionQuery EditCondition
ec2

instance Show EditCondition where
  show :: EditCondition -> String
show EditCondition
ec =
    [String] -> String
unwords
      [ String
"EditConditon {",
        String
"_editCondition_query = PgCommand {",
        String
"pgCommandType = ",
        PgCommandType -> String
forall a. Show a => a -> String
show (PgCommandType -> String) -> PgCommandType -> String
forall a b. (a -> b) -> a -> b
$ PgCommandSyntax -> PgCommandType
Syntax.pgCommandType (PgCommandSyntax -> PgCommandType)
-> PgCommandSyntax -> PgCommandType
forall a b. (a -> b) -> a -> b
$ EditCondition -> BeamSqlBackendSyntax Postgres
_editCondition_query EditCondition
ec,
        String
"fromPgCommand = ",
        ByteString -> String
forall a b. StringConv a b => a -> b
toS (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ EditCondition -> ByteString
prettyEditConditionQuery EditCondition
ec,
        String
"},",
        String
"_editCondition_check = <check function>",
        String
"}"
      ]

data Edit = Edit
  { Edit -> EditAction
_editAction :: EditAction,
    Edit -> Either EditCondition EditSafety
_editCondition :: Either EditCondition EditSafety
  }
  deriving (Int -> Edit -> ShowS
[Edit] -> ShowS
Edit -> String
(Int -> Edit -> ShowS)
-> (Edit -> String) -> ([Edit] -> ShowS) -> Show Edit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Edit] -> ShowS
$cshowList :: [Edit] -> ShowS
show :: Edit -> String
$cshow :: Edit -> String
showsPrec :: Int -> Edit -> ShowS
$cshowsPrec :: Int -> Edit -> ShowS
Show, Edit -> Edit -> Bool
(Edit -> Edit -> Bool) -> (Edit -> Edit -> Bool) -> Eq Edit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Edit -> Edit -> Bool
$c/= :: Edit -> Edit -> Bool
== :: Edit -> Edit -> Bool
$c== :: Edit -> Edit -> Bool
Eq)

editAction :: Lens' Edit EditAction
editAction :: (EditAction -> f EditAction) -> Edit -> f Edit
editAction = (Edit -> EditAction)
-> (Edit -> EditAction -> Edit)
-> Lens Edit Edit EditAction EditAction
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Edit -> EditAction
_editAction (\(Edit EditAction
_ Either EditCondition EditSafety
ec) EditAction
ea -> EditAction -> Either EditCondition EditSafety -> Edit
Edit EditAction
ea Either EditCondition EditSafety
ec)

editCondition :: Lens' Edit (Either EditCondition EditSafety)
editCondition :: (Either EditCondition EditSafety
 -> f (Either EditCondition EditSafety))
-> Edit -> f Edit
editCondition = (Edit -> Either EditCondition EditSafety)
-> (Edit -> Either EditCondition EditSafety -> Edit)
-> Lens
     Edit
     Edit
     (Either EditCondition EditSafety)
     (Either EditCondition EditSafety)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Edit -> Either EditCondition EditSafety
_editCondition (\(Edit EditAction
ea Either EditCondition EditSafety
_) Either EditCondition EditSafety
ec -> EditAction -> Either EditCondition EditSafety -> Edit
Edit EditAction
ea Either EditCondition EditSafety
ec)

editSafetyIs :: EditSafety -> Edit -> Bool
editSafetyIs :: EditSafety -> Edit -> Bool
editSafetyIs EditSafety
s = Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (Maybe Bool -> Bool) -> (Edit -> Maybe Bool) -> Edit -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Bool) Edit Bool -> Edit -> Maybe Bool
forall a s. Getting (First a) s a -> s -> Maybe a
preview ((Either EditCondition EditSafety
 -> Const (First Bool) (Either EditCondition EditSafety))
-> Edit -> Const (First Bool) Edit
Lens
  Edit
  Edit
  (Either EditCondition EditSafety)
  (Either EditCondition EditSafety)
editCondition ((Either EditCondition EditSafety
  -> Const (First Bool) (Either EditCondition EditSafety))
 -> Edit -> Const (First Bool) Edit)
-> ((Bool -> Const (First Bool) Bool)
    -> Either EditCondition EditSafety
    -> Const (First Bool) (Either EditCondition EditSafety))
-> Getting (First Bool) Edit Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (EditSafety -> Const (First Bool) EditSafety)
-> Either EditCondition EditSafety
-> Const (First Bool) (Either EditCondition EditSafety)
forall a b b'. Traversal (Either a b) (Either a b') b b'
_Right ((EditSafety -> Const (First Bool) EditSafety)
 -> Either EditCondition EditSafety
 -> Const (First Bool) (Either EditCondition EditSafety))
-> ((Bool -> Const (First Bool) Bool)
    -> EditSafety -> Const (First Bool) EditSafety)
-> (Bool -> Const (First Bool) Bool)
-> Either EditCondition EditSafety
-> Const (First Bool) (Either EditCondition EditSafety)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (EditSafety -> Bool) -> SimpleGetter EditSafety Bool
forall s a. (s -> a) -> SimpleGetter s a
to (EditSafety -> EditSafety -> Bool
forall a. Eq a => a -> a -> Bool
== EditSafety
s))

mkEditWith :: (AutomaticEditAction -> EditSafety) -> AutomaticEditAction -> Edit
mkEditWith :: (AutomaticEditAction -> EditSafety) -> AutomaticEditAction -> Edit
mkEditWith AutomaticEditAction -> EditSafety
isSafe AutomaticEditAction
e = EditAction -> Either EditCondition EditSafety -> Edit
Edit (AutomaticEditAction -> EditAction
EditAction_Automatic AutomaticEditAction
e) (EditSafety -> Either EditCondition EditSafety
forall a b. b -> Either a b
Right (EditSafety -> Either EditCondition EditSafety)
-> EditSafety -> Either EditCondition EditSafety
forall a b. (a -> b) -> a -> b
$ AutomaticEditAction -> EditSafety
isSafe AutomaticEditAction
e)

defMkEdit :: AutomaticEditAction -> Edit
defMkEdit :: AutomaticEditAction -> Edit
defMkEdit = (AutomaticEditAction -> EditSafety) -> AutomaticEditAction -> Edit
mkEditWith AutomaticEditAction -> EditSafety
defaultEditSafety

data InsertionOrder
  = Before
  | After
  deriving (Int -> InsertionOrder -> ShowS
[InsertionOrder] -> ShowS
InsertionOrder -> String
(Int -> InsertionOrder -> ShowS)
-> (InsertionOrder -> String)
-> ([InsertionOrder] -> ShowS)
-> Show InsertionOrder
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InsertionOrder] -> ShowS
$cshowList :: [InsertionOrder] -> ShowS
show :: InsertionOrder -> String
$cshow :: InsertionOrder -> String
showsPrec :: Int -> InsertionOrder -> ShowS
$cshowsPrec :: Int -> InsertionOrder -> ShowS
Show, InsertionOrder -> InsertionOrder -> Bool
(InsertionOrder -> InsertionOrder -> Bool)
-> (InsertionOrder -> InsertionOrder -> Bool) -> Eq InsertionOrder
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: InsertionOrder -> InsertionOrder -> Bool
$c/= :: InsertionOrder -> InsertionOrder -> Bool
== :: InsertionOrder -> InsertionOrder -> Bool
$c== :: InsertionOrder -> InsertionOrder -> Bool
Eq, (forall x. InsertionOrder -> Rep InsertionOrder x)
-> (forall x. Rep InsertionOrder x -> InsertionOrder)
-> Generic InsertionOrder
forall x. Rep InsertionOrder x -> InsertionOrder
forall x. InsertionOrder -> Rep InsertionOrder x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep InsertionOrder x -> InsertionOrder
$cfrom :: forall x. InsertionOrder -> Rep InsertionOrder x
Generic)

instance NFData InsertionOrder

instance NFData EditAction where
  rnf :: EditAction -> ()
rnf (EditAction_Automatic AutomaticEditAction
ea) = AutomaticEditAction -> ()
forall a. NFData a => a -> ()
rnf AutomaticEditAction
ea
  rnf (EditAction_Manual ManualEditAction
ea) = ManualEditAction -> ()
forall a. NFData a => a -> ()
rnf ManualEditAction
ea

instance NFData ManualEditAction where
  rnf :: ManualEditAction -> ()
rnf (ColumnRenamed TableName
tName ColumnName
oldName ColumnName
newName) = TableName
tName TableName -> ColumnName -> ColumnName
forall a b. NFData a => a -> b -> b
`deepseq` ColumnName
oldName ColumnName -> ColumnName -> ColumnName
forall a b. NFData a => a -> b -> b
`deepseq` ColumnName
newName ColumnName -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()

-- Manual instance as 'AST.DataType' doesn't derive 'NFData'.
instance NFData AutomaticEditAction where
  rnf :: AutomaticEditAction -> ()
rnf (TableAdded TableName
tName Table
tbl) = TableName
tName TableName -> Table -> Table
forall a b. NFData a => a -> b -> b
`deepseq` Table
tbl Table -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (TableRemoved TableName
tName) = TableName -> ()
forall a. NFData a => a -> ()
rnf TableName
tName
  rnf (TableConstraintAdded TableName
tName TableConstraint
tCon) = TableName
tName TableName -> TableConstraint -> TableConstraint
forall a b. NFData a => a -> b -> b
`deepseq` TableConstraint
tCon TableConstraint -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (TableConstraintRemoved TableName
tName TableConstraint
tCon) = TableName
tName TableName -> TableConstraint -> TableConstraint
forall a b. NFData a => a -> b -> b
`deepseq` TableConstraint
tCon TableConstraint -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (ColumnAdded TableName
tName ColumnName
cName Column
col) = TableName
tName TableName -> ColumnName -> ColumnName
forall a b. NFData a => a -> b -> b
`deepseq` ColumnName
cName ColumnName -> Column -> Column
forall a b. NFData a => a -> b -> b
`deepseq` Column
col Column -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (ColumnRemoved TableName
tName ColumnName
colName) = TableName
tName TableName -> ColumnName -> ColumnName
forall a b. NFData a => a -> b -> b
`deepseq` ColumnName
colName ColumnName -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (ColumnTypeChanged TableName
tName ColumnName
colName ColumnType
c1 ColumnType
c2) = ColumnType
c1 ColumnType -> () -> ()
`seq` ColumnType
c2 ColumnType -> () -> ()
`seq` TableName
tName TableName -> ColumnName -> ColumnName
forall a b. NFData a => a -> b -> b
`deepseq` ColumnName
colName ColumnName -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (ColumnConstraintAdded TableName
tName ColumnName
cName ColumnConstraint
cCon) = TableName
tName TableName -> ColumnName -> ColumnName
forall a b. NFData a => a -> b -> b
`deepseq` ColumnName
cName ColumnName -> ColumnConstraint -> ColumnConstraint
forall a b. NFData a => a -> b -> b
`deepseq` ColumnConstraint
cCon ColumnConstraint -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (ColumnConstraintRemoved TableName
tName ColumnName
colName ColumnConstraint
cCon) = TableName
tName TableName -> ColumnName -> ColumnName
forall a b. NFData a => a -> b -> b
`deepseq` ColumnName
colName ColumnName -> ColumnConstraint -> ColumnConstraint
forall a b. NFData a => a -> b -> b
`deepseq` ColumnConstraint
cCon ColumnConstraint -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (EnumTypeAdded EnumerationName
eName Enumeration
enum) = EnumerationName
eName EnumerationName -> Enumeration -> Enumeration
forall a b. NFData a => a -> b -> b
`deepseq` Enumeration
enum Enumeration -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (EnumTypeRemoved EnumerationName
eName) = EnumerationName
eName EnumerationName -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (EnumTypeValueAdded EnumerationName
eName Text
inserted InsertionOrder
order Text
insertionPoint) =
    EnumerationName
eName EnumerationName -> Text -> Text
forall a b. NFData a => a -> b -> b
`deepseq` Text
inserted Text -> InsertionOrder -> InsertionOrder
forall a b. NFData a => a -> b -> b
`deepseq` InsertionOrder
order InsertionOrder -> Text -> Text
forall a b. NFData a => a -> b -> b
`deepseq` Text
insertionPoint Text -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (SequenceAdded SequenceName
sName Sequence
s) = SequenceName
sName SequenceName -> Sequence -> Sequence
forall a b. NFData a => a -> b -> b
`deepseq` Sequence
s Sequence -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()
  rnf (SequenceRemoved SequenceName
sName) = SequenceName
sName SequenceName -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()

-- | A possible enumerations of the reasons why a 'diff' operation might not work.
data DiffError
  = -- | The diff couldn't be completed. TODO(adn) We need extra information
    -- we can later on reify into the raw SQL queries users can try to run
    -- themselves.
    AutomaticDiffNotPossible
  | -- | Postgres doesn't support removing values from an enum.
    ValuesRemovedFromEnum EnumerationName [Text]
  deriving (Int -> DiffError -> ShowS
[DiffError] -> ShowS
DiffError -> String
(Int -> DiffError -> ShowS)
-> (DiffError -> String)
-> ([DiffError] -> ShowS)
-> Show DiffError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DiffError] -> ShowS
$cshowList :: [DiffError] -> ShowS
show :: DiffError -> String
$cshow :: DiffError -> String
showsPrec :: Int -> DiffError -> ShowS
$cshowsPrec :: Int -> DiffError -> ShowS
Show, (forall x. DiffError -> Rep DiffError x)
-> (forall x. Rep DiffError x -> DiffError) -> Generic DiffError
forall x. Rep DiffError x -> DiffError
forall x. DiffError -> Rep DiffError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DiffError x -> DiffError
$cfrom :: forall x. DiffError -> Rep DiffError x
Generic, DiffError -> DiffError -> Bool
(DiffError -> DiffError -> Bool)
-> (DiffError -> DiffError -> Bool) -> Eq DiffError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DiffError -> DiffError -> Bool
$c/= :: DiffError -> DiffError -> Bool
== :: DiffError -> DiffError -> Bool
$c== :: DiffError -> DiffError -> Bool
Eq)

instance Exception DiffError

instance NFData DiffError

--
-- Utility functions
--

noSchema :: Schema
noSchema :: Schema
noSchema = Tables -> Enumerations -> Sequences -> Schema
Schema Tables
forall a. Monoid a => a
mempty Enumerations
forall a. Monoid a => a
mempty Sequences
forall a. Monoid a => a
mempty

noTableConstraints :: Set TableConstraint
noTableConstraints :: Set TableConstraint
noTableConstraints = Set TableConstraint
forall a. Monoid a => a
mempty

noColumnConstraints :: Set ColumnConstraint
noColumnConstraints :: Set ColumnConstraint
noColumnConstraints = Set ColumnConstraint
forall a. Monoid a => a
mempty