Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

356 lines
10 KiB

<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\db;
use Yii;
use yii\base\Object;
/**
* ColumnSchemaBuilder helps to define database schema types using a PHP interface.
*
* See [[SchemaBuilderTrait]] for more detailed description and usage examples.
*
* @author Vasenin Matvey <vaseninm@gmail.com>
* @since 2.0.6
*/
class ColumnSchemaBuilder extends Object
{
/**
* The following are the categories of column data types.
* @since 2.0.8
*/
const CAT_PK = 'pk';
const CAT_STRING = 'string';
const CAT_NUMERIC = 'numeric';
const CAT_TIME = 'time';
const CAT_OTHER = 'other';
/**
* @var string the column type definition such as INTEGER, VARCHAR, DATETIME, etc.
*/
protected $type;
/**
* @var integer|string|array column size or precision definition. This is what goes into the parenthesis after
* the column type. This can be either a string, an integer or an array. If it is an array, the array values will
* be joined into a string separated by comma.
*/
protected $length;
/**
* @var boolean whether the column is not nullable. If this is `true`, a `NOT NULL` constraint will be added.
*/
protected $isNotNull = false;
/**
* @var boolean whether the column values should be unique. If this is `true`, a `UNIQUE` constraint will be added.
*/
protected $isUnique = false;
/**
* @var string the `CHECK` constraint for the column.
*/
protected $check;
/**
* @var mixed default value of the column.
*/
protected $default;
/**
* @var boolean whether the column values should be unsigned. If this is `true`, an `UNSIGNED` keyword will be added.
* @since 2.0.7
*/
protected $isUnsigned = false;
/**
* @var string the column after which this column will be added.
* @since 2.0.8
*/
protected $after;
/**
* @var boolean whether this column is to be inserted at the beginning of the table.
* @since 2.0.8
*/
protected $isFirst;
/**
* @var array mapping of type categories (keys) to abstract column types (values).
*/
public $categoryMap = [
Schema::TYPE_PK => self::CAT_PK,
Schema::TYPE_BIGPK => self::CAT_PK,
Schema::TYPE_UNSIGNEDPK => self::CAT_PK,
Schema::TYPE_CHAR => self::CAT_STRING,
Schema::TYPE_STRING => self::CAT_STRING,
Schema::TYPE_TEXT => self::CAT_STRING,
Schema::TYPE_SMALLINT => self::CAT_NUMERIC,
Schema::TYPE_INTEGER => self::CAT_NUMERIC,
Schema::TYPE_BIGINT => self::CAT_NUMERIC,
Schema::TYPE_FLOAT => self::CAT_NUMERIC,
Schema::TYPE_DOUBLE => self::CAT_NUMERIC,
Schema::TYPE_DECIMAL => self::CAT_NUMERIC,
Schema::TYPE_DATETIME => self::CAT_TIME,
Schema::TYPE_TIMESTAMP => self::CAT_TIME,
Schema::TYPE_TIME => self::CAT_TIME,
Schema::TYPE_DATE => self::CAT_TIME,
Schema::TYPE_BINARY => self::CAT_OTHER,
Schema::TYPE_BOOLEAN => self::CAT_NUMERIC,
Schema::TYPE_MONEY => self::CAT_NUMERIC,
];
/**
* Create a column schema builder instance giving the type and value precision.
*
* @param string $type type of the column. See [[$type]].
* @param integer|string|array $length length or precision of the column. See [[$length]].
* @param array $config name-value pairs that will be used to initialize the object properties
*/
public function __construct($type, $length = null, $config = [])
{
$this->type = $type;
$this->length = $length;
parent::__construct($config);
}
/**
* Adds a `NOT NULL` constraint to the column.
* @return $this
*/
public function notNull()
{
$this->isNotNull = true;
return $this;
}
/**
* Adds a `UNIQUE` constraint to the column.
* @return $this
*/
public function unique()
{
$this->isUnique = true;
return $this;
}
/**
* Sets a `CHECK` constraint for the column.
* @param string $check the SQL of the `CHECK` constraint to be added.
* @return $this
*/
public function check($check)
{
$this->check = $check;
return $this;
}
/**
* Specify the default value for the column.
* @param mixed $default the default value.
* @return $this
*/
public function defaultValue($default)
{
$this->default = $default;
return $this;
}
/**
* Marks column as unsigned.
* @return $this
* @since 2.0.7
*/
public function unsigned()
{
$this->isUnsigned = true;
return $this;
}
/**
* Adds an `AFTER` constraint to the column.
* Note: MySQL, Oracle and Cubrid support only.
* @param string $after the column after which $this column will be added.
* @return $this
* @since 2.0.8
*/
public function after($after)
{
$this->after = $after;
return $this;
}
/**
* Adds an `FIRST` constraint to the column.
* Note: MySQL, Oracle and Cubrid support only.
* @return $this
* @since 2.0.8
*/
public function first()
{
$this->isFirst = true;
return $this;
}
/**
* Specify the default SQL expression for the column.
* @param string $default the default value expression.
* @return $this
* @since 2.0.7
*/
public function defaultExpression($default)
{
$this->default = new Expression($default);
return $this;
}
/**
* Builds the full string for the column's schema
* @return string
*/
public function __toString()
{
switch ($this->getTypeCategory()) {
case self::CAT_PK:
$format = '{type}{length}{pos}';
break;
default:
$format = '{type}{length}{notnull}{unique}{default}{check}';
}
return $this->buildCompleteString($format);
}
/**
* Builds the length/precision part of the column.
* @return string
*/
protected function buildLengthString()
{
if ($this->length === null || $this->length === []) {
return '';
}
if (is_array($this->length)) {
$this->length = implode(',', $this->length);
}
return "({$this->length})";
}
/**
* Builds the not null constraint for the column.
* @return string returns 'NOT NULL' if [[isNotNull]] is true, otherwise it returns an empty string.
*/
protected function buildNotNullString()
{
return $this->isNotNull ? ' NOT NULL' : '';
}
/**
* Builds the unique constraint for the column.
* @return string returns string 'UNIQUE' if [[isUnique]] is true, otherwise it returns an empty string.
*/
protected function buildUniqueString()
{
return $this->isUnique ? ' UNIQUE' : '';
}
/**
* Builds the default value specification for the column.
* @return string string with default value of column.
*/
protected function buildDefaultString()
{
if ($this->default === null) {
return '';
}
$string = ' DEFAULT ';
switch (gettype($this->default)) {
case 'integer':
$string .= (string) $this->default;
break;
case 'double':
// ensure type cast always has . as decimal separator in all locales
$string .= str_replace(',', '.', (string) $this->default);
break;
case 'boolean':
$string .= $this->default ? 'TRUE' : 'FALSE';
break;
case 'object':
$string .= (string) $this->default;
break;
default:
$string .= "'{$this->default}'";
}
return $string;
}
/**
* Builds the check constraint for the column.
* @return string a string containing the CHECK constraint.
*/
protected function buildCheckString()
{
return $this->check !== null ? " CHECK ({$this->check})" : '';
}
/**
* Builds the unsigned string for column. Defaults to unsupported.
* @return string a string containing UNSIGNED keyword.
* @since 2.0.7
*/
protected function buildUnsignedString()
{
return '';
}
/**
* Builds the after constraint for the column. Defaults to unsupported.
* @return string a string containing the AFTER constraint.
* @since 2.0.8
*/
protected function buildAfterString()
{
return '';
}
/**
* Builds the first constraint for the column. Defaults to unsupported.
* @return string a string containing the FIRST constraint.
* @since 2.0.8
*/
protected function buildFirstString()
{
return '';
}
/**
* Returns the category of the column type.
* @return string a string containing the column type category name.
* @since 2.0.8
*/
protected function getTypeCategory()
{
return $this->categoryMap[$this->type];
}
/**
* Returns the complete column definition from input format
* @param string $format the format of the definition.
* @return string a string containing the complete column definition.
* @since 2.0.8
*/
protected function buildCompleteString($format)
{
$placeholderValues = [
'{type}' => $this->type,
'{length}' => $this->buildLengthString(),
'{unsigned}' => $this->buildUnsignedString(),
'{notnull}' => $this->buildNotNullString(),
'{unique}' => $this->buildUniqueString(),
'{default}' => $this->buildDefaultString(),
'{check}' => $this->buildCheckString(),
'{pos}' => ($this->isFirst) ?
$this->buildFirstString() :
$this->buildAfterString(),
];
return $text = strtr($format, $placeholderValues);
}
}