content: module Database.Selda.Table.Type where
  import Database.Selda.SqlType (SqlTypeRep)
  import Database.Selda.SQL (SQL)
  import Database.Selda.Types ( TableName, ColName )
  import Database.Selda.Exp ( UntypedCol )
  
  -- | A database table, based on some Haskell data type.
  --   Any single constructor type can form the basis of a table, as long as
  --   it derives @Generic@ and all of its fields are instances of @SqlType@.
  data Table a = Table
    { -- | Name of the table. NOT guaranteed to be a valid SQL name.
      tableName :: TableName
  
      -- | All table columns.
      --   Invariant: the 'colAttrs' list of each column is sorted and contains
      --   no duplicates.
    , tableCols :: [ColInfo]
  
      -- | Does the given table have an auto-incrementing primary key?
    , tableHasAutoPK :: Bool
  
      -- | Attributes involving multiple columns.
    , tableAttrs :: [([Int], ColAttr)]
    }
  
  type ColForeignKey = (Table (), ColName, Bool)
  
  -- | A complete description of a database column.
  data ColInfo = ColInfo
    { colName  :: ColName
    , colType  :: SqlTypeRep
    , colAttrs :: [ColAttr]
    , colFKs   :: [ColForeignKey]
    , colExpr  :: UntypedCol SQL
    }
  
  -- | Strongly or weakly auto-incrementing primary key?
  data AutoIncType = Weak | Strong
    deriving (Show, Eq, Ord)
  
  -- | Column attributes such as nullability, auto increment, etc.
  --   When adding elements, make sure that they are added in the order
  --   required by SQL syntax, as this list is only sorted before being
  --   pretty-printed.
  data ColAttr
    = Primary
    | AutoPrimary AutoIncType
    | Required
    | Optional
    | Unique
    | Indexed (Maybe IndexMethod)
    deriving (Show, Eq, Ord)
  
  isAutoPrimary :: ColAttr -> Bool
  isAutoPrimary (AutoPrimary _) = True
  isAutoPrimary _               = False
  
  isPrimary :: ColAttr -> Bool
  isPrimary Primary = True
  isPrimary attr    = isAutoPrimary attr
  
  isUnique :: ColAttr -> Bool
  isUnique Unique      = True
  isUnique (Indexed _) = True
  isUnique attr        = isPrimary attr
  
  -- | Method to use for indexing with 'indexedUsing'.
  --   Index methods are ignored by the SQLite backend, as SQLite doesn't support
  --   different index methods.
  data IndexMethod
    = BTreeIndex
    | HashIndex
  -- Omitted until the operator class business is sorted out
  --  | GistIndex
  --  | GinIndex
    deriving (Show, Eq, Ord)
  