<?php
/**
 * Database query class for ALTER TABLE queries
 *
 * This file is part of Zoph.
 *
 * Zoph is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Zoph is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with Zoph; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @package Zoph
 * @author Jeroen Roos
 */

namespace db;

use db\exception\hasAlterationException as dbAlterTableHasAlterationException;
use db\exception\hasNoAlterationException as dbAlterTableHasNoAlterationException;
use db\exception\unsupportedEngineException as dbAlterTableUnsupportedEngineException;

/**
 * The alter object is used to create ALTER TABLE queries
 *
 * ALTER TABLE has quite a few options, for now the following are planned:
 *
 * ADD COLUMN column_name column_definition [ FIRST | AFTER column ]
 * DROP COLUMN column_name
 * MODIFY COLUMN column_name column_definition [ FIRST | AFTER column ]
 * CHANGE COLUMN column_name new_column_name column_definition [ FIRST | AFTER column ]
 *
 * in the future, ADD / DROP / RENAME INDEX and RENAME will probably be added, others when needed.
 *
 * MySQL allows multiple alterations in a single command, this class will not.
 *
 * @package Zoph
 * @author Jeroen Roos
 */
class alter extends query {
    /** @var array Supported MySQL/Mariadb engines */
    private static $engines = array("MyISAM", "InnoDB");

    /** @var string alteration [ ADD | MODIFY | CHANGE | DROP ] for this query */
    private $alteration;

    /** @var string after [ FIRST | AFTER <col> ] for this query */
    private $after="";

    /**
     * Create INSERT query
     * @return string SQL query
     */
    public function __toString() {
        $sql = "ALTER TABLE " . $this->table;

        if (empty($this->alteration)) {
            throw new dbAlterTableHasNoAlterationException();
        }

        $sql .= " " . $this->alteration . $this->after;

        return $sql . ";";
    }

    public function addColumn(column $column) {
        if (!empty($this->alteration)) {
            throw new dbAlterTableHasAlterationException();
        }
        $this->alteration="ADD COLUMN " . (string) $column;
        return $this;
    }

    public function modifyColumn(column $column) {
        if (!empty($this->alteration)) {
            throw new dbAlterTableHasAlterationException();
        }
        $this->alteration="MODIFY COLUMN " . (string) $column;
        return $this;
    }

    public function changeColumn(string $col, column $column) {
        if (!empty($this->alteration)) {
            throw new dbAlterTableHasAlterationException();
        }
        $this->alteration="CHANGE COLUMN " . $col . " " . (string) $column;
        return $this;
    }

    public function dropColumn(string $col) {
        if (!empty($this->alteration)) {
            throw new dbAlterTableHasAlterationException();
        }
        $this->alteration="DROP COLUMN " . $col;
        return $this;
    }

    public function first() {
        $this->after = " FIRST";
        return $this;
    }

    public function after(string $col) {
        $this->after = " AFTER " . $col;
        return $this;
    }

    /**
     * Change MySQL/MariaDB Engine
     * @see @var $engines for supported engines
     * @param string engine
     * @return alter for concatenation of methods
     */
    public function setEngine(string $engine) {
        if (in_array($engine, static::$engines)) {
            if (!empty($this->alteration)) {
                throw new dbAlterTableHasAlterationException();
            }
            $this->alteration="ENGINE = \"" . $engine . "\"";
        } else {
            throw new dbAlterTableUnsupportedEngineException("Unknown database engine: " . $engine);
        }
        return $this;
    }
}
