Change a table column type.

@param string        $columnName    Column Name
@param string|\Phinx\Db\Table\Column|\Phinx\Util\Literal $newColumnType New Column Type
@param array         $options       Options
@return \Phinx\Db\Table
5404
public function changeColumn($columnName, $newColumnType, array $options = [])
    {
        if ($newColumnType instanceof Column) {
            $action = new ChangeColumn($this->table, $columnName, $newColumnType);
        } else {
            $action = ChangeColumn::build($this->table, $columnName, $newColumnType, $options);
        }
        $this->actions->addAction($action);

        return $this;
    }
235635
public function column(string $columnName): ColumnTypeDefiner
    {
        return new ColumnTypeDefiner(
            $this,
            function (Column $column) {
                $this->addColumn($column);
            },
            $columnName
        );
    }
783564
final private static function getColumnType($fieldName) {
		
		$db = Database::getInstance();
		$column = $db->describeColumn(static::TABLE_NAME, $fieldName);
		
		if (is_null($column)) {
			return NULL;
		}
		
		// split the column Type to recognize field type and length
		preg_match('#^([\w]+)(\([^\)]+\))? ?(unsigned)?#i', $column->Type, $matches);
		
		$field = new \stdClass();
		
		$field->name	= $fieldName;
		$field->type	= $matches[1];
		$field->unsigned= (isset($matches[3]));
		$field->nullable= 'YES' == $column->Null ? TRUE : FALSE;
		$field->key		= $column->Key;
		$field->default	= $column->Default;
		$field->extra	= $column->Extra;

		if (isset($matches[2])) {
			if (in_array($field->type, ['enum','set'])) {
				$field->length = explode("','", substr($matches[2], 2, -2));
			} else {
				$field->length = explode(",", substr($matches[2], 1, -1));
			}
		} else {
			$field->length = NULL;
		}
		
		return $field;
		
	}
977608
private function getTableColumnTypes($tableName)
    {
        $columnTypes = array();
        $columns = $this->dbHandler->query(
            $this->typeAdapter->show_columns($tableName)
        );
        $columns->setFetchMode(PDO::FETCH_ASSOC);

        foreach ($columns as $key => $col) {
            $types = $this->typeAdapter->parseColumnType($col);
            $columnTypes[$col['Field']] = array(
                'is_numeric'=> $types['is_numeric'],
                'is_blob' => $types['is_blob'],
                'type' => $types['type'],
                'type_sql' => $col['Type'],
                'is_virtual' => $types['is_virtual']
            );
        }

        return $columnTypes;
    }
945023
public function changeColumn($columnName, array $options)
    {
        $column = $this->getColumn($columnName);
        $column->setOptions($options);

        return $this;
    }
1072376
public function modifyColumn(
        $name,
        $type = 'text',
        $signed = true,
        $allowNull = true,
        $default = '',
        $comment = '',
        $options = []
    ) {
        $column = $name;

        if ($column instanceof Column) {
            $name = $column->getName();
            $type = $column->getType();
            $length = $column->getLength();
            $allowNull = $column->getAllowNull();
            $default = $column->getDefault();
            $comment = $column->getComment();
        }

        if (!$this->hasColumn($name)) {
            return $this;
        }

        $type = SqlsrvType::getType($type);
        $length = $length ?? SqlsrvType::getLength($type);
        $length = SqlsrvType::noLength($type) ? null : $length;
        $length = $length ? '(' . $length . ')' : null;

        $query = $this->db->getQuery(true);

        // Sqlsrv must drop default constraint first
        $q = <<<SQL
DECLARE @ConstraintName nvarchar(200)
    
SELECT @ConstraintName = Name FROM SYS.DEFAULT_CONSTRAINTS
WHERE PARENT_OBJECT_ID = OBJECT_ID(%q)
AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns
                        WHERE NAME = N%q
                        AND object_id = OBJECT_ID(N%q))
    
IF @ConstraintName IS NOT NULL
EXEC('ALTER TABLE %n DROP CONSTRAINT [' + @ConstraintName + ']')
SQL;

        $table = $this->db->replacePrefix($this->getName());

        $this->db->execute($query->format($q, $table, $name, $table, $table));

        // Type
        $this->db->execute(SqlsrvGrammar::build(
            'ALTER TABLE',
            $query->quoteName($this->getName()),
            'ALTER COLUMN',
            $query->quoteName($name),
            $type . $length,
            $allowNull ? null : 'NOT NULL'
        ));

        if ($default !== false) {
            $this->db->execute(SqlsrvGrammar::build(
                'ALTER TABLE',
                $query->quoteName($this->getName()),
                'ADD DEFAULT',
                $query->validValue($default),
                'FOR',
                $query->quoteName($name)
            ));
        }

        if ($comment) {
            $this->db->execute(SqlsrvGrammar::comment(
                'COLUMN',
                $this->db->replacePrefix($this->getName()),
                $column->getName(),
                $comment
            ));
        }

        return $this->reset();
    }
1155480
public function addIndex($columnName, $type = Table::INDEX_REGULAR) {
        if (!array_key_exists($columnName, $this->getIndexes()) && !array_key_exists($columnName,
                        $this->newIndexes))
                $this->newIndexes[$columnName] = $type;
        return $this;
    }
1330230
public function addIndex(array $columnNames, $indexName = null, array $flags = [], array $options = [])
    {
        if ($indexName === null) {
            $indexName = $this->_generateIdentifierName(
                array_merge([$this->getName()], $columnNames),
                'idx',
                $this->_getMaxIdentifierLength()
            );
        }

        return $this->_addIndex($this->_createIndex($columnNames, $indexName, false, false, $flags, $options));
    }
485156
private function alterTableMigrate(array $alterDef, array $options = []) {
        $table = $alterDef['name'];
        $currentDef = $this->fetchTableDef($table);

        // Merge the table definitions if we aren't dropping stuff.
        if (!self::val(Db::OPTION_DROP, $options)) {
            $tableDef = $this->mergeTableDefs($currentDef, $alterDef);
        } else {
            $tableDef = $alterDef['def'];
        }

        // Drop all of the indexes on the current table.
        foreach (self::val('indexes', $currentDef, []) as $indexDef) {
            if (self::val('type', $indexDef, Db::INDEX_IX) === Db::INDEX_IX) {
                $this->dropIndex($indexDef['name']);
            }
        }

        $tmpTable = $table.'_'.time();

        // Rename the current table.
        $this->renameTable($table, $tmpTable);

        // Create the new table.
        $this->createTableDb($tableDef, $options);

        // Figure out the columns that we can insert.
        $columns = array_keys(array_intersect_key($tableDef['columns'], $currentDef['columns']));

        // Build the insert/select statement.
        $sql = 'insert into '.$this->prefixTable($table)."\n".
            $this->bracketList($columns, '`')."\n".
            $this->buildSelect($tmpTable, [], ['columns' => $columns]);

        $this->queryDefine($sql);

        // Drop the temp table.
        $this->dropTable($tmpTable);
    }
776378
public function createListColumn($columnName, $listColumnTypeClass = ColumnType::class, array $options = array())
    {
        $listColumnBuilder = $this->createListColumnBuilder($columnName, $listColumnTypeClass, $options);
        return $listColumnBuilder->getListColumn();
    }
166113
public function createType($type, array $options = [])
    {
        $class = isset($this->mappingTypeList[$type]) ? $this->mappingTypeList[$type] : $type;
        if (!class_exists($class)) {
            throw new DataTypeNotFoundException($type, $class);
        }

        return new MetadataType($class, $options);
    }
457078
public static function processSingleColumn($column_name, $column_options, $data, $options = []) {
		$result = [];
		// process domain
		if (!empty($options['process_domains'])) {
			$temp = [$column_name => $column_options];
			$temp = \Object\Data\Common::processDomainsAndTypes($temp);
			$column_options = $temp[$column_name];
		}
		// if we ignoring not set fields
		if (!empty($options['ignore_not_set_fields']) && !array_key_exists($column_name, $data)) {
			return $result;
		}
		// processing
		$value = $data[$column_name] ?? null;
		if (is_array($value)) {
			$result2 = [];
			foreach ($value as $k => $v) {
				$temp = self::processSingleColumnType($column_name, $column_options, $v, ['ignore_defaults' => $options['ignore_defaults'] ?? false]);
				if (array_key_exists($column_name, $temp) && $temp[$column_name] !== null) {
					$result2[] = $temp[$column_name];
				}
			}
			$result[$column_name] = $result2;
		} else {
			$result = self::processSingleColumnType($column_name, $column_options, $value, ['ignore_defaults' => $options['ignore_defaults'] ?? false]);
		}
		return $result;
	}
137585
public function add($id, $columnClass, array $options = array())
    {
        $this->columns[$id] = array(
            'class' => $columnClass,
            'options' => $options,
        );

        return $this;
    }
1294929
public function type($type, $config = null)
    {
        if ($config) {
            $this->_types[$type] = $config;
        }
        if (!isset($this->_types[$type])) {
            throw new SqlException("Column type `'{$type}'` does not exist.");
        }
        return $this->_types[$type];
    }
485340
public boolean changeColumn (Connection conn, String table, String column, String type,
                                 Boolean nullable, Boolean unique, String defaultValue)
        throws SQLException
    {
        String defStr = expandDefinition(type, nullable != null ? nullable : false,
                                         unique != null ? unique : false, defaultValue);

        executeQuery(conn, "ALTER TABLE " + tableSQL(table) + " CHANGE " +
                     columnSQL(column) + " " + columnSQL(column) + " " + defStr);
        log("Database column '" + column + "' of table '" + table + "' modified to have " +
            "definition '" + defStr + "'.");
        return true;
    }
992600
public static function toMigrationMethodName($type, $columnName)
    {
        $typeMap = self::getDoctrineTypeMap();

        if (!in_array($type, $typeMap)) {
            throw new SystemException(sprintf('Unknown column type: %s', $type));
        }

        // Some Doctrine types map to multiple migration types, for example
        // Doctrine boolean could be boolean and tinyInteger in migrations.
        // Some guessing could be required in this method. The method is not
        // 100% reliable.

        if ($type == DoctrineType::DATETIME) {
            // The datetime type maps to datetime and timestamp. Use the name 
            // guessing as the only possible solution.

            if (in_array($columnName, ['created_at', 'updated_at', 'deleted_at', 'published_at', 'deleted_at'])) {
                return self::TYPE_TIMESTAMP;
            }

            return self::TYPE_DATETIME;
        }

        $typeMap = array_flip($typeMap);
        return $typeMap[$type];
    }
453230
public function addIndex($type, $columns = [], $name = null, $comment = null, $options = [])
    {
        if (!$type instanceof Key) {
            if (!$columns) {
                throw new \InvalidArgumentException('No columns given.');
            }

            $columns = (array) $columns;

            $index = new Key($type, $columns, $name, $comment);
        } else {
            $index = $type;
        }

        if ($this->hasIndex($index->getName())) {
            $this->dropIndex($index->getName());
        }

        $query = SqlsrvGrammar::addIndex(
            $this->db->replacePrefix($this->getName()),
            strtolower($index->getType()) === 'key' ? 'INDEX' : $index->getType(),
            $index->getColumns(),
            $index->getName()
        );

        $this->db->execute($query);

        // No index comment now.
//        if ($index->getComment()) {
//            $query = SqlsrvGrammar::comment('INDEX', 'public', $index->getName(), $index->getComment());
//
//            $this->db->setQuery($query)->execute();
//        }

        return $this->reset();
    }