tp6混合easyswoole DLL 多应用模式 修改版
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.

416 lines
11 KiB

<?php
namespace EasySwoole\DDL\Blueprint;
use EasySwoole\DDL\Enum\DataType;
use EasySwoole\DDL\Filter\FilterLimit;
use EasySwoole\DDL\Filter\FilterUnsigned;
use EasySwoole\DDL\Filter\FilterZerofill;
use InvalidArgumentException;
/**
* 字段构造器
* Class Column
* @package EasySwoole\DDL\Blueprint
*/
class Column
{
protected $columnName; // 字段名称
protected $columnType; // 字段类型
protected $columnLimit; // 字段限制 如 INT(11) / decimal(10,2) 括号部分
protected $columnComment; // 字段注释
protected $columnCharset; // 字段编码
protected $isBinary; // 二进制 (只允许在字符串类型上设置)
protected $isUnique; // 唯一的 (请勿重复设置索引UNI)
protected $unsigned; // 无符号 (仅数字类型可以设置)
protected $zeroFill; // 零填充 (仅数字类型可以设置)
protected $defaultValue; // 默认值 (非TEXT/BLOB可以设置)
protected $isNotNull = true; // 字段可空 (默认已经设置全部字段不可空)
protected $autoIncrement; // 字段自增 (仅数字类型可以设置)
protected $isPrimaryKey; // 主键字段 (请勿重复设置索引PK)
/**
* Column constructor.
* @param string $columnName 列的名称
* @param string $columnType 列的类型
*/
function __construct(string $columnName, string $columnType)
{
$this->setColumnName($columnName);
$this->setColumnType($columnType);
}
/**
* 是否无符号
* @param bool $enable
* @return Column
*/
function setIsUnsigned(bool $enable = true): Column
{
// TODO 暂未做规范判断
// 同样需要做规范判断 字段为文本/日期时间/BLOB时不能设置为无符号
$this->unsigned = $enable;
return $this;
}
/**
* 是否值自增
* @param bool $enable
* @return Column
*/
function setIsAutoIncrement(bool $enable = true): Column
{
// TODO 暂未做规范判断
// 同样需要做规范判断 只有数字类型才允许自增
$this->autoIncrement = $enable;
return $this;
}
/**
* 转化为字符串
* @return string
*/
function __toString()
{
return $this->__createDDL();
}
/**
* 创建DDL
* 带下划线的方法请不要外部调用
* @return string
*/
function __createDDL(): string
{
FilterLimit::run($this);//检测limit是否合法
FilterUnsigned::run($this); //检测无符号类型
FilterZerofill::run($this); //检测是否补充长度
$default = $this->parseDefaultValue();
$columnCharset = $this->columnCharset ? explode('_', $this->columnCharset)[0] : false;
return implode(' ',
array_filter(
[
'`' . $this->columnName . '`',
(string)$this->parseDataType(),
$this->isBinary ? 'BINARY' : null,
$this->columnCharset ? 'CHARACTER SET ' . strtoupper($columnCharset) . ' COLLATE ' . strtoupper($this->columnCharset) : null,
$this->unsigned ? 'UNSIGNED' : null,
$this->zeroFill ? 'ZEROFILL' : null,
$this->isUnique ? 'UNIQUE' : null,
$this->isNotNull ? 'NOT NULL' : 'NULL',
$default !== false ? 'DEFAULT ' . $default : null,
$this->isPrimaryKey ? 'PRIMARY KEY' : null,
$this->autoIncrement ? 'AUTO_INCREMENT' : null,
$this->columnComment ? sprintf("COMMENT '%s'", addslashes($this->columnComment)) : null
]
)
);
}
/**
* 处理字段的默认值
* @return bool|string
*/
private function parseDefaultValue()
{
// AUTO_INCREMENT 和默认值不能同时出现
if ($this->autoIncrement) {
return false;
}
// 如果当前允许NULL值 而没有设置默认值 那么默认就为NULL
if (!$this->isNotNull && ($this->defaultValue == null || $this->defaultValue == 'NULL')) {
return 'NULL';
}
// 否则字段是不允许NULL值的 如果默认值是文本应该加入引号
if (is_string($this->defaultValue) && !DataType::typeIsDatetime($this->parseDataType())) {
return "'" . $this->defaultValue . "'";
} else if (is_bool($this->defaultValue)) { // 布尔类型强转0和1
return $this->defaultValue ? '1' : '0';
} else if (is_null($this->defaultValue)) {
return false;
} else if (DataType::typeIsDatetime($this->parseDataType())) { // 其他类型强转String
if (stripos($this->defaultValue, "CURRENT_TIMESTAMP") === false) {
return "'" . $this->defaultValue . "'";
}
return $this->defaultValue;
} else {
return (string)$this->defaultValue;
}
}
/**
* 处理数据类型
* @return string
*/
private function parseDataType()
{
$columnLimit = $this->parseColumnLimit();
$columnType = $this->columnType;
if ($columnLimit) {
$columnType .= $columnLimit;
}
return $columnType;
}
/**
* 处理字段的类型宽度限制
* @return bool|string
*/
private function parseColumnLimit()
{
// 是一个数组需要用逗号接起来
if (is_array($this->columnLimit)) {
return "(" . implode(',', $this->columnLimit) . ")";
}
// 是一个数字可以直接设置在类型后面
if (is_numeric($this->columnLimit)) {
return "(" . $this->columnLimit . ")";
}
// 否则没有设置
return false;
}
/**
* @return mixed
*/
public function getColumnName()
{
return $this->columnName;
}
/**
* 设置字段名称
* @param string $name 字段名称
* @return Column
*/
function setColumnName(string $name): Column
{
$name = trim($name);
if (empty($name)) {
throw new InvalidArgumentException('The column name cannot be empty');
}
$this->columnName = $name;
return $this;
}
/**
* @return mixed
*/
public function getColumnType()
{
return $this->columnType;
}
/**
* 设置字段类型
* @param string $type
* @return Column
*/
function setColumnType(string $type): Column
{
$type = trim($type);
if (!DataType::isValidValue($type)) {
throw new InvalidArgumentException('The column type ' . $type . ' is invalid');
}
$this->columnType = $type;
return $this;
}
/**
* @return mixed
*/
public function getColumnLimit()
{
return $this->columnLimit;
}
/**
* 设置字段列宽限制
* @param integer|array $limit
* @return Column
*/
function setColumnLimit($limit): Column
{
// TODO 暂未做规范判断
// 此处根据类型的不同实际上还应该判断 TEXT/BLOB 不可能存在limit
// 另外数字类型如 INT DisplayWidth < 256 | DECIMAL (1,5) 总精度必须大于小数部分精度等限制
$this->columnLimit = $limit;
return $this;
}
/**
* @return mixed
*/
public function getColumnComment()
{
return $this->columnComment;
}
/**
* 设置字段备注
* @param string $comment
* @return Column
*/
function setColumnComment(string $comment): Column
{
$this->columnComment = $comment;
return $this;
}
/**
* @return mixed
*/
public function getColumnCharset()
{
return $this->columnCharset;
}
/**
* 设置字段编码
* @param string $charset
* @return Column
*/
function setColumnCharset(string $charset): Column
{
$this->columnCharset = $charset;
return $this;
}
/**
* @return mixed
*/
public function getIsBinary()
{
return $this->isBinary;
}
/**
* 是否二进制
* 在字符列上设置了二进制会使得该列严格区分大小写
* @param bool $enable
* @return Column
*/
function setIsBinary(bool $enable = true): Column
{
// TODO 暂未做规范判断
// 同样需要做规范判断 只有字符串类型才允许二进制
$this->isBinary = $enable;
return $this;
}
/**
* @return mixed
*/
public function getIsUnique()
{
return $this->isUnique;
}
/**
* 字段设置为Unique
* 请不要和索引互相重复设置
* @param bool $enable
* @return Column
*/
function setIsUnique(bool $enable = true): Column
{
$this->isUnique = $enable;
return $this;
}
/**
* @return mixed
*/
public function getUnsigned()
{
return $this->unsigned;
}
/**
* @return mixed
*/
public function getZeroFill()
{
return $this->zeroFill;
}
/**
* 是否零填充
* @param bool $enable
* @return Column
*/
function setZeroFill(bool $enable = true): Column
{
$this->zeroFill = $enable;
return $this;
}
/**
* @return mixed
*/
public function getDefaultValue()
{
return $this->defaultValue;
}
/**
* 字段默认值
* @param $value
* @return Column
*/
function setDefaultValue($value): Column
{
// TODO 暂未做规范判断
// 同样需要做规范判断 字段为文本/BLOB时不能设置默认值
$this->defaultValue = $value;
return $this;
}
/**
* @return bool
*/
public function getIsNotNull(): bool
{
return $this->isNotNull;
}
/**
* 设置不可空
* @param bool $enable
* @return Column
*/
function setIsNotNull(bool $enable = true): Column
{
$this->isNotNull = $enable;
return $this;
}
/**
* @return mixed
*/
public function getAutoIncrement()
{
return $this->autoIncrement;
}
/**
* @return mixed
*/
public function getIsPrimaryKey()
{
return $this->isPrimaryKey;
}
/**
* 直接在字段上设置PK
* 请不要和索引互相重复设置
* @param bool $enable
* @return Column
*/
function setIsPrimaryKey(bool $enable = true): Column
{
$this->isPrimaryKey = $enable;
return $this;
}
}