content: -- | An interpretation of Codd's Relational Model, as described in 'A Relational Model of Data for Large Shared Data Banks' (1970). Types ('domains') and values are parameterized so as to allow for application-specific implementations. No special support is provided for 'nonsimple' domains; i.e. relations are assumed to be normalized.
  
  module Hydra.Relational where
  
  import qualified Hydra.Core as Core
  import Prelude hiding  (Enum, Ordering, fail, map, pure, sum)
  import qualified Data.Int as I
  import qualified Data.List as L
  import qualified Data.Map as M
  import qualified Data.Set as S
  
  -- | A name for a domain which serves to identify the role played by that domain in the given relation; a 'role name' in Codd
  newtype ColumnName = 
    ColumnName {
      unColumnName :: String}
    deriving (Eq, Ord, Read, Show)
  
  _ColumnName = (Core.Name "hydra.relational.ColumnName")
  
  -- | An abstract specification of the domain represented by a column in a relation; a role
  data ColumnSchema t = 
    ColumnSchema {
      -- | A unique name for the column
      columnSchemaName :: ColumnName,
      -- | The domain (type) of the column
      columnSchemaDomain :: t}
    deriving (Eq, Ord, Read, Show)
  
  _ColumnSchema = (Core.Name "hydra.relational.ColumnSchema")
  
  _ColumnSchema_name = (Core.Name "name")
  
  _ColumnSchema_domain = (Core.Name "domain")
  
  -- | A mapping from certain columns of a source relation to primary key columns of a target relation
  data ForeignKey = 
    ForeignKey {
      -- | The name of the target relation
      foreignKeyForeignRelation :: RelationName,
      -- | The mapping of source column names to target column names. The target column names must together make up the primary key of the target relation.
      foreignKeyKeys :: (M.Map ColumnName ColumnName)}
    deriving (Eq, Ord, Read, Show)
  
  _ForeignKey = (Core.Name "hydra.relational.ForeignKey")
  
  _ForeignKey_foreignRelation = (Core.Name "foreignRelation")
  
  _ForeignKey_keys = (Core.Name "keys")
  
  -- | A primary key of a relation, specified either as a single column, or as a list of columns
  newtype PrimaryKey = 
    PrimaryKey {
      unPrimaryKey :: [ColumnName]}
    deriving (Eq, Ord, Read, Show)
  
  _PrimaryKey = (Core.Name "hydra.relational.PrimaryKey")
  
  -- | A set of distinct n-tuples; a table
  newtype Relation v = 
    Relation {
      unRelation :: [Row v]}
    deriving (Eq, Ord, Read, Show)
  
  _Relation = (Core.Name "hydra.relational.Relation")
  
  -- | A unique relation (table) name
  newtype RelationName = 
    RelationName {
      unRelationName :: String}
    deriving (Eq, Ord, Read, Show)
  
  _RelationName = (Core.Name "hydra.relational.RelationName")
  
  -- | An abstract relation; the name and columns of a relation without its actual data
  data RelationSchema t = 
    RelationSchema {
      -- | A unique name for the relation
      relationSchemaName :: RelationName,
      -- | A list of column specifications
      relationSchemaColumns :: [ColumnSchema t],
      -- | Any number of primary keys for the relation, each of which must be valid for this relation
      relationSchemaPrimaryKeys :: [PrimaryKey],
      -- | Any number of foreign keys, each of which must be valid for both this relation and the target relation
      relationSchemaForeignKeys :: [ForeignKey]}
    deriving (Eq, Ord, Read, Show)
  
  _RelationSchema = (Core.Name "hydra.relational.RelationSchema")
  
  _RelationSchema_name = (Core.Name "name")
  
  _RelationSchema_columns = (Core.Name "columns")
  
  _RelationSchema_primaryKeys = (Core.Name "primaryKeys")
  
  _RelationSchema_foreignKeys = (Core.Name "foreignKeys")
  
  -- | A domain-unordered (string-indexed, rather than position-indexed) relation
  newtype Relationship v = 
    Relationship {
      unRelationship :: (S.Set (M.Map ColumnName v))}
    deriving (Eq, Ord, Read, Show)
  
  _Relationship = (Core.Name "hydra.relational.Relationship")
  
  -- | An n-tuple which is an element of a given relation
  newtype Row v = 
    Row {
      unRow :: [v]}
    deriving (Eq, Ord, Read, Show)
  
  _Row = (Core.Name "hydra.relational.Row")
  