From 08f8f417d5db7e20b3958f6830b43e7b847c795b Mon Sep 17 00:00:00 2001 From: "as2252258@163.com" Date: Sat, 27 Mar 2021 03:29:38 +0800 Subject: [PATCH] modify --- Database/ActiveQuery.php | 511 +++++++++++++++++---------------- Database/SqlBuilder.php | 492 ++++++++++++++++--------------- Database/Traits/QueryTrait.php | 2 +- 3 files changed, 511 insertions(+), 494 deletions(-) diff --git a/Database/ActiveQuery.php b/Database/ActiveQuery.php index fb8ce1ea..9e424863 100644 --- a/Database/ActiveQuery.php +++ b/Database/ActiveQuery.php @@ -21,300 +21,303 @@ use Snowflake\Snowflake; class ActiveQuery extends Component implements ISqlBuilder { - use QueryTrait; + use QueryTrait; - /** @var array */ - public array $with = []; + /** @var array */ + public array $with = []; - /** @var bool */ - public bool $asArray = FALSE; + /** @var bool */ + public bool $asArray = FALSE; - /** @var bool */ - public bool $useCache = FALSE; + /** @var bool */ + public bool $useCache = FALSE; - /** - * @var Connection|null - */ - public ?Connection $db = NULL; + /** + * @var Connection|null + */ + public ?Connection $db = NULL; - /** - * @var array - * 参数绑定 - */ - public array $attributes = []; + /** + * @var array + * 参数绑定 + */ + public array $attributes = []; - private SqlBuilder $builder; + private SqlBuilder $builder; - /** - * Comply constructor. - * @param $model - * @param array $config - * @throws - */ - public function __construct($model, $config = []) - { - if (!is_object($model)) { - $model = Snowflake::createObject($model); - } - $this->modelClass = $model; + /** + * Comply constructor. + * @param $model + * @param array $config + * @throws + */ + public function __construct($model, $config = []) + { + if (!is_object($model)) { + $model = Snowflake::createObject($model); + } + $this->modelClass = $model; - $this->builder = SqlBuilder::builder($this); - parent::__construct($config); - } + $this->builder = SqlBuilder::builder($this); + parent::__construct($config); + } - /** - * 清除不完整数据 - */ - public function clear() - { - $this->db = null; - $this->useCache = false; - $this->with = []; - } + /** + * 清除不完整数据 + */ + public function clear() + { + $this->db = null; + $this->useCache = false; + $this->with = []; + } - /** - * @param $key - * @param $value - * @return $this - */ - public function addParam($key, $value): static - { - $this->attributes[$key] = $value; - return $this; - } + /** + * @param $key + * @param $value + * @return $this + */ + public function addParam($key, $value): static + { + $this->attributes[$key] = $value; + return $this; + } - /** - * @param array $values - * @return $this - */ - public function addParams(array $values): static - { - foreach ($values as $key => $val) { - $this->addParam($key, $val); - } - return $this; - } + /** + * @param array $values + * @return $this + */ + public function addParams(array $values): static + { + foreach ($values as $key => $val) { + $this->addParam($key, $val); + } + return $this; + } - /** - * @param $name - * @return $this - */ - public function with($name): static - { - if (empty($name)) { - return $this; - } - if (is_string($name)) { - $name = explode(',', $name); - } - foreach ($name as $key => $val) { - array_push($this->with, $val); - } - return $this; - } + /** + * @param $name + * @return $this + */ + public function with($name): static + { + if (empty($name)) { + return $this; + } + if (is_string($name)) { + $name = explode(',', $name); + } + foreach ($name as $key => $val) { + array_push($this->with, $val); + } + return $this; + } - /** - * @param bool $isArray - * @return $this - */ - public function asArray($isArray = TRUE): static - { - $this->asArray = $isArray; - return $this; - } + /** + * @param bool $isArray + * @return $this + */ + public function asArray($isArray = TRUE): static + { + $this->asArray = $isArray; + return $this; + } - /** - * @param $sql - * @return mixed - */ - public function execute($sql): Command - { - return $this->modelClass::getDb()->createCommand($sql); - } + /** + * @param $sql + * @return mixed + */ + public function execute($sql): Command + { + return $this->modelClass::getDb()->createCommand($sql); + } - /** - * @return ActiveRecord|array|null - * @throws Exception - */ - public function first(): ActiveRecord|array|null - { - $data = $this->execute($this->builder->one())->one(); - if (empty($data)) { - return NULL; - } - $newModel = $this->modelClass; - $newModel = $this->populate($newModel, $data); - if ($this->asArray) { - return $newModel->toArray(); - } - return $newModel; - } + /** + * @return ActiveRecord|array|null + * @throws Exception + */ + public function first(): ActiveRecord|array|null + { + $data = $this->execute($this->builder->one())->one(); + if (empty($data)) { + return NULL; + } + $newModel = $this->modelClass; + $newModel = $this->populate($newModel, $data); + if ($this->asArray) { + return $newModel->toArray(); + } + return $newModel; + } - /** - * @return string - * @throws Exception - */ - public function toSql(): string - { - return $this->builder->get(); - } + /** + * @return string + * @throws Exception + */ + public function toSql(): string + { + return $this->builder->get(); + } - /** - * @return array|Collection - */ - public function get(): Collection|array - { - return $this->all(); - } + /** + * @return array|Collection + */ + public function get(): Collection|array + { + return $this->all(); + } - /** - * @throws Exception - */ - public function flush(): array|bool|int|string|null - { - return $this->execute($this->builder->truncate())->exec(); - } + /** + * @throws Exception + */ + public function flush(): array|bool|int|string|null + { + return $this->execute($this->builder->truncate())->exec(); + } - /** - * @param int $size - * @param callable $callback - * @return Pagination - * @throws Exception - */ - public function page(int $size, callable $callback): Pagination - { - $pagination = new Pagination($this); - $pagination->setOffset(0); - $pagination->setLimit($size); - $pagination->setCallback($callback); - return $pagination; - } + /** + * @param int $size + * @param callable $callback + * @return Pagination + * @throws Exception + */ + public function page(int $size, callable $callback): Pagination + { + $pagination = new Pagination($this); + $pagination->setOffset(0); + $pagination->setLimit($size); + $pagination->setCallback($callback); + return $pagination; + } - /** - * @param string $field - * @param string $setKey - * - * @return array|null - * @throws Exception - */ - public function column(string $field, $setKey = ''): ?array - { - return $this->all()->column($field, $setKey); - } + /** + * @param string $field + * @param string $setKey + * + * @return array|null + * @throws Exception + */ + public function column(string $field, $setKey = ''): ?array + { + return $this->all()->column($field, $setKey); + } - /** - * @return array|Collection - * @throws - */ - public function all(): Collection|array - { - $data = $this->execute($this->builder->all())->all(); + /** + * @return array|Collection + * @throws + */ + public function all(): Collection|array + { + $data = $this->execute($this->builder->all())->all(); - $collect = new Collection($this, $data, $this->modelClass); - if ($this->asArray) { - return $collect->toArray(); - } - return $collect; - } + $collect = new Collection($this, $data, $this->modelClass); + if ($this->asArray) { + return $collect->toArray(); + } + return $collect; + } - /** - * @param ActiveRecord $model - * @param $data - * @return ActiveRecord - * @throws Exception - */ - public function populate(ActiveRecord $model, $data): ActiveRecord - { - return $this->getWith($model::populate($data)); - } + /** + * @param ActiveRecord $model + * @param $data + * @return ActiveRecord + * @throws Exception + */ + public function populate(ActiveRecord $model, $data): ActiveRecord + { + return $this->getWith($model::populate($data)); + } - /** - * @param ActiveRecord $model - * @return ActiveRecord - */ - public function getWith(ActiveRecord $model): ActiveRecord - { - if (empty($this->with) || !is_array($this->with)) { - return $model; - } - return $model->setWith($this->with); - } + /** + * @param ActiveRecord $model + * @return ActiveRecord + */ + public function getWith(ActiveRecord $model): ActiveRecord + { + if (empty($this->with) || !is_array($this->with)) { + return $model; + } + return $model->setWith($this->with); + } - /** - * @return int - * @throws Exception - */ - public function count(): int - { - $data = $this->execute($this->builder->count())->one(); - if ($data && is_array($data)) { - return (int)array_shift($data); - } - return 0; - } + /** + * @return int + * @throws Exception + */ + public function count(): int + { + $data = $this->execute($this->builder->count())->one(); + if ($data && is_array($data)) { + return (int)array_shift($data); + } + return 0; + } - /** - * @param array $data - * @return array|Command|bool|int|string - * @throws Exception - */ - public function batchUpdate(array $data): Command|array|bool|int|string - { - $generate = $this->builder->update($data); - if (is_bool($generate)) { - return $generate; - } - return $this->execute(...$generate)->exec(); - } + /** + * @param array $data + * @return array|Command|bool|int|string + * @throws Exception + */ + public function batchUpdate(array $data): Command|array|bool|int|string + { + $generate = $this->builder->update($data); + if (is_bool($generate)) { + return $generate; + } + return $this->execute(...$generate)->exec(); + } - /** - * @param array $data - * @return bool - * @throws Exception - */ - public function batchInsert(array $data): bool - { - return $this->execute($this->builder->insert($data, true))->exec(); - } + /** + * @param array $data + * @return bool + * @throws Exception + */ + public function batchInsert(array $data): bool + { + return $this->execute($this->builder->insert($data, true))->exec(); + } - /** - * @param $filed - * - * @return null - * @throws Exception - */ - public function value($filed) - { - return $this->first()[$filed] ?? null; - } + /** + * @param $filed + * + * @return null + * @throws Exception + */ + public function value($filed) + { + return $this->first()[$filed] ?? null; + } - /** - * @return bool - * @throws Exception - */ - public function exists(): bool - { - return $this->execute($this->builder->one())->fetchColumn() !== false; - } + /** + * @return bool + * @throws Exception + */ + public function exists(): bool + { + return $this->execute($this->builder->one())->fetchColumn() !== false; + } - /** - * @return bool - * @throws Exception - */ - public function delete(): bool - { - return $this->execute($this->builder->all())->delete(); - } + /** + * @return bool + * @throws Exception + */ + public function delete($getSql = false): string|bool + { + if ($getSql) { + return $this->builder->delete(); + } + return $this->execute($this->builder->all())->delete(); + } } diff --git a/Database/SqlBuilder.php b/Database/SqlBuilder.php index bf287646..af4f9fee 100644 --- a/Database/SqlBuilder.php +++ b/Database/SqlBuilder.php @@ -17,292 +17,306 @@ use Snowflake\Abstracts\Component; class SqlBuilder extends Component { - use Builder; + use Builder; - public ActiveQuery|Query|null $query; + public ActiveQuery|Query|null $query; - /** - * @param $query - * @return $this - */ - public static function builder(ISqlBuilder|null $query): static - { - return new static(['query' => $query]); - } + /** + * @param $query + * @return $this + */ + public static function builder(ISqlBuilder|null $query): static + { + return new static(['query' => $query]); + } - /** - * @return string - * @throws Exception - */ - public function getCondition(): string - { - return $this->conditionToString(); - } + /** + * @return string + * @throws Exception + */ + public function getCondition(): string + { + return $this->conditionToString(); + } - /** - * @param array $attributes - * @return bool|array - * @throws Exception - */ - public function update(array $attributes): bool|array - { - [$string, $array] = $this->builderParams($attributes); - if (empty($string) || empty($array)) { - return $this->addError('None data update.'); - } + /** + * @param array $attributes + * @return bool|array + * @throws Exception + */ + public function update(array $attributes): bool|array + { + [$string, $array] = $this->builderParams($attributes); + if (empty($string) || empty($array)) { + return $this->addError('None data update.'); + } - $condition = $this->conditionToString(); - if (!empty($condition)) { - $condition = ' WHERE ' . $condition; - } + $condition = $this->conditionToString(); + if (!empty($condition)) { + $condition = ' WHERE ' . $condition; + } - $update = 'UPDATE ' . $this->tableName() . ' SET ' . implode(',', $string) . $condition; - $update .= $this->builderLimit($this->query); + $update = 'UPDATE ' . $this->tableName() . ' SET ' . implode(',', $string) . $condition; + $update .= $this->builderLimit($this->query); - return [$update, $array]; - } + return [$update, $array]; + } - /** - * @param array $attributes - * @param string $opera - * @return bool|array - * @throws Exception - */ - public function mathematics(array $attributes, $opera = '+'): bool|array - { - $string = $array = []; + /** + * @param array $attributes + * @param string $opera + * @return bool|array + * @throws Exception + */ + public function mathematics(array $attributes, $opera = '+'): bool|array + { + $string = $array = []; - foreach ($attributes as $attribute => $value) { - $string[] = $attribute . '=' . $attribute . $opera . $value; - } + foreach ($attributes as $attribute => $value) { + $string[] = $attribute . '=' . $attribute . $opera . $value; + } - if (empty($string)) { - return $this->addError('None data update.'); - } + if (empty($string)) { + return $this->addError('None data update.'); + } - $condition = $this->conditionToString(); - if (!empty($condition)) { - $condition = ' WHERE ' . $condition; - } + $condition = $this->conditionToString(); + if (!empty($condition)) { + $condition = ' WHERE ' . $condition; + } - $update = 'UPDATE ' . $this->tableName() . ' SET ' . implode(',', $string) . $condition; - $update .= $this->builderLimit($this->query); + $update = 'UPDATE ' . $this->tableName() . ' SET ' . implode(',', $string) . $condition; + $update .= $this->builderLimit($this->query); - return [$update, []]; - } + return [$update, []]; + } - /** - * @param array $attributes - * @param false $isBatch - * @return array - * @throws Exception - */ - public function insert(array $attributes, $isBatch = false): array - { - $update = sprintf('INSERT INTO %s', $this->tableName()); - if ($isBatch === false) { - $attributes = [$attributes]; - } - $update .= '(' . implode(',', $this->getFields($attributes)) . ') VALUES '; + /** + * @param array $attributes + * @param false $isBatch + * @return array + * @throws Exception + */ + public function insert(array $attributes, $isBatch = false): array + { + $update = sprintf('INSERT INTO %s', $this->tableName()); + if ($isBatch === false) { + $attributes = [$attributes]; + } + $update .= '(' . implode(',', $this->getFields($attributes)) . ') VALUES '; - $order = 0; - $keys = $params = []; - foreach ($attributes as $attribute) { - [$_keys, $params] = $this->builderParams($attribute, true, $params, $order); + $order = 0; + $keys = $params = []; + foreach ($attributes as $attribute) { + [$_keys, $params] = $this->builderParams($attribute, true, $params, $order); - $keys[] = implode(',', $_keys); - $order++; - } - return [$update . '(' . implode('),(', $keys) . ')', $params]; - } + $keys[] = implode(',', $_keys); + $order++; + } + return [$update . '(' . implode('),(', $keys) . ')', $params]; + } - /** - * @param $attributes - * @return array - */ - #[Pure] private function getFields($attributes): array - { - return array_keys(current($attributes)); - } + /** + * @return string + * @throws Exception + */ + public function delete() + { + $delete = sprintf('DELETE FROM %s ', $this->query->modelClass::getTable()); + + $this->query->from = null; + + return $delete . $this->_prefix(true); + } - /** - * @param array $attributes - * @param bool $isInsert - * @param array $params - * @param int $order - * @return array[] - * a=:b, - */ - private function builderParams(array $attributes, bool $isInsert = false, $params = [], $order = 0): array - { - $keys = []; - foreach ($attributes as $key => $value) { - if ($isInsert === true) { - $keys[] = ':' . $key . $order; - } else { - $keys[] = $key . '=:' . $key . $order; - } - $params[$key . $order] = $value; - } - return [$keys, $params]; - } + /** + * @param $attributes + * @return array + */ + #[Pure] private function getFields($attributes): array + { + return array_keys(current($attributes)); + } - /** - * @return string - * @throws Exception - */ - public function one(): string - { - $this->query->limit(0, 1); - return $this->_prefix(true); - } + /** + * @param array $attributes + * @param bool $isInsert + * @param array $params + * @param int $order + * @return array[] + * a=:b, + */ + private function builderParams(array $attributes, bool $isInsert = false, $params = [], $order = 0): array + { + $keys = []; + foreach ($attributes as $key => $value) { + if ($isInsert === true) { + $keys[] = ':' . $key . $order; + } else { + $keys[] = $key . '=:' . $key . $order; + } + $params[$key . $order] = $value; + } + return [$keys, $params]; + } - /** - * @return string - * @throws Exception - */ - public function all(): string - { - return $this->_prefix(true); - } + /** + * @return string + * @throws Exception + */ + public function one(): string + { + $this->query->limit(0, 1); + return $this->_prefix(true); + } - /** - * @return string - * @throws Exception - */ - public function count(): string - { - return $this->_prefix(); - } + /** + * @return string + * @throws Exception + */ + public function all(): string + { + return $this->_prefix(true); + } - /** - * @param $table - * @return string - */ - public function columns($table): string - { - return 'SHOW FULL FIELDS FROM ' . $table; - } + /** + * @return string + * @throws Exception + */ + public function count(): string + { + return $this->_prefix(); + } - /** - * @param bool $hasOrder - * @return string - * @throws Exception - */ - private function _prefix($hasOrder = false): string - { - $select = ''; - if (!empty($this->query->from)) { - $select = $this->_selectPrefix(); - } - $select = $this->_wherePrefix($select); - if (!empty($this->query->group)) { - $select .= $this->builderGroup($this->query->group); - } - if ($hasOrder === true && !empty($this->query->order)) { - $select .= $this->builderOrder($this->query->order); - } - return $select . $this->builderLimit($this->query); - } + /** + * @param $table + * @return string + */ + public function columns($table): string + { + return 'SHOW FULL FIELDS FROM ' . $table; + } - /** - * @param $select - * @return string - * @throws Exception - */ - private function _wherePrefix($select): string - { - $condition = $this->conditionToString(); - if (empty($condition)) { - return $select; - } else if (empty($select)) { - return $condition; - } - return sprintf('%s WHERE %s', $select, $condition); - } + /** + * @param bool $hasOrder + * @return string + * @throws Exception + */ + private function _prefix($hasOrder = false): string + { + $select = ''; + if (!empty($this->query->from)) { + $select = $this->_selectPrefix(); + } + $select = $this->_wherePrefix($select); + if (!empty($this->query->group)) { + $select .= $this->builderGroup($this->query->group); + } + if ($hasOrder === true && !empty($this->query->order)) { + $select .= $this->builderOrder($this->query->order); + } + return $select . $this->builderLimit($this->query); + } - /** - * @return string - * @throws Exception - */ - private function _selectPrefix(): string - { - $select = $this->builderSelect($this->query->select) . ' FROM ' . $this->tableName(); - if (!empty($this->query->alias)) { - $select .= $this->builderAlias($this->query->alias); - } - if (!empty($this->query->join)) { - $select .= $this->builderJoin($this->query->join); - } - return $select; - } + /** + * @param $select + * @return string + * @throws Exception + */ + private function _wherePrefix($select): string + { + $condition = $this->conditionToString(); + if (empty($condition)) { + return $select; + } else if (empty($select)) { + return $condition; + } + return sprintf('%s WHERE %s', $select, $condition); + } - /** - * @param false $isCount - * @return string - * @throws Exception - */ - public function get($isCount = false): string - { - if ($isCount === false) { - return $this->all(); - } - return $this->count(); - } + /** + * @return string + * @throws Exception + */ + private function _selectPrefix(): string + { + $select = $this->builderSelect($this->query->select) . ' FROM ' . $this->tableName(); + if (!empty($this->query->alias)) { + $select .= $this->builderAlias($this->query->alias); + } + if (!empty($this->query->join)) { + $select .= $this->builderJoin($this->query->join); + } + return $select; + } - /** - * @return string - * @throws Exception - */ - public function truncate(): string - { - return sprintf('TRUNCATE %s', $this->tableName()); - } + /** + * @param false $isCount + * @return string + * @throws Exception + */ + public function get($isCount = false): string + { + if ($isCount === false) { + return $this->all(); + } + return $this->count(); + } - /** - * @return string - * @throws Exception - */ - private function conditionToString(): string - { - return $this->where($this->query->where); - } + /** + * @return string + * @throws Exception + */ + public function truncate(): string + { + return sprintf('TRUNCATE %s', $this->tableName()); + } - /** - * @return string - * @throws Exception - */ - public function tableName(): string - { - if ($this->query->from instanceof \Closure) { - $this->query->from = sprintf('(%s)', $this->query->makeClosureFunction($this->query->from)); - } - if ($this->query->from instanceof ActiveQuery) { - $this->query->from = sprintf('%s', SqlBuilder::builder($this->query->from)->get($this->query->from)); - } - if (empty($this->query->from)) { - return $this->query->modelClass::getTable(); - } - return $this->query->from; - } + /** + * @return string + * @throws Exception + */ + private function conditionToString(): string + { + return $this->where($this->query->where); + } + + + /** + * @return string + * @throws Exception + */ + public function tableName(): string + { + if ($this->query->from instanceof \Closure) { + $this->query->from = sprintf('(%s)', $this->query->makeClosureFunction($this->query->from)); + } + if ($this->query->from instanceof ActiveQuery) { + $this->query->from = sprintf('%s', SqlBuilder::builder($this->query->from)->get($this->query->from)); + } + if (empty($this->query->from)) { + return $this->query->modelClass::getTable(); + } + return $this->query->from; + } } diff --git a/Database/Traits/QueryTrait.php b/Database/Traits/QueryTrait.php index c9a8526b..f589b64a 100644 --- a/Database/Traits/QueryTrait.php +++ b/Database/Traits/QueryTrait.php @@ -34,7 +34,7 @@ trait QueryTrait public ?int $offset = NULL; public ?int $limit = NULL; public string $group = ''; - public string|Closure|ActiveQuery $from = ''; + public string|Closure|ActiveQuery|null $from = ''; public string $alias = 't1'; public array $filter = [];