src/Db/Db.php
public function setTableDef($tablename, array $tableDef, array $options = []) {
        $ltablename = strtolower($tablename);
        $tableDef['name'] = $tablename;
        $drop = val(Db::OPTION_DROP, $options, false);
        $curTable = $this->getTableDef($tablename);

        $this->fixIndexes($tablename, $tableDef, $curTable);

        if (!$curTable) {
            $this->createTable($tablename, $tableDef, $options);
            $this->tables[$ltablename] = $tableDef;
            return;
        }
        // This is the alter statement.
        $alterDef = [];

        // Figure out the columns that have changed.
        $curColumns = (array)val('columns', $curTable, []);
        $newColumns = (array)val('columns', $tableDef, []);

        $alterDef['add']['columns'] = array_diff_key($newColumns, $curColumns);
        $alterDef['alter']['columns'] = array_uintersect_assoc($newColumns, $curColumns, function ($new, $curr) {
            // Return 0 if the values are different, not the same.
            if (val('type', $curr) !== val('type', $new) ||
                val('required', $curr) !== val('required', $new) ||
                val('default', $curr) !== val('required', $new)) {
                return 0;
            }
            return 1;
        });

        // Figure out the indexes that have changed.
        $curIndexes = (array)val('indexes', $curTable, []);
        $newIndexes = (array)val('indexes', $tableDef, []);

        $alterDef['add']['indexes'] = array_udiff($newIndexes, $curIndexes, [$this, 'indexCompare']);

        $dropIndexes = array_udiff($curIndexes, $newIndexes, [$this, 'indexCompare']);
        if ($drop) {
            $alterDef['drop']['columns'] = array_diff_key($curColumns, $newColumns);
            $alterDef['drop']['indexes'] = $dropIndexes;
        } else {
            $alterDef['drop']['columns'] = [];
            $alterDef['drop']['indexes'] = [];

            // If the primary key has changed then the old one needs to be dropped.
            if (isset($dropIndexes[Db::INDEX_PK])) {
                $alterDef['drop']['indexes'][Db::INDEX_PK] = $dropIndexes[Db::INDEX_PK];
            }
        }

        // Check to see if any alterations at all need to be made.
        if (empty($alterDef['add']['columns']) && empty($alterDef['add']['indexes']) &&
            empty($alterDef['drop']['columns']) && empty($alterDef['drop']['indexes']) &&
            empty($alterDef['alter']['columns'])) {
            return;
        }

        $alterDef['def'] = $tableDef;

        // Alter the table.
        $this->alterTable($tablename, $alterDef, $options);

        // Update the cached schema.
        $tableDef['name'] = $tablename;
        $this->tables[$ltablename] = $tableDef;
    }
public function setTableDef($tablename, array $tableDef, array $options = []) {
        $ltablename = strtolower($tablename);
        $tableDef['name'] = $tablename;
        $drop = val(Db::OPTION_DROP, $options, false);
        $curTable = $this->getTableDef($tablename);

        $this->fixIndexes($tablename, $tableDef, $curTable);

        if (!$curTable) {
            $this->createTable($tablename, $tableDef, $options);
            $this->tables[$ltablename] = $tableDef;
            return;
        }
        // This is the alter statement.
        $alterDef = [];

        // Figure out the columns that have changed.
        $curColumns = (array)val('columns', $curTable, []);
        $newColumns = (array)val('columns', $tableDef, []);

        $alterDef['add']['columns'] = array_diff_key($newColumns, $curColumns);
        $alterDef['alter']['columns'] = array_uintersect_assoc($newColumns, $curColumns, function ($new, $curr) {
            // Return 0 if the values are different, not the same.
            if (val('type', $curr) !== val('type', $new) ||
                val('required', $curr) !== val('required', $new) ||
                val('default', $curr) !== val('required', $new)) {
                return 0;
            }
            return 1;
        });

        // Figure out the indexes that have changed.
        $curIndexes = (array)val('indexes', $curTable, []);
        $newIndexes = (array)val('indexes', $tableDef, []);

        $alterDef['add']['indexes'] = array_udiff($newIndexes, $curIndexes, [$this, 'indexCompare']);

        $dropIndexes = array_udiff($curIndexes, $newIndexes, [$this, 'indexCompare']);
        if ($drop) {
            $alterDef['drop']['columns'] = array_diff_key($curColumns, $newColumns);
            $alterDef['drop']['indexes'] = $dropIndexes;
        } else {
            $alterDef['drop']['columns'] = [];
            $alterDef['drop']['indexes'] = [];

            // If the primary key has changed then the old one needs to be dropped.
            if (isset($dropIndexes[Db::INDEX_PK])) {
                $alterDef['drop']['indexes'][Db::INDEX_PK] = $dropIndexes[Db::INDEX_PK];
            }
        }

        // Check to see if any alterations at all need to be made.
        if (empty($alterDef['add']['columns']) && empty($alterDef['add']['indexes']) &&
            empty($alterDef['drop']['columns']) && empty($alterDef['drop']['indexes']) &&
            empty($alterDef['alter']['columns'])) {
            return;
        }

        $alterDef['def'] = $tableDef;

        // Alter the table.
        $this->alterTable($tablename, $alterDef, $options);

        // Update the cached schema.
        $tableDef['name'] = $tablename;
        $this->tables[$ltablename] = $tableDef;
    }
Set a table definition to the database.

@param string $tablename The name of the table.
@param array $tableDef The table definition.
@param array $options An array of additional options when adding the table.