/**
  * Generate the following table in the database, modifying whatever already exists
  * as necessary.
  *
  * @todo Change detection for CREATE TABLE $options other than "Engine"
  *
  * @param string $table The name of the table
  * @param array $fieldSchema A list of the fields to create, in the same form as DataObject::$db
  * @param array $indexSchema A list of indexes to create. See {@link requireIndex()}
  * The values of the array can be one of:
  *   - true: Create a single column index on the field named the same as the index.
  *   - array('fields' => array('A','B','C'), 'type' => 'index/unique/fulltext'): This gives you full
  *     control over the index.
  * @param boolean $hasAutoIncPK A flag indicating that the primary key on this table is an autoincrement type
  * @param array $options Create table options (ENGINE, etc.)
  * @param array|bool $extensions List of extensions
  */
 public function requireTable($table, $fieldSchema = null, $indexSchema = null, $hasAutoIncPK = true, $options = array(), $extensions = false)
 {
     if (!isset($this->tableList[strtolower($table)])) {
         $this->transCreateTable($table, $options, $extensions);
         $this->alterationMessage("Table {$table}: created", "created");
     } else {
         if (Config::inst()->get(static::class, 'fix_table_case_on_build')) {
             $this->fixTableCase($table);
         }
         if (Config::inst()->get(static::class, 'check_and_repair_on_build')) {
             $this->checkAndRepairTable($table);
         }
         // Check if options changed
         $tableOptionsChanged = false;
         // Check for DB constant on the schema class
         $dbIDName = sprintf('%s::ID', get_class($this));
         $dbID = defined($dbIDName) ? constant($dbIDName) : null;
         if ($dbID && isset($options[$dbID])) {
             if (preg_match('/ENGINE=([^\\s]*)/', $options[$dbID], $alteredEngineMatches)) {
                 $alteredEngine = $alteredEngineMatches[1];
                 $tableStatus = $this->query(sprintf('SHOW TABLE STATUS LIKE \'%s\'', $table))->first();
                 $tableOptionsChanged = $tableStatus['Engine'] != $alteredEngine;
             }
         }
         if ($tableOptionsChanged || $extensions && $this->database->supportsExtensions($extensions)) {
             $this->transAlterTable($table, $options, $extensions);
         }
     }
     //DB ABSTRACTION: we need to convert this to a db-specific version:
     if (!isset($fieldSchema['ID'])) {
         $this->requireField($table, 'ID', $this->IdColumn(false, $hasAutoIncPK));
     }
     // Create custom fields
     if ($fieldSchema) {
         foreach ($fieldSchema as $fieldName => $fieldSpec) {
             //Is this an array field?
             $arrayValue = '';
             if (strpos($fieldSpec, '[') !== false) {
                 //If so, remove it and store that info separately
                 $pos = strpos($fieldSpec, '[');
                 $arrayValue = substr($fieldSpec, $pos);
                 $fieldSpec = substr($fieldSpec, 0, $pos);
             }
             /** @var DBField $fieldObj */
             $fieldObj = Object::create_from_string($fieldSpec, $fieldName);
             $fieldObj->setArrayValue($arrayValue);
             $fieldObj->setTable($table);
             if ($fieldObj instanceof DBPrimaryKey) {
                 /** @var DBPrimaryKey $fieldObj */
                 $fieldObj->setAutoIncrement($hasAutoIncPK);
             }
             $fieldObj->requireField();
         }
     }
     // Create custom indexes
     if ($indexSchema) {
         foreach ($indexSchema as $indexName => $indexDetails) {
             $this->requireIndex($table, $indexName, $indexDetails);
         }
     }
 }