module Sqel.Data.Term where

import Sqel.Data.Dd (DdInc (DdMerge, DdNest), DdSort (DdCon, DdProd, DdSum))
import Sqel.Data.PgType (PgColumnName, PgPrimName)
import Sqel.Data.PgTypeName (PgTableName)
import Sqel.Data.Sql (Sql)

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

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

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

data Struct =
  Prim PgPrimName
  |
  Comp Text Comp CompInc [DdTerm]
  deriving stock (Struct -> Struct -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Struct -> Struct -> Bool
$c/= :: Struct -> Struct -> Bool
== :: Struct -> Struct -> Bool
$c== :: Struct -> Struct -> Bool
Eq, Int -> Struct -> ShowS
[Struct] -> ShowS
Struct -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Struct] -> ShowS
$cshowList :: [Struct] -> ShowS
show :: Struct -> String
$cshow :: Struct -> String
showsPrec :: Int -> Struct -> ShowS
$cshowsPrec :: Int -> Struct -> ShowS
Show, forall x. Rep Struct x -> Struct
forall x. Struct -> Rep Struct x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Struct x -> Struct
$cfrom :: forall x. Struct -> Rep Struct x
Generic)

-- TODO would be nice to have a separate type wrapping the root for the table name
data DdTerm =
  DdTerm {
    DdTerm -> PgColumnName
name :: PgColumnName,
    DdTerm -> Maybe PgTableName
tableName :: Maybe PgTableName,
    DdTerm -> Bool
unique :: Bool,
    DdTerm -> [Sql]
constraints :: [Sql],
    DdTerm -> Struct
struct :: Struct
  }
  deriving stock (DdTerm -> DdTerm -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DdTerm -> DdTerm -> Bool
$c/= :: DdTerm -> DdTerm -> Bool
== :: DdTerm -> DdTerm -> Bool
$c== :: DdTerm -> DdTerm -> Bool
Eq, Int -> DdTerm -> ShowS
[DdTerm] -> ShowS
DdTerm -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DdTerm] -> ShowS
$cshowList :: [DdTerm] -> ShowS
show :: DdTerm -> String
$cshow :: DdTerm -> String
showsPrec :: Int -> DdTerm -> ShowS
$cshowsPrec :: Int -> DdTerm -> ShowS
Show, forall x. Rep DdTerm x -> DdTerm
forall x. DdTerm -> Rep DdTerm x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DdTerm x -> DdTerm
$cfrom :: forall x. DdTerm -> Rep DdTerm x
Generic)

demoteComp :: DdSort c -> Comp
demoteComp :: forall (c :: Comp). DdSort c -> Comp
demoteComp = \case
  DdSort c
DdProd -> ProdType -> Comp
Prod ProdType
Reg
  DdSort c
DdCon -> ProdType -> Comp
Prod ProdType
Con
  DdSort c
DdSum -> Comp
Sum

demoteInc :: DdInc i -> CompInc
demoteInc :: forall (i :: CompInc). DdInc i -> CompInc
demoteInc = \case
  DdInc i
DdMerge -> CompInc
Merge
  DdInc i
DdNest -> CompInc
Nest