module Sqel.Data.PgType where import Data.Aeson (FromJSON, ToJSON) import qualified Data.Map.Strict as Map import qualified Exon import Lens.Micro.Extras (view) import Prettyprinter (Pretty (pretty), nest, sep, vsep, (<+>)) import Sqel.SOP.Constraint (symbolText) import Sqel.Text.DbIdentifier (dbIdentifierT, dbSymbol) import Sqel.Data.PgTypeName (PgCompName, PgTableName, pattern PgTypeName) import Sqel.Data.Selector (Selector (unSelector), assign, nameSelector) import Sqel.Data.Sql (Sql, ToSql (toSql), sql, sqlQuote) import Sqel.Data.SqlFragment ( CommaSep (CommaSep), Create (Create), Delete (Delete), From (From), Insert (Insert), Into (Into), Returning (Returning), Select (Select), Update (Update), ) newtype PgPrimName = PgPrimName { PgPrimName -> Text unPgPrimName :: Text } deriving stock (PgPrimName -> PgPrimName -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: PgPrimName -> PgPrimName -> Bool $c/= :: PgPrimName -> PgPrimName -> Bool == :: PgPrimName -> PgPrimName -> Bool $c== :: PgPrimName -> PgPrimName -> Bool Eq, Int -> PgPrimName -> ShowS [PgPrimName] -> ShowS PgPrimName -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [PgPrimName] -> ShowS $cshowList :: [PgPrimName] -> ShowS show :: PgPrimName -> String $cshow :: PgPrimName -> String showsPrec :: Int -> PgPrimName -> ShowS $cshowsPrec :: Int -> PgPrimName -> ShowS Show, forall x. Rep PgPrimName x -> PgPrimName forall x. PgPrimName -> Rep PgPrimName x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep PgPrimName x -> PgPrimName $cfrom :: forall x. PgPrimName -> Rep PgPrimName x Generic) deriving newtype (String -> PgPrimName forall a. (String -> a) -> IsString a fromString :: String -> PgPrimName $cfromString :: String -> PgPrimName IsString, Eq PgPrimName PgPrimName -> PgPrimName -> Bool PgPrimName -> PgPrimName -> Ordering PgPrimName -> PgPrimName -> PgPrimName 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 :: PgPrimName -> PgPrimName -> PgPrimName $cmin :: PgPrimName -> PgPrimName -> PgPrimName max :: PgPrimName -> PgPrimName -> PgPrimName $cmax :: PgPrimName -> PgPrimName -> PgPrimName >= :: PgPrimName -> PgPrimName -> Bool $c>= :: PgPrimName -> PgPrimName -> Bool > :: PgPrimName -> PgPrimName -> Bool $c> :: PgPrimName -> PgPrimName -> Bool <= :: PgPrimName -> PgPrimName -> Bool $c<= :: PgPrimName -> PgPrimName -> Bool < :: PgPrimName -> PgPrimName -> Bool $c< :: PgPrimName -> PgPrimName -> Bool compare :: PgPrimName -> PgPrimName -> Ordering $ccompare :: PgPrimName -> PgPrimName -> Ordering Ord, NonEmpty PgPrimName -> PgPrimName PgPrimName -> PgPrimName -> PgPrimName forall b. Integral b => b -> PgPrimName -> PgPrimName forall a. (a -> a -> a) -> (NonEmpty a -> a) -> (forall b. Integral b => b -> a -> a) -> Semigroup a stimes :: forall b. Integral b => b -> PgPrimName -> PgPrimName $cstimes :: forall b. Integral b => b -> PgPrimName -> PgPrimName sconcat :: NonEmpty PgPrimName -> PgPrimName $csconcat :: NonEmpty PgPrimName -> PgPrimName <> :: PgPrimName -> PgPrimName -> PgPrimName $c<> :: PgPrimName -> PgPrimName -> PgPrimName Semigroup, Semigroup PgPrimName PgPrimName [PgPrimName] -> PgPrimName PgPrimName -> PgPrimName -> PgPrimName forall a. Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a mconcat :: [PgPrimName] -> PgPrimName $cmconcat :: [PgPrimName] -> PgPrimName mappend :: PgPrimName -> PgPrimName -> PgPrimName $cmappend :: PgPrimName -> PgPrimName -> PgPrimName mempty :: PgPrimName $cmempty :: PgPrimName Monoid, [PgPrimName] -> Encoding [PgPrimName] -> Value PgPrimName -> Encoding PgPrimName -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [PgPrimName] -> Encoding $ctoEncodingList :: [PgPrimName] -> Encoding toJSONList :: [PgPrimName] -> Value $ctoJSONList :: [PgPrimName] -> Value toEncoding :: PgPrimName -> Encoding $ctoEncoding :: PgPrimName -> Encoding toJSON :: PgPrimName -> Value $ctoJSON :: PgPrimName -> Value ToJSON, Value -> Parser [PgPrimName] Value -> Parser PgPrimName forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [PgPrimName] $cparseJSONList :: Value -> Parser [PgPrimName] parseJSON :: Value -> Parser PgPrimName $cparseJSON :: Value -> Parser PgPrimName FromJSON) instance Pretty PgPrimName where pretty :: forall ann. PgPrimName -> Doc ann pretty (PgPrimName Text n) = forall a ann. Pretty a => a -> Doc ann pretty Text n pgPrimName :: ∀ name . KnownSymbol name => PgPrimName pgPrimName :: forall (name :: Symbol). KnownSymbol name => PgPrimName pgPrimName = Text -> PgPrimName PgPrimName (forall (name :: Symbol). KnownSymbol name => Text dbSymbol @name) newtype PgProdName = PgProdName { PgProdName -> Text unPgProdName :: Text } deriving stock (PgProdName -> PgProdName -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: PgProdName -> PgProdName -> Bool $c/= :: PgProdName -> PgProdName -> Bool == :: PgProdName -> PgProdName -> Bool $c== :: PgProdName -> PgProdName -> Bool Eq, Int -> PgProdName -> ShowS [PgProdName] -> ShowS PgProdName -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [PgProdName] -> ShowS $cshowList :: [PgProdName] -> ShowS show :: PgProdName -> String $cshow :: PgProdName -> String showsPrec :: Int -> PgProdName -> ShowS $cshowsPrec :: Int -> PgProdName -> ShowS Show, forall x. Rep PgProdName x -> PgProdName forall x. PgProdName -> Rep PgProdName x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep PgProdName x -> PgProdName $cfrom :: forall x. PgProdName -> Rep PgProdName x Generic) deriving newtype (String -> PgProdName forall a. (String -> a) -> IsString a fromString :: String -> PgProdName $cfromString :: String -> PgProdName IsString, Eq PgProdName PgProdName -> PgProdName -> Bool PgProdName -> PgProdName -> Ordering PgProdName -> PgProdName -> PgProdName 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 :: PgProdName -> PgProdName -> PgProdName $cmin :: PgProdName -> PgProdName -> PgProdName max :: PgProdName -> PgProdName -> PgProdName $cmax :: PgProdName -> PgProdName -> PgProdName >= :: PgProdName -> PgProdName -> Bool $c>= :: PgProdName -> PgProdName -> Bool > :: PgProdName -> PgProdName -> Bool $c> :: PgProdName -> PgProdName -> Bool <= :: PgProdName -> PgProdName -> Bool $c<= :: PgProdName -> PgProdName -> Bool < :: PgProdName -> PgProdName -> Bool $c< :: PgProdName -> PgProdName -> Bool compare :: PgProdName -> PgProdName -> Ordering $ccompare :: PgProdName -> PgProdName -> Ordering Ord) newtype PgColumnName = PgColumnName { PgColumnName -> Text unPgColumnName :: Text } deriving stock (PgColumnName -> PgColumnName -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: PgColumnName -> PgColumnName -> Bool $c/= :: PgColumnName -> PgColumnName -> Bool == :: PgColumnName -> PgColumnName -> Bool $c== :: PgColumnName -> PgColumnName -> Bool Eq, Int -> PgColumnName -> ShowS [PgColumnName] -> ShowS PgColumnName -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [PgColumnName] -> ShowS $cshowList :: [PgColumnName] -> ShowS show :: PgColumnName -> String $cshow :: PgColumnName -> String showsPrec :: Int -> PgColumnName -> ShowS $cshowsPrec :: Int -> PgColumnName -> ShowS Show, forall x. Rep PgColumnName x -> PgColumnName forall x. PgColumnName -> Rep PgColumnName x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep PgColumnName x -> PgColumnName $cfrom :: forall x. PgColumnName -> Rep PgColumnName x Generic) deriving newtype (Eq PgColumnName PgColumnName -> PgColumnName -> Bool PgColumnName -> PgColumnName -> Ordering PgColumnName -> PgColumnName -> PgColumnName 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 :: PgColumnName -> PgColumnName -> PgColumnName $cmin :: PgColumnName -> PgColumnName -> PgColumnName max :: PgColumnName -> PgColumnName -> PgColumnName $cmax :: PgColumnName -> PgColumnName -> PgColumnName >= :: PgColumnName -> PgColumnName -> Bool $c>= :: PgColumnName -> PgColumnName -> Bool > :: PgColumnName -> PgColumnName -> Bool $c> :: PgColumnName -> PgColumnName -> Bool <= :: PgColumnName -> PgColumnName -> Bool $c<= :: PgColumnName -> PgColumnName -> Bool < :: PgColumnName -> PgColumnName -> Bool $c< :: PgColumnName -> PgColumnName -> Bool compare :: PgColumnName -> PgColumnName -> Ordering $ccompare :: PgColumnName -> PgColumnName -> Ordering Ord, [PgColumnName] -> Encoding [PgColumnName] -> Value PgColumnName -> Encoding PgColumnName -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [PgColumnName] -> Encoding $ctoEncodingList :: [PgColumnName] -> Encoding toJSONList :: [PgColumnName] -> Value $ctoJSONList :: [PgColumnName] -> Value toEncoding :: PgColumnName -> Encoding $ctoEncoding :: PgColumnName -> Encoding toJSON :: PgColumnName -> Value $ctoJSON :: PgColumnName -> Value ToJSON, Value -> Parser [PgColumnName] Value -> Parser PgColumnName forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [PgColumnName] $cparseJSONList :: Value -> Parser [PgColumnName] parseJSON :: Value -> Parser PgColumnName $cparseJSON :: Value -> Parser PgColumnName FromJSON) instance Pretty PgColumnName where pretty :: forall ann. PgColumnName -> Doc ann pretty (PgColumnName Text n) = forall a ann. Pretty a => a -> Doc ann pretty Text n instance ToSql PgColumnName where toSql :: PgColumnName -> Sql toSql = Text -> Sql sqlQuote forall b c a. (b -> c) -> (a -> b) -> a -> c . PgColumnName -> Text unPgColumnName pgColumnName :: Text -> PgColumnName pgColumnName :: Text -> PgColumnName pgColumnName Text n = Text -> PgColumnName PgColumnName (Text -> Text dbIdentifierT Text n) instance IsString PgColumnName where fromString :: String -> PgColumnName fromString = Text -> PgColumnName pgColumnName forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. IsString a => String -> a fromString newtype PgTypeRef = PgTypeRef { PgTypeRef -> Text unPgTypeRef :: Text } deriving stock (PgTypeRef -> PgTypeRef -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: PgTypeRef -> PgTypeRef -> Bool $c/= :: PgTypeRef -> PgTypeRef -> Bool == :: PgTypeRef -> PgTypeRef -> Bool $c== :: PgTypeRef -> PgTypeRef -> Bool Eq, Int -> PgTypeRef -> ShowS [PgTypeRef] -> ShowS PgTypeRef -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [PgTypeRef] -> ShowS $cshowList :: [PgTypeRef] -> ShowS show :: PgTypeRef -> String $cshow :: PgTypeRef -> String showsPrec :: Int -> PgTypeRef -> ShowS $cshowsPrec :: Int -> PgTypeRef -> ShowS Show, forall x. Rep PgTypeRef x -> PgTypeRef forall x. PgTypeRef -> Rep PgTypeRef x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep PgTypeRef x -> PgTypeRef $cfrom :: forall x. PgTypeRef -> Rep PgTypeRef x Generic) deriving newtype (String -> PgTypeRef forall a. (String -> a) -> IsString a fromString :: String -> PgTypeRef $cfromString :: String -> PgTypeRef IsString, Eq PgTypeRef PgTypeRef -> PgTypeRef -> Bool PgTypeRef -> PgTypeRef -> Ordering PgTypeRef -> PgTypeRef -> PgTypeRef 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 :: PgTypeRef -> PgTypeRef -> PgTypeRef $cmin :: PgTypeRef -> PgTypeRef -> PgTypeRef max :: PgTypeRef -> PgTypeRef -> PgTypeRef $cmax :: PgTypeRef -> PgTypeRef -> PgTypeRef >= :: PgTypeRef -> PgTypeRef -> Bool $c>= :: PgTypeRef -> PgTypeRef -> Bool > :: PgTypeRef -> PgTypeRef -> Bool $c> :: PgTypeRef -> PgTypeRef -> Bool <= :: PgTypeRef -> PgTypeRef -> Bool $c<= :: PgTypeRef -> PgTypeRef -> Bool < :: PgTypeRef -> PgTypeRef -> Bool $c< :: PgTypeRef -> PgTypeRef -> Bool compare :: PgTypeRef -> PgTypeRef -> Ordering $ccompare :: PgTypeRef -> PgTypeRef -> Ordering Ord, [PgTypeRef] -> Encoding [PgTypeRef] -> Value PgTypeRef -> Encoding PgTypeRef -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [PgTypeRef] -> Encoding $ctoEncodingList :: [PgTypeRef] -> Encoding toJSONList :: [PgTypeRef] -> Value $ctoJSONList :: [PgTypeRef] -> Value toEncoding :: PgTypeRef -> Encoding $ctoEncoding :: PgTypeRef -> Encoding toJSON :: PgTypeRef -> Value $ctoJSON :: PgTypeRef -> Value ToJSON, Value -> Parser [PgTypeRef] Value -> Parser PgTypeRef forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [PgTypeRef] $cparseJSONList :: Value -> Parser [PgTypeRef] parseJSON :: Value -> Parser PgTypeRef $cparseJSON :: Value -> Parser PgTypeRef FromJSON) instance Pretty PgTypeRef where pretty :: forall ann. PgTypeRef -> Doc ann pretty (PgTypeRef Text n) = forall a ann. Pretty a => a -> Doc ann pretty Text n instance ToSql PgTypeRef where toSql :: PgTypeRef -> Sql toSql = Text -> Sql sqlQuote forall b c a. (b -> c) -> (a -> b) -> a -> c . PgTypeRef -> Text unPgTypeRef pgTypeRef :: Text -> PgTypeRef pgTypeRef :: Text -> PgTypeRef pgTypeRef Text n = Text -> PgTypeRef PgTypeRef (Text -> Text dbIdentifierT Text n) pgCompRef :: PgCompName -> PgTypeRef pgCompRef :: PgCompName -> PgTypeRef pgCompRef (PgTypeName Text n) = Text -> PgTypeRef PgTypeRef Text n pgTypeRefSym :: ∀ tname . KnownSymbol tname => PgTypeRef pgTypeRefSym :: forall (tname :: Symbol). KnownSymbol tname => PgTypeRef pgTypeRefSym = Text -> PgTypeRef pgTypeRef (forall (name :: Symbol). KnownSymbol name => Text symbolText @tname) data ColumnType = ColumnPrim { ColumnType -> PgPrimName name :: PgPrimName, ColumnType -> Bool unique :: Bool, ColumnType -> [Sql] constraints :: [Sql] } | ColumnComp { ColumnType -> PgTypeRef pgType :: PgTypeRef, unique :: Bool, constraints :: [Sql] } deriving stock (ColumnType -> ColumnType -> Bool 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, Int -> ColumnType -> ShowS [ColumnType] -> ShowS ColumnType -> String 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, 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) deriving anyclass ([ColumnType] -> Encoding [ColumnType] -> Value ColumnType -> Encoding ColumnType -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [ColumnType] -> Encoding $ctoEncodingList :: [ColumnType] -> Encoding toJSONList :: [ColumnType] -> Value $ctoJSONList :: [ColumnType] -> Value toEncoding :: ColumnType -> Encoding $ctoEncoding :: ColumnType -> Encoding toJSON :: ColumnType -> Value $ctoJSON :: ColumnType -> Value ToJSON, Value -> Parser [ColumnType] Value -> Parser ColumnType forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [ColumnType] $cparseJSONList :: Value -> Parser [ColumnType] parseJSON :: Value -> Parser ColumnType $cparseJSON :: Value -> Parser ColumnType FromJSON) data PgColumn = PgColumn { PgColumn -> PgColumnName name :: PgColumnName, PgColumn -> ColumnType pgType :: ColumnType } deriving stock (PgColumn -> PgColumn -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: PgColumn -> PgColumn -> Bool $c/= :: PgColumn -> PgColumn -> Bool == :: PgColumn -> PgColumn -> Bool $c== :: PgColumn -> PgColumn -> Bool Eq, Int -> PgColumn -> ShowS [PgColumn] -> ShowS PgColumn -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [PgColumn] -> ShowS $cshowList :: [PgColumn] -> ShowS show :: PgColumn -> String $cshow :: PgColumn -> String showsPrec :: Int -> PgColumn -> ShowS $cshowsPrec :: Int -> PgColumn -> ShowS Show, forall x. Rep PgColumn x -> PgColumn forall x. PgColumn -> Rep PgColumn x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep PgColumn x -> PgColumn $cfrom :: forall x. PgColumn -> Rep PgColumn x Generic) deriving anyclass (Value -> Parser [PgColumn] Value -> Parser PgColumn forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [PgColumn] $cparseJSONList :: Value -> Parser [PgColumn] parseJSON :: Value -> Parser PgColumn $cparseJSON :: Value -> Parser PgColumn FromJSON, [PgColumn] -> Encoding [PgColumn] -> Value PgColumn -> Encoding PgColumn -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [PgColumn] -> Encoding $ctoEncodingList :: [PgColumn] -> Encoding toJSONList :: [PgColumn] -> Value $ctoJSONList :: [PgColumn] -> Value toEncoding :: PgColumn -> Encoding $ctoEncoding :: PgColumn -> Encoding toJSON :: PgColumn -> Value $ctoJSON :: PgColumn -> Value ToJSON) instance Pretty PgColumn where pretty :: forall ann. PgColumn -> Doc ann pretty = \case PgColumn PgColumnName n (ColumnPrim PgPrimName t Bool _ [Sql] opt) -> Doc ann "*" forall ann. Doc ann -> Doc ann -> Doc ann <+> forall a ann. Pretty a => a -> Doc ann pretty PgColumnName n forall ann. Doc ann -> Doc ann -> Doc ann <+> forall a ann. Pretty a => a -> Doc ann pretty PgPrimName t forall ann. Doc ann -> Doc ann -> Doc ann <+> forall ann. [Doc ann] -> Doc ann sep (forall a ann. Pretty a => a -> Doc ann pretty forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Sql] opt) PgColumn PgColumnName n (ColumnComp PgTypeRef t Bool _ [Sql] opt) -> Doc ann "+" forall ann. Doc ann -> Doc ann -> Doc ann <+> forall a ann. Pretty a => a -> Doc ann pretty PgColumnName n forall ann. Doc ann -> Doc ann -> Doc ann <+> forall a ann. Pretty a => a -> Doc ann pretty PgTypeRef t forall ann. Doc ann -> Doc ann -> Doc ann <+> forall ann. [Doc ann] -> Doc ann sep (forall a ann. Pretty a => a -> Doc ann pretty forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Sql] opt) instance ToSql (Create PgColumn) where toSql :: Create PgColumn -> Sql toSql (Create PgColumn {ColumnType PgColumnName pgType :: ColumnType name :: PgColumnName $sel:pgType:PgColumn :: PgColumn -> ColumnType $sel:name:PgColumn :: PgColumn -> PgColumnName ..}) = case ColumnType pgType of ColumnPrim (PgPrimName Text tpe) Bool _ (forall a (t :: * -> *). (Monoid a, Foldable t) => a -> t a -> a Exon.intercalate Sql " " -> Sql params) -> [sql|##{name} ##{tpe} #{params}|] ColumnComp (PgTypeRef Text tpe) Bool _ (forall a (t :: * -> *). (Monoid a, Foldable t) => a -> t a -> a Exon.intercalate Sql " " -> Sql params) -> [sql|##{name} ##{tpe} #{params}|] newtype PgColumns = PgColumns { PgColumns -> [PgColumn] unPgColumns :: [PgColumn] } deriving stock (PgColumns -> PgColumns -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: PgColumns -> PgColumns -> Bool $c/= :: PgColumns -> PgColumns -> Bool == :: PgColumns -> PgColumns -> Bool $c== :: PgColumns -> PgColumns -> Bool Eq, Int -> PgColumns -> ShowS [PgColumns] -> ShowS PgColumns -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [PgColumns] -> ShowS $cshowList :: [PgColumns] -> ShowS show :: PgColumns -> String $cshow :: PgColumns -> String showsPrec :: Int -> PgColumns -> ShowS $cshowsPrec :: Int -> PgColumns -> ShowS Show) deriving newtype (Value -> Parser [PgColumns] Value -> Parser PgColumns forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [PgColumns] $cparseJSONList :: Value -> Parser [PgColumns] parseJSON :: Value -> Parser PgColumns $cparseJSON :: Value -> Parser PgColumns FromJSON, [PgColumns] -> Encoding [PgColumns] -> Value PgColumns -> Encoding PgColumns -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [PgColumns] -> Encoding $ctoEncodingList :: [PgColumns] -> Encoding toJSONList :: [PgColumns] -> Value $ctoJSONList :: [PgColumns] -> Value toEncoding :: PgColumns -> Encoding $ctoEncoding :: PgColumns -> Encoding toJSON :: PgColumns -> Value $ctoJSON :: PgColumns -> Value ToJSON) data StructureType = StructurePrim { StructureType -> PgPrimName name :: PgPrimName, StructureType -> Bool unique :: Bool, StructureType -> [Sql] constraints :: [Sql] } | StructureComp { StructureType -> PgCompName compName :: PgCompName, StructureType -> PgStructure struct :: PgStructure, unique :: Bool, constraints :: [Sql] } deriving stock (StructureType -> StructureType -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: StructureType -> StructureType -> Bool $c/= :: StructureType -> StructureType -> Bool == :: StructureType -> StructureType -> Bool $c== :: StructureType -> StructureType -> Bool Eq, Int -> StructureType -> ShowS [StructureType] -> ShowS StructureType -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [StructureType] -> ShowS $cshowList :: [StructureType] -> ShowS show :: StructureType -> String $cshow :: StructureType -> String showsPrec :: Int -> StructureType -> ShowS $cshowsPrec :: Int -> StructureType -> ShowS Show, forall x. Rep StructureType x -> StructureType forall x. StructureType -> Rep StructureType x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep StructureType x -> StructureType $cfrom :: forall x. StructureType -> Rep StructureType x Generic) deriving anyclass (Value -> Parser [StructureType] Value -> Parser StructureType forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [StructureType] $cparseJSONList :: Value -> Parser [StructureType] parseJSON :: Value -> Parser StructureType $cparseJSON :: Value -> Parser StructureType FromJSON, [StructureType] -> Encoding [StructureType] -> Value StructureType -> Encoding StructureType -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [StructureType] -> Encoding $ctoEncodingList :: [StructureType] -> Encoding toJSONList :: [StructureType] -> Value $ctoJSONList :: [StructureType] -> Value toEncoding :: StructureType -> Encoding $ctoEncoding :: StructureType -> Encoding toJSON :: StructureType -> Value $ctoJSON :: StructureType -> Value ToJSON) structureToColumn :: StructureType -> ColumnType structureToColumn :: StructureType -> ColumnType structureToColumn = \case StructurePrim {Bool [Sql] PgPrimName constraints :: [Sql] unique :: Bool name :: PgPrimName $sel:constraints:StructurePrim :: StructureType -> [Sql] $sel:unique:StructurePrim :: StructureType -> Bool $sel:name:StructurePrim :: StructureType -> PgPrimName ..} -> ColumnPrim {Bool [Sql] PgPrimName constraints :: [Sql] unique :: Bool name :: PgPrimName $sel:constraints:ColumnPrim :: [Sql] $sel:unique:ColumnPrim :: Bool $sel:name:ColumnPrim :: PgPrimName ..} StructureComp (PgTypeName Text ref) PgStructure _ Bool unique [Sql] constr -> PgTypeRef -> Bool -> [Sql] -> ColumnType ColumnComp (Text -> PgTypeRef PgTypeRef Text ref) Bool unique [Sql] constr instance Pretty PgColumns where pretty :: forall ann. PgColumns -> Doc ann pretty (PgColumns [PgColumn] cs) = forall ann. [Doc ann] -> Doc ann vsep (forall a ann. Pretty a => a -> Doc ann pretty forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [PgColumn] cs) instance ToSql (CommaSep PgColumns) where toSql :: CommaSep PgColumns -> Sql toSql (CommaSep (PgColumns [PgColumn] cols)) = forall a. ToSql a => a -> Sql toSql (forall a. a -> CommaSep a CommaSep (forall a s. Getting a s a -> s -> a view forall a. IsLabel "name" a => a #name forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [PgColumn] cols)) instance ToSql (Create PgColumns) where toSql :: Create PgColumns -> Sql toSql (Create (PgColumns [PgColumn] cols)) = [sql|(##{CommaSep (Create <$> cols)})|] newtype PgStructure = PgStructure { PgStructure -> [(PgColumnName, StructureType)] unPgColumns :: [(PgColumnName, StructureType)] } deriving stock (PgStructure -> PgStructure -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: PgStructure -> PgStructure -> Bool $c/= :: PgStructure -> PgStructure -> Bool == :: PgStructure -> PgStructure -> Bool $c== :: PgStructure -> PgStructure -> Bool Eq, Int -> PgStructure -> ShowS [PgStructure] -> ShowS PgStructure -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [PgStructure] -> ShowS $cshowList :: [PgStructure] -> ShowS show :: PgStructure -> String $cshow :: PgStructure -> String showsPrec :: Int -> PgStructure -> ShowS $cshowsPrec :: Int -> PgStructure -> ShowS Show) deriving newtype (Value -> Parser [PgStructure] Value -> Parser PgStructure forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [PgStructure] $cparseJSONList :: Value -> Parser [PgStructure] parseJSON :: Value -> Parser PgStructure $cparseJSON :: Value -> Parser PgStructure FromJSON, [PgStructure] -> Encoding [PgStructure] -> Value PgStructure -> Encoding PgStructure -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [PgStructure] -> Encoding $ctoEncodingList :: [PgStructure] -> Encoding toJSONList :: [PgStructure] -> Value $ctoJSONList :: [PgStructure] -> Value toEncoding :: PgStructure -> Encoding $ctoEncoding :: PgStructure -> Encoding toJSON :: PgStructure -> Value $ctoJSON :: PgStructure -> Value ToJSON) structureToColumns :: PgStructure -> PgColumns structureToColumns :: PgStructure -> PgColumns structureToColumns (PgStructure [(PgColumnName, StructureType)] cols) = [PgColumn] -> PgColumns PgColumns (forall a b c. (a -> b -> c) -> (a, b) -> c uncurry PgColumnName -> ColumnType -> PgColumn PgColumn forall b c a. (b -> c) -> (a -> b) -> a -> c . forall (p :: * -> * -> *) b c a. Bifunctor p => (b -> c) -> p a b -> p a c second StructureType -> ColumnType structureToColumn forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [(PgColumnName, StructureType)] cols) data PgComposite = PgComposite { PgComposite -> PgCompName name :: PgCompName, PgComposite -> PgColumns columns :: PgColumns } deriving stock (PgComposite -> PgComposite -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: PgComposite -> PgComposite -> Bool $c/= :: PgComposite -> PgComposite -> Bool == :: PgComposite -> PgComposite -> Bool $c== :: PgComposite -> PgComposite -> Bool Eq, Int -> PgComposite -> ShowS [PgComposite] -> ShowS PgComposite -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [PgComposite] -> ShowS $cshowList :: [PgComposite] -> ShowS show :: PgComposite -> String $cshow :: PgComposite -> String showsPrec :: Int -> PgComposite -> ShowS $cshowsPrec :: Int -> PgComposite -> ShowS Show, forall x. Rep PgComposite x -> PgComposite forall x. PgComposite -> Rep PgComposite x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep PgComposite x -> PgComposite $cfrom :: forall x. PgComposite -> Rep PgComposite x Generic) deriving anyclass (Value -> Parser [PgComposite] Value -> Parser PgComposite forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [PgComposite] $cparseJSONList :: Value -> Parser [PgComposite] parseJSON :: Value -> Parser PgComposite $cparseJSON :: Value -> Parser PgComposite FromJSON, [PgComposite] -> Encoding [PgComposite] -> Value PgComposite -> Encoding PgComposite -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [PgComposite] -> Encoding $ctoEncodingList :: [PgComposite] -> Encoding toJSONList :: [PgComposite] -> Value $ctoJSONList :: [PgComposite] -> Value toEncoding :: PgComposite -> Encoding $ctoEncoding :: PgComposite -> Encoding toJSON :: PgComposite -> Value $ctoJSON :: PgComposite -> Value ToJSON) instance Pretty PgComposite where pretty :: forall ann. PgComposite -> Doc ann pretty PgComposite {PgCompName PgColumns columns :: PgColumns name :: PgCompName $sel:columns:PgComposite :: PgComposite -> PgColumns $sel:name:PgComposite :: PgComposite -> PgCompName ..} = forall ann. Int -> Doc ann -> Doc ann nest Int 2 (forall ann. [Doc ann] -> Doc ann vsep [Doc ann "type" forall ann. Doc ann -> Doc ann -> Doc ann <+> forall a ann. Pretty a => a -> Doc ann pretty PgCompName name, forall a ann. Pretty a => a -> Doc ann pretty PgColumns columns]) newtype TableSelectors = TableSelectors { TableSelectors -> [Selector] unTableSelectors :: [Selector] } deriving stock (TableSelectors -> TableSelectors -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: TableSelectors -> TableSelectors -> Bool $c/= :: TableSelectors -> TableSelectors -> Bool == :: TableSelectors -> TableSelectors -> Bool $c== :: TableSelectors -> TableSelectors -> Bool Eq, Int -> TableSelectors -> ShowS [TableSelectors] -> ShowS TableSelectors -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [TableSelectors] -> ShowS $cshowList :: [TableSelectors] -> ShowS show :: TableSelectors -> String $cshow :: TableSelectors -> String showsPrec :: Int -> TableSelectors -> ShowS $cshowsPrec :: Int -> TableSelectors -> ShowS Show, forall x. Rep TableSelectors x -> TableSelectors forall x. TableSelectors -> Rep TableSelectors x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep TableSelectors x -> TableSelectors $cfrom :: forall x. TableSelectors -> Rep TableSelectors x Generic) instance ToSql (CommaSep TableSelectors) where toSql :: CommaSep TableSelectors -> Sql toSql (CommaSep (TableSelectors [Selector] s)) = forall a. ToSql a => a -> Sql toSql (forall a. a -> CommaSep a CommaSep (Selector -> Sql unSelector forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Selector] s)) instance ToSql (Select TableSelectors) where toSql :: Select TableSelectors -> Sql toSql (Select TableSelectors s) = Sql "select " forall a. Semigroup a => a -> a -> a <> forall a. ToSql a => a -> Sql toSql (forall a. a -> CommaSep a CommaSep TableSelectors s) newtype TableValues = TableValues { TableValues -> [Sql] unTableValues :: [Sql] } deriving stock (TableValues -> TableValues -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: TableValues -> TableValues -> Bool $c/= :: TableValues -> TableValues -> Bool == :: TableValues -> TableValues -> Bool $c== :: TableValues -> TableValues -> Bool Eq, Int -> TableValues -> ShowS [TableValues] -> ShowS TableValues -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [TableValues] -> ShowS $cshowList :: [TableValues] -> ShowS show :: TableValues -> String $cshow :: TableValues -> String showsPrec :: Int -> TableValues -> ShowS $cshowsPrec :: Int -> TableValues -> ShowS Show, forall x. Rep TableValues x -> TableValues forall x. TableValues -> Rep TableValues x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep TableValues x -> TableValues $cfrom :: forall x. TableValues -> Rep TableValues x Generic) data PgTable a = PgTable { forall {k} (a :: k). PgTable a -> PgTableName name :: PgTableName, forall {k} (a :: k). PgTable a -> PgColumns columns :: PgColumns, forall {k} (a :: k). PgTable a -> Map PgTypeRef PgComposite types :: Map PgTypeRef PgComposite, forall {k} (a :: k). PgTable a -> TableSelectors selectors :: TableSelectors, forall {k} (a :: k). PgTable a -> TableValues values :: TableValues, forall {k} (a :: k). PgTable a -> PgStructure structure :: PgStructure } deriving stock (Int -> PgTable a -> ShowS forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a forall k (a :: k). Int -> PgTable a -> ShowS forall k (a :: k). [PgTable a] -> ShowS forall k (a :: k). PgTable a -> String showList :: [PgTable a] -> ShowS $cshowList :: forall k (a :: k). [PgTable a] -> ShowS show :: PgTable a -> String $cshow :: forall k (a :: k). PgTable a -> String showsPrec :: Int -> PgTable a -> ShowS $cshowsPrec :: forall k (a :: k). Int -> PgTable a -> ShowS Show, forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a forall k (a :: k) x. Rep (PgTable a) x -> PgTable a forall k (a :: k) x. PgTable a -> Rep (PgTable a) x $cto :: forall k (a :: k) x. Rep (PgTable a) x -> PgTable a $cfrom :: forall k (a :: k) x. PgTable a -> Rep (PgTable a) x Generic) instance Pretty (PgTable a) where pretty :: forall ann. PgTable a -> Doc ann pretty PgTable {Map PgTypeRef PgComposite PgTableName TableValues TableSelectors PgStructure PgColumns structure :: PgStructure values :: TableValues selectors :: TableSelectors types :: Map PgTypeRef PgComposite columns :: PgColumns name :: PgTableName $sel:structure:PgTable :: forall {k} (a :: k). PgTable a -> PgStructure $sel:values:PgTable :: forall {k} (a :: k). PgTable a -> TableValues $sel:selectors:PgTable :: forall {k} (a :: k). PgTable a -> TableSelectors $sel:types:PgTable :: forall {k} (a :: k). PgTable a -> Map PgTypeRef PgComposite $sel:columns:PgTable :: forall {k} (a :: k). PgTable a -> PgColumns $sel:name:PgTable :: forall {k} (a :: k). PgTable a -> PgTableName ..} = forall ann. Int -> Doc ann -> Doc ann nest Int 2 (forall ann. [Doc ann] -> Doc ann vsep ((Doc ann "table" forall ann. Doc ann -> Doc ann -> Doc ann <+> forall a ann. Pretty a => a -> Doc ann pretty PgTableName name) forall a. a -> [a] -> [a] : forall a ann. Pretty a => a -> Doc ann pretty PgColumns columns forall a. a -> [a] -> [a] : (forall a ann. Pretty a => a -> Doc ann pretty forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall k a. Map k a -> [a] Map.elems Map PgTypeRef PgComposite types))) instance ToSql (Create (PgTable a)) where toSql :: Create (PgTable a) -> Sql toSql (Create PgTable {PgTableName name :: PgTableName $sel:name:PgTable :: forall {k} (a :: k). PgTable a -> PgTableName name, PgColumns columns :: PgColumns $sel:columns:PgTable :: forall {k} (a :: k). PgTable a -> PgColumns columns}) = [sql|create table ##{name} ##{Create columns}|] instance ToSql (Select (PgTable a)) where toSql :: Select (PgTable a) -> Sql toSql (Select PgTable {PgTableName name :: PgTableName $sel:name:PgTable :: forall {k} (a :: k). PgTable a -> PgTableName name, TableSelectors selectors :: TableSelectors $sel:selectors:PgTable :: forall {k} (a :: k). PgTable a -> TableSelectors selectors}) = [sql|##{Select selectors} ##{From name}|] instance ToSql (Update (PgTable a)) where toSql :: Update (PgTable a) -> Sql toSql (Update PgTable {$sel:columns:PgTable :: forall {k} (a :: k). PgTable a -> PgColumns columns = PgColumns [PgColumn] columns, $sel:values:PgTable :: forall {k} (a :: k). PgTable a -> TableValues values = TableValues [Sql] values}) = [sql|update set ##{CommaSep assigns}|] where assigns :: [Sql] assigns = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] zipWith Selector -> Sql -> Sql assign [Selector] colNames [Sql] values colNames :: [Selector] colNames = [PgColumn] columns forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b <&> \ (PgColumn (PgColumnName Text name) ColumnType _) -> Text -> Selector nameSelector Text name instance ToSql (Returning (PgTable a)) where toSql :: Returning (PgTable a) -> Sql toSql (Returning (PgTable {TableSelectors selectors :: TableSelectors $sel:selectors:PgTable :: forall {k} (a :: k). PgTable a -> TableSelectors selectors})) = [sql|returning ##{CommaSep selectors}|] instance ToSql (Insert (PgTable a)) where toSql :: Insert (PgTable a) -> Sql toSql (Insert PgTable {PgTableName name :: PgTableName $sel:name:PgTable :: forall {k} (a :: k). PgTable a -> PgTableName name, PgColumns columns :: PgColumns $sel:columns:PgTable :: forall {k} (a :: k). PgTable a -> PgColumns columns, $sel:values:PgTable :: forall {k} (a :: k). PgTable a -> TableValues values = TableValues [Sql] values}) = [sql|insert ##{Into name} (##{CommaSep columns}) values (##{CommaSep values})|] instance ToSql (Delete (PgTable a)) where toSql :: Delete (PgTable a) -> Sql toSql (Delete PgTable {PgTableName name :: PgTableName $sel:name:PgTable :: forall {k} (a :: k). PgTable a -> PgTableName name}) = [sql|delete ##{From name}|]