diff --git a/ActiveQuery.php b/ActiveQuery.php index dbdcb4e..eb51f97 100644 --- a/ActiveQuery.php +++ b/ActiveQuery.php @@ -9,8 +9,10 @@ declare(strict_types=1); namespace Database; +use Closure; use Database\Traits\QueryTrait; -use JetBrains\PhpStorm\ArrayShape; +use Kiri\Di\Context; +use Swoole\Coroutine; /** * Class ActiveQuery @@ -20,62 +22,8 @@ class ActiveQuery extends QueryTrait implements ISqlBuilder { - public bool $asArray = FALSE; - public ?Connection $db = NULL; - public array $attributes = []; - protected mixed $_mock = null; - - - /** - * Comply constructor. - * @param $model - * @throws - */ - public function __construct($model) - { - $this->modelClass = $model; - $this->builder = SqlBuilder::builder($this); - parent::__construct(); - } - - - /** - * @param string $key - * @param mixed $value - * @return $this - */ - public function addParam(string $key, mixed $value): static - { - $this->attributes[$key] = $value; - return $this; - } - - - /** - * @param int $size - * @param int $page - * @return array - * @throws - */ - #[ArrayShape([])] - public function pagination(int $size = 20, int $page = 1): array - { - $page = max(1, $page); - $size = max(1, $size); - $offset = ($page - 1) * $size; - $count = $this->count(); - $lists = $this->offset($offset)->limit($size)->get()->toArray(); - return [ - 'code' => 0, - 'message' => 'ok', - 'size' => $size, - 'page' => $page, - 'count' => $count, - 'next' => max($page + 1, 1), - 'prev' => max($page - 1, 1), - 'param' => $lists, - ]; - } + public bool $asArray = FALSE; + protected mixed $_mock = null; /** @@ -88,19 +36,6 @@ class ActiveQuery extends QueryTrait implements ISqlBuilder 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 $methods * @return $this @@ -113,90 +48,67 @@ class ActiveQuery extends QueryTrait implements ISqlBuilder /** - * @param $sql - * @param array $params - * @return mixed + * @return ModelInterface|array|null|bool * @throws */ - public function execute($sql, array $params = []): Command + public function first(): ModelInterface|null|array|bool { - return $this->modelClass->getConnection()->createCommand($sql, $params); - } - - - /** - * @return ModelInterface|array|null - * @throws - */ - public function first(): ModelInterface|null|array - { - $data = $this->limit(1)->execute($this->builder->one(), $this->attributes)->one(); + $data = $this->buildCommand($this->builder->one())->one(); if (is_array($data)) { return $this->populate($data); - } else { - return NULL; } + return $data; } - /** - * @return string - * @throws + * @return bool|Collection */ - public function toSql(): string + public function get(): bool|Collection { - return $this->builder->get(); - } - - - /** - * @return Collection - * @throws - */ - public function get(): Collection - { - $data = $this->execute($this->builder->all(), $this->attributes)->all(); - if ($data !== false) { - return new Collection($this, $data, $this->modelClass); - } else { - return new Collection($this, [], $this->modelClass); + $data = $this->buildCommand($this->builder->all())->all(); + if (is_array($data)) { + return new Collection($this, $this->modelClass, $data); } + return false; } /** * @throws */ - public function flush(): array|bool|int|string|null + public function flush(): bool { - return $this->execute($this->builder->truncate())->exec(); + return (bool)$this->buildCommand($this->builder->truncate())->exec(); } /** * @param int $size - * @param callable $callback - * @param int $offset - * @return Pagination - * @throws + * @param Closure $closure + * @return void */ - public function page(int $size, callable $callback, int $offset = 0): Pagination + public function chunk(int $size, Closure $closure): void { - $pagination = new Pagination($this); - $pagination->setOffset($offset); - $pagination->setLimit($size); - $pagination->setCallback($callback); - return $pagination; + $data = $this->offset($this->offset)->limit($size)->get(); + if (!$data || $data->isEmpty()) { + return; + } + if (Context::inCoroutine()) { + Coroutine::create(fn() => $closure($data)); + } else { + call_user_func($closure, $data); + } + $this->offset += $size; + $this->chunk($size, $closure); } /** * @param string $field - * @param string $setKey + * @param string|null $setKey * * @return array|null - * @throws */ - public function column(string $field, string $setKey = ''): ?array + public function column(string $field, ?string $setKey = null): ?array { return $this->get()->column($field, $setKey); } @@ -241,7 +153,7 @@ class ActiveQuery extends QueryTrait implements ISqlBuilder */ public function count(): int { - return $this->execute($this->builder->count(), $this->attributes)->one()['row_count'] ?? 0; + return $this->buildCommand($this->builder->count())->rowCount(); } @@ -257,7 +169,7 @@ class ActiveQuery extends QueryTrait implements ISqlBuilder } $generate = $this->builder->update($data); if (!is_bool($generate)) { - return (bool)$this->execute($generate, $this->attributes)->exec(); + return (bool)$this->buildCommand($generate)->exec(); } else { return $generate; } @@ -272,16 +184,16 @@ class ActiveQuery extends QueryTrait implements ISqlBuilder { [$sql, $params] = $this->builder->insert($data, TRUE); - return (bool)$this->execute($sql, $params)->exec(); + return (bool)$this->buildCommand($sql, $params)->exec(); } /** * @param $filed * - * @return null + * @return mixed * @throws */ - public function value($filed) + public function value($filed): mixed { return $this->first()[$filed] ?? NULL; } @@ -292,22 +204,26 @@ class ActiveQuery extends QueryTrait implements ISqlBuilder */ public function exists(): bool { - return !empty($this->execute($this->builder->one(), $this->attributes)->fetchColumn()); + return $this->buildCommand($this->builder->one())->rowCount() > 0; } /** - * @param bool $getSql - * @return bool|string - * @throws + * @param string $sql + * @param array $params + * @return int|bool */ - public function delete(bool $getSql = FALSE): bool|string + public function execute(string $sql, array $params = []): int|bool { - $sql = $this->builder->delete(); - if ($getSql === FALSE) { - return (bool)$this->execute($sql, $this->attributes)->delete(); - } else { - return $sql; - } + return $this->buildCommand($sql, $params)->exec(); + } + + + /** + * @return bool + */ + public function delete(): bool + { + return $this->buildCommand($this->builder->delete())->delete(); } } diff --git a/Base/AbstractCollection.php b/Base/AbstractCollection.php index 23493fd..bad8894 100644 --- a/Base/AbstractCollection.php +++ b/Base/AbstractCollection.php @@ -13,7 +13,6 @@ namespace Database\Base; use ArrayIterator; use Database\ActiveQuery; use Database\ModelInterface; -use Exception; use JetBrains\PhpStorm\Pure; use Kiri\Abstracts\Component; use ReturnTypeWillChange; @@ -29,41 +28,29 @@ abstract class AbstractCollection extends Component implements \IteratorAggregat /** * @var ModelInterface[] */ - protected array $_item = []; + private array $_item; /** - * @var ModelInterface|string|null + * @return array */ - protected ModelInterface|string|null $model; - - - /** - * @var ActiveQuery - */ - protected ActiveQuery $query; - - - public function clean(): void + public function getItems(): array { - unset($this->query, $this->model, $this->_item); + // TODO: Change the autogenerated stub + return $this->_item; } /** * Collection constructor. * - * @param $query + * @param ActiveQuery $query * @param array $array * @param ModelInterface|null $model - * @throws */ - public function __construct($query, array $array = [], ModelInterface $model = null) + public function __construct(public ActiveQuery $query, public ?ModelInterface $model = null, array $array = []) { $this->_item = $array; - $this->query = $query; - $this->model = $model; - parent::__construct(); } diff --git a/Base/ActiveQueryInterface.php b/Base/ActiveQueryInterface.php index 5daab33..e0b4588 100644 --- a/Base/ActiveQueryInterface.php +++ b/Base/ActiveQueryInterface.php @@ -3,6 +3,7 @@ namespace Database\Base; use Closure; +use Database\Collection; use Database\Traits\QueryTrait; interface ActiveQueryInterface @@ -77,29 +78,29 @@ interface ActiveQueryInterface /** * @param string $tableName * @param string $alias - * @param string|array $onCondition + * @param array $onCondition * @param array $param * @return QueryTrait */ - public function leftJoin(string $tableName, string $alias, string|array $onCondition, array $param = []): QueryTrait; + public function leftJoin(string $tableName, string $alias, array $onCondition, array $param = []): QueryTrait; /** * @param string $tableName * @param string $alias - * @param string|array $onCondition + * @param array $onCondition * @param array $param * @return QueryTrait */ - public function rightJoin(string $tableName, string $alias, string|array $onCondition, array $param = []): QueryTrait; + public function rightJoin(string $tableName, string $alias, array $onCondition, array $param = []): QueryTrait; /** * @param string $tableName * @param string $alias - * @param string|array $onCondition + * @param array $onCondition * @param array $param * @return QueryTrait */ - public function innerJoin(string $tableName, string $alias, string|array $onCondition, array $param = []): QueryTrait; + public function innerJoin(string $tableName, string $alias, array $onCondition, array $param = []): QueryTrait; /** * @param string $field @@ -138,16 +139,16 @@ interface ActiveQueryInterface public function orderBy(string|array $column, string $sort = 'DESC'): QueryTrait; /** - * @param array|string $column + * @param array $column * * @return QueryTrait */ - public function select(array|string $column = '*'): QueryTrait; + public function select(array $column = ['*']): QueryTrait; /** * @return QueryTrait */ - public function orderRand(): QueryTrait; + public function rand(): QueryTrait; /** * @param array|Closure|string $conditionArray diff --git a/Base/Model.php b/Base/Model.php index 1aeaa9c..f098503 100644 --- a/Base/Model.php +++ b/Base/Model.php @@ -1,4 +1,4 @@ -getLastError('mysql'); + return $this->getLogger()->getLastError('mysql'); } @@ -237,16 +237,18 @@ abstract class Model extends Component implements ModelInterface, ArrayAccess, \ */ public static function findOne(int|string|array $param, $db = NULL): ?static { - $model = new ActiveQuery(static::makeNewInstance()); - $model->from($model->getTable())->alias('t1'); + $model = static::instance(); + + $query = new ActiveQuery($model); + $query->from($model->getTable())->alias('t1'); if (is_numeric($param)) { - $model->where([$model->modelClass->getPrimary() => $param]); + $query->where([$model->getPrimary() => $param]); } else if (is_array($param)) { - $model->where($param); + $query->where($param); } else { - $model->whereRaw($param); + $query->whereRaw($param); } - return $model->first(); + return $query->first(); } @@ -258,27 +260,27 @@ abstract class Model extends Component implements ModelInterface, ArrayAccess, \ */ public static function primary(int $param, $db = NULL): ?static { - $model = new ActiveQuery(static::makeNewInstance()); - $model->from($model->getTable())->alias('t1'); - $model->where([$model->modelClass->getPrimary() => $param]); - return $model->first(); + $model = static::instance(); + $query = new ActiveQuery($model); + $query->from($model->getTable())->alias('t1')->where([$model->getPrimary() => $param]); + return $query->first(); } /** - * @return mixed - * @throws + * @return bool|int + * @throws Exception */ - public function optimize(): mixed + public function optimize(): bool|int { - return static::query()->execute('OPTIMIZE TABLE ' . $this->getTable())->exec(); + return static::query()->execute('OPTIMIZE TABLE ' . $this->getTable()); } /** * @return static */ - private static function makeNewInstance(): static + protected static function instance(): static { return new static(); } @@ -302,7 +304,7 @@ abstract class Model extends Component implements ModelInterface, ArrayAccess, \ */ public static function all(string|array $condition): Collection { - $model = new ActiveQuery(static::makeNewInstance()); + $model = new ActiveQuery(static::instance()); $model->from($model->getTable())->alias('t1'); if (is_array($condition)) { $model->where($condition); @@ -319,7 +321,7 @@ abstract class Model extends Component implements ModelInterface, ArrayAccess, \ */ public static function query(): ActiveQuery { - $model = new ActiveQuery(static::makeNewInstance()); + $model = new ActiveQuery(static::instance()); $model->from($model->getTable())->alias('t1'); return $model; } @@ -336,21 +338,21 @@ abstract class Model extends Component implements ModelInterface, ArrayAccess, \ /** - * @param array|string|null $condition + * @param array|string $condition * @param array $attributes * * @return bool - * @throws */ - protected static function deleteByCondition(array|string|null $condition = NULL, array $attributes = []): bool + protected static function deleteByCondition(array|string $condition = [], array $attributes = []): bool { - $model = static::query()->bindParams($attributes); - if (is_array($condition)) { - $model->where($condition); - } else if (is_string($condition)) { + $model = static::query(); + $model->bindParams($attributes); + if (is_string($condition)) { $model->whereRaw($condition); + } else { + $model->where($condition); } - return (bool)$model->delete(); + return $model->delete(); } diff --git a/Collection.php b/Collection.php index b150da3..48ee4ca 100644 --- a/Collection.php +++ b/Collection.php @@ -21,33 +21,15 @@ use JetBrains\PhpStorm\Pure; class Collection extends AbstractCollection { - /** - * @return array - */ - public function getItems(): array - { - // TODO: Change the autogenerated stub - return $this->_item; - } /** - * @param $field + * @param string $field * * @return array|null - * @throws */ - public function values($field): ?array + public function values(string $field): ?array { - if (empty($field) || !is_string($field)) { - return NULL; - } - $_tmp = []; - $data = $this->toArray(); - foreach ($data as $val) { - /** @var ModelInterface $val */ - $_tmp[] = $val[$field]; - } - return $_tmp; + return array_values($this->column($field)); } @@ -58,15 +40,10 @@ class Collection extends AbstractCollection */ public function update(array $attributes): bool { - $lists = []; - $model = $this->getModel(); - if (!$this->isEmpty()) { - foreach ($this->_item as $item) { - $lists[] = $item[$model->getPrimary()]; - } - return $model::query()->whereIn($model->getPrimary(), $lists)->update($attributes); + if ($this->isEmpty()) { + return $this->getLogger()->failure('No data by update', 'mysql'); } - return false; + return $this->batch()->update($attributes); } /** @@ -80,18 +57,9 @@ class Collection extends AbstractCollection foreach ($column as $key => $value) { $column[$key] = $array[$value]; } - return $column; } - /** - * @return $this - */ - public function orderRand(): static - { - shuffle($this->_item); - return $this; - } /** * @param int $start @@ -101,13 +69,13 @@ class Collection extends AbstractCollection */ #[Pure] public function slice(int $start = 0, int $length = 20): array { - if (empty($this->_item)) { + if (empty($this->getItems())) { return []; } - if (\count($this->_item) < $length) { - return $this->_item; + if (\count($this->getItems()) < $length) { + return $this->getItems(); } else { - return array_slice($this->_item, $start, $length); + return array_slice($this->getItems(), $start, $length); } } @@ -149,7 +117,7 @@ class Collection extends AbstractCollection */ #[Pure] public function current(): ModelInterface|array { - return current($this->_item); + return current($this->getItems()); } /** @@ -157,7 +125,7 @@ class Collection extends AbstractCollection */ #[Pure] public function size(): int { - return count($this->_item); + return count($this->getItems()); } /** @@ -171,7 +139,6 @@ class Collection extends AbstractCollection foreach ($this as $value) { $array[] = $value->toArray(); } - $this->_item = []; return $array; } @@ -182,10 +149,24 @@ class Collection extends AbstractCollection public function delete(): bool { $model = $this->getModel(); - if ($model->hasPrimary()) { - return $model::query()->whereIn($model->getPrimary(), $this->column($model->getPrimary()))->delete(); + if ($this->isEmpty()) { + return $this->getLogger()->failure('No data by delete', 'mysql'); } - throw new Exception('Must set primary key. if you wante delete'); + if (!$model->hasPrimary()) { + throw new Exception('Must set primary key. if you want to delete data'); + } + return $this->batch()->delete(); + } + + + /** + * @return ActiveQuery + * @throws Exception + */ + private function batch(): ActiveQuery + { + return $this->makeNewQuery()->whereIn($this->getModel()->getPrimary(), + $this->column($this->getModel()->getPrimary())); } /** @@ -205,7 +186,7 @@ class Collection extends AbstractCollection } $_filters[] = $value; } - return new Collection($this->query, $_filters, $this->model); + return new Collection($this->query, $this->model, $_filters); } diff --git a/Command.php b/Command.php index 7bd6eb3..84b0d4e 100644 --- a/Command.php +++ b/Command.php @@ -41,21 +41,21 @@ class Command extends Component /** - * @return int|bool + * @return bool * @throws */ - public function incrOrDecr(): int|bool + public function incrOrDecr(): bool { - return $this->_prepare(); + return (bool)$this->_prepare(); } /** - * @return int|bool + * @return bool * @throws */ - public function save(): int|bool + public function save(): bool { - return $this->_prepare(); + return (bool)$this->_prepare(); } @@ -69,10 +69,10 @@ class Command extends Component } /** - * @return bool|array|null + * @return array|bool|null * @throws */ - public function one(): null|bool|array + public function one(): array|null|bool { return $this->search('fetch'); } @@ -86,6 +86,29 @@ class Command extends Component return $this->search('fetchColumn'); } + /** + * @return mixed + * @throws + */ + public function rowCount(): mixed + { + return $this->search('rowCount'); + } + + + /** + * @return bool + * @throws Exception + */ + public function exists(): bool + { + $total = $this->search('rowCount'); + if ($total === false) { + throw new Exception('Query data is has error.'); + } + return $total > 0; + } + /** * @param string $method @@ -101,13 +124,17 @@ class Command extends Component } $prepare->execute($this->params); + $prepare->closeCursor(); + if ($method == 'rowCount') { + return $prepare->rowCount(); + } return $prepare->{$method}(PDO::FETCH_ASSOC); } catch (Throwable $throwable) { if ($this->isRefresh($throwable)) { return $this->search($method); } - return $this->error($throwable); + return $this->getLogger()->failure(throwable($throwable), 'mysql'); } finally { $this->connection->release($client); } @@ -115,20 +142,20 @@ class Command extends Component /** - * @return int|bool + * @return bool * @throws */ - public function flush(): int|bool + public function flush(): bool { - return $this->_prepare(); + return (bool)$this->_prepare(); } /** - * @return PDOStatement|int + * @return int|bool * @throws */ - private function _prepare(): bool|int + private function _prepare(): int|bool { $client = $this->connection->getConnection(); try { @@ -142,12 +169,12 @@ class Command extends Component $result = $client->lastInsertId(); - return $result == 0 ? $prepare->rowCount() > 0 : (int)$result; + return $result == 0 ? $prepare->rowCount() : (int)$result; } catch (Throwable $throwable) { if ($this->isRefresh($throwable)) { return $this->_prepare(); } - return $this->error($throwable); + return $this->getLogger()->failure(throwable($throwable), 'mysql'); } finally { $this->connection->release($client); } @@ -174,27 +201,16 @@ class Command extends Component /** - * @param Throwable $throwable * @return bool - */ - private function error(Throwable $throwable): bool - { - return trigger_print_error($this->sql . '.' . json_encode($this->params, JSON_UNESCAPED_UNICODE) . PHP_EOL . throwable($throwable), 'mysql'); - } - - - /** - * @return int|bool * @throws */ - public function delete(): int|bool + public function delete(): bool { - return $this->_prepare(); + return (bool)$this->_prepare(); } /** * @return int|bool - * @throws */ public function exec(): int|bool { @@ -213,15 +229,4 @@ class Command extends Component return $this; } - /** - * @param $sql - * @return $this - * @throws - */ - public function setSql($sql): static - { - $this->sql = $sql; - return $this; - } - } diff --git a/Connection.php b/Connection.php index bb5bf84..2539f48 100644 --- a/Connection.php +++ b/Connection.php @@ -22,11 +22,9 @@ use Kiri\Abstracts\Component; use Kiri\Di\Context; use Kiri\Pool\Pool; use Kiri\Events\EventProvider; -use Kiri\Exception\NotFindClassException; use PDO; use Kiri\Error\StdoutLogger; use Psr\Log\LoggerInterface; -use ReflectionException; use Kiri\Server\Events\OnWorkerStart; use Kiri\Server\Events\OnTaskerStart; use Kiri\Server\Events\OnAfterRequest; diff --git a/Db.php b/Db.php index d8b719f..dcf5e35 100644 --- a/Db.php +++ b/Db.php @@ -15,6 +15,7 @@ use Database\Affair\Commit; use Database\Affair\Rollback; use Database\Traits\QueryTrait; use Exception; +use Kiri; use Throwable; /** @@ -42,9 +43,10 @@ class Db extends QueryTrait implements ISqlBuilder { $db = new Db(); if (is_string($dbname)) { - $dbname = \Kiri::getDi()->get(DatabasesProviders::class)->get($dbname); + $db->connection = Kiri::getDi()->get(DatabasesProviders::class)->get($dbname); + } else { + $db->connection = $dbname; } - $db->connection = $dbname; return $db; } @@ -58,30 +60,6 @@ class Db extends QueryTrait implements ISqlBuilder } - /** - * @param Closure $closure - * @param mixed ...$params - * @return mixed - * @throws - */ - public static function Transaction(Closure $closure, ...$params): mixed - { - static::beginTransaction(); - try { - $result = call_user_func($closure, ...$params); - } catch (Throwable $throwable) { - $result = trigger_print_error($throwable->getMessage(), 'mysql'); - } finally { - if ($result === false) { - static::rollback(); - } else { - static::commit(); - } - return $result; - } - } - - /** * @return void * @throws @@ -149,21 +127,21 @@ class Db extends QueryTrait implements ISqlBuilder } /** - * @return bool|int - * @throws + * @return int */ - public function count(): bool|int + public function count(): int { - return $this->connection->createCommand(SqlBuilder::builder($this)->count())->one()['row_count']; + $count = $this->connection->createCommand(SqlBuilder::builder($this)->count())->one(); + return current($count); } /** - * @return bool|int - * @throws + * @return bool */ - public function exists(): bool|int + public function exists(): bool { - return $this->connection->createCommand(SqlBuilder::builder($this)->one())->fetchColumn(); + $fetchColumn = $this->connection->createCommand(SqlBuilder::builder($this)->one())->fetchColumn(); + return !empty($fetchColumn); } /** @@ -180,20 +158,18 @@ class Db extends QueryTrait implements ISqlBuilder /** * @param string $sql * @param array $attributes - * @return array|bool|int|string|null - * @throws + * @return array|null */ - public function one(string $sql, array $attributes = []): int|bool|array|string|null + public function one(string $sql, array $attributes = []): ?array { return $this->connection->createCommand($sql, $attributes)->one(); } /** - * @return bool|int - * @throws + * @return bool */ - public function delete(): bool|int + public function delete(): bool { return $this->connection->createCommand(SqlBuilder::builder($this)->delete())->delete(); } @@ -215,7 +191,7 @@ class Db extends QueryTrait implements ISqlBuilder ->select('*') ->from('INFORMATION_SCHEMA.KEY_COLUMN_USAGE') ->where(['REFERENCED_TABLE_NAME' => $table]) - ->getSql())->one(); + ->build())->one(); } @@ -248,7 +224,7 @@ class Db extends QueryTrait implements ISqlBuilder return $connection; } $databases = \config('databases.connections', []); - $providers = \Kiri::getDi()->get(DatabasesProviders::class); + $providers = Kiri::getDi()->get(DatabasesProviders::class); if (empty($databases) || !is_array($databases)) { throw new Exception('Please configure the database link.'); } diff --git a/Model.php b/Model.php index c3092c2..ffba292 100644 --- a/Model.php +++ b/Model.php @@ -102,14 +102,23 @@ class Model extends Base\Model */ public static function findOrCreate(array $condition, array $attributes): bool|static { - return Db::Transaction(function ($condition, $attributes) { + $model = static::instance(); + $connection = $model->getConnection()->beginTransaction(); + try { /** @var static $select */ - $select = static::query()->where($condition)->first(); + $select = $model::query()->where($condition)->first(); if ($select === null) { - $select = static::populate(array_merge($condition, $attributes))->save(); + $select = $model::populate(array_merge($condition, $attributes)); + if (!$select->save()) { + throw new Exception('保存失败: ' . $model->getLastError()); + } } + $connection->commit(); return $select; - }, $condition, $attributes); + } catch (\Throwable $throwable) { + $connection->rollback(); + return \Kiri::getLogger()->failure($throwable); + } } @@ -121,15 +130,24 @@ class Model extends Base\Model */ public static function createOrUpdate(array $condition, array $attributes = []): bool|static { - return Db::Transaction(function ($condition, $attributes) { + $model = static::instance(); + $connection = $model->getConnection()->beginTransaction(); + try { /** @var static $select */ $select = static::query()->where($condition)->first(); if (empty($select)) { $select = static::populate($condition); } $select->attributes = $attributes; - return $select->save(); - }, $condition, $attributes); + if (!$select->save()) { + throw new Exception('保存失败: ' . $model->getLastError()); + } + $connection->commit(); + return $select; + } catch (\Throwable $throwable) { + $connection->rollback(); + return \Kiri::getLogger()->failure($throwable); + } } @@ -157,14 +175,13 @@ class Model extends Base\Model */ private function mathematics($columns, $action): int|bool|array|string|null { - $condition = [$this->getPrimary() => $this->getPrimaryValue()]; - + $condition = [$this->getPrimary() => $this->getPrimaryValue()]; $activeQuery = static::query()->where($condition); $create = SqlBuilder::builder($activeQuery)->mathematics($columns, $action); if (is_bool($create)) { return false; } - return $this->getConnection()->createCommand($create, $activeQuery->attributes)->exec(); + return $activeQuery->buildCommand($create)->exec(); } @@ -179,11 +196,16 @@ class Model extends Base\Model return FALSE; } - $condition = array_diff_assoc($this->_oldAttributes, $params); - - $old = array_intersect_key($this->_oldAttributes, $params); - - return $this->updateInternal($old, $condition, $params); + $condition = []; + $oldPrams = []; + foreach ($this->_oldAttributes as $key => $attribute) { + if (!array_key_exists($key, $params) || $params[$key] == $attribute) { + $condition[$key] = $attribute; + } else { + $oldPrams[$key] = $this->_oldAttributes[$attribute]; + } + } + return $this->updateInternal($oldPrams, $condition, $params); } @@ -206,57 +228,15 @@ class Model extends Base\Model */ public function delete(): bool { - if ($this->beforeDelete()) { - if ($this->hasPrimary()) { - $result = static::deleteByCondition("id = ?", [$this->getPrimaryValue()]); - } else { - $result = static::deleteByCondition($this->_attributes); - } - $this->optimize(); - return $this->afterDelete($result); + if (!$this->beforeDelete()) { + return false; } - return false; - } - - - /** - * @param mixed $condition - * @param array $attributes - * - * @return bool - * @throws - */ - public static function updateAll(mixed $condition, array $attributes = []): bool - { - return static::query()->where($condition)->update($attributes); - } - - - /** - * @param $condition - * @return array|Collection - * @throws - */ - public static function get($condition): Collection|array - { - return static::query()->where($condition)->get(); - } - - - /** - * @param $condition - * @param array $attributes - * - * @return array|Collection - * @throws - */ - public static function findAll($condition, array $attributes = []): array|Collection - { - $query = static::query()->where($condition); - if (!empty($attributes)) { - $query->bindParams($attributes); + if ($this->hasPrimary()) { + $result = static::deleteByCondition(['id' => $this->getPrimaryValue()]); + } else { + $result = static::deleteByCondition($this->_attributes); } - return $query->get(); + return $this->afterDelete($result); } diff --git a/Orm/Condition.php b/Orm/Condition.php deleted file mode 100644 index e06976c..0000000 --- a/Orm/Condition.php +++ /dev/null @@ -1,28 +0,0 @@ -where($query); - } -} diff --git a/Pagination.php b/Pagination.php deleted file mode 100644 index 6888ef1..0000000 --- a/Pagination.php +++ /dev/null @@ -1,206 +0,0 @@ -activeQuery = $activeQuery; - } - - - /** - * @return void - */ - public function clean(): void - { - unset($this->activeQuery, $this->_callback, $this->_group); - $this->_offset = 0; - $this->_limit = 100; - $this->_max = 0; - $this->_length = 0;; - } - - - /** - * recover class by clone - */ - public function __clone() - { - $this->clean(); - } - - - /** - * @param array|Closure $callback - * @throws - */ - public function setCallback(array|Closure $callback): void - { - if (!is_callable($callback, true)) { - throw new Exception('非法回调函数~'); - } - $this->_callback = $callback; - } - - - /** - * @param int $number - * @return Pagination - */ - public function setOffset(int $number): static - { - if ($number < 0) { - $number = 0; - } - $this->_offset = $number; - return $this; - } - - - /** - * @param int $number - * @return Pagination - */ - public function setLimit(int $number): static - { - if ($number < 1) { - $number = 100; - } else if ($number > 5000) { - $number = 5000; - } - $this->_limit = $number; - return $this; - } - - - /** - * @param int $number - * @return Pagination - */ - public function setMax(int $number): static - { - if ($number < 0) { - return $this; - } - $this->_max = $number; - return $this; - } - - - /** - * @param array $param - * @return void - * @throws - */ - public function plunk(array $param = []): void - { - $this->loop($param); - } - - - /** - * 轮训 - * @param $param - * @return array - * @throws - */ - public function loop($param): array - { - if ($this->_max > 0 && $this->_length >= $this->_max) { - return $this->output(); - } - [$length, $data] = $this->get(); - try { - call_user_func($this->_callback, $data, $param); - } catch (\Throwable $exception) { - error($exception); - } finally { - $data = null; - } - if ($length < $this->_limit) { - return $this->output(); - } - return $this->loop($param); - } - - - /** - * @return array - */ - public function output(): array - { - return []; - } - - - /** - * @param $data - * @param $param - * @throws - */ - private function executed($data, $param): void - { - try { - call_user_func($this->_callback, $data, $param); - } catch (\Throwable $exception) { - error($exception); - } - } - - - /** - * @return array|Collection - * @throws - */ - private function get(): Collection|array - { - if ($this->_max > 0 && $this->_length + $this->_limit > $this->_max) { - $this->_limit = $this->_length + $this->_limit - $this->_max; - } - $data = $this->activeQuery->offset($this->_offset)->limit($this->_limit)->get(); - $this->_offset += $this->_limit; - $size = $data->size(); - $this->_length += $size; - return [$size, $data]; - } - -} diff --git a/Query.php b/Query.php index d991528..51b2c31 100644 --- a/Query.php +++ b/Query.php @@ -19,25 +19,6 @@ use Database\Traits\QueryTrait; class Query extends QueryTrait implements ISqlBuilder { - /** - * @throws - */ - public function __construct() - { - $this->builder = SqlBuilder::builder($this); - - parent::__construct(); - } - - /** - * @return string - * @throws - */ - public function getSql(): string - { - return $this->builder->get(); - } - /** * @return string diff --git a/SqlBuilder.php b/SqlBuilder.php index 86f381f..6a102c6 100644 --- a/SqlBuilder.php +++ b/SqlBuilder.php @@ -1,12 +1,12 @@ -conditionToString(); + return $this->where($this->query->where); } @@ -76,9 +73,9 @@ class SqlBuilder extends Component */ public function update(array $attributes): bool|string { - $conditions = $this->query->attributes; - $this->query->attributes = []; - $data = $this->__updateBuilder($this->builderParams($attributes)); + $conditions = $this->query->params; + $this->query->params = []; + $data = $this->__updateBuilder($this->makeParams($attributes)); foreach ($conditions as $condition) { $this->query->pushParam($condition); } @@ -110,9 +107,9 @@ class SqlBuilder extends Component private function __updateBuilder(array $string): string|bool { if (empty($string)) { - return \Kiri::getLogger()->failure('None data update.'); + return Kiri::getLogger()->failure('None data update.'); } - return 'UPDATE ' . $this->query->from . ' SET ' . implode(',', $string) . $this->_prefix(); + return 'UPDATE ' . $this->query->from . ' SET ' . implode(',', $string) . $this->make(); } @@ -130,15 +127,13 @@ class SqlBuilder extends Component } $update .= '(' . implode(',', $this->getFields($attributes)) . ') VALUES '; - $order = 0; - $keys = []; + $keys = []; foreach ($attributes as $attribute) { - $_keys = $this->builderParams($attribute, true, $order); + $_keys = $this->makeParams($attribute, true); $keys[] = implode(',', $_keys); - $order++; } - return [$update . '(' . implode('),(', $keys) . ')', $this->query->attributes]; + return [$update . '(' . implode('),(', $keys) . ')', $this->query->params]; } @@ -148,7 +143,7 @@ class SqlBuilder extends Component */ public function delete(): string { - return 'DELETE FROM ' . $this->query->from . $this->_prefix(); + return 'DELETE FROM ' . $this->query->from . $this->make(); } @@ -165,19 +160,18 @@ class SqlBuilder extends Component /** * @param array $attributes * @param bool $isInsert - * @param int $order * @return array[] * a=:b, */ - private function builderParams(array $attributes, bool $isInsert = false, int $order = 0): array + private function makeParams(array $attributes, bool $isInsert = false): array { $keys = []; foreach ($attributes as $key => $value) { - if ($isInsert === true) { + if ($isInsert !== true) { $keys[] = '?'; $this->query->pushParam($value); } else { - $keys = $this->resolveParams($key, $value, $order, $keys); + $keys = $this->resolveParams($key, $value, $keys); } } return $keys; @@ -187,16 +181,15 @@ class SqlBuilder extends Component /** * @param string $key * @param mixed $value - * @param int $order * @param array $keys * @return array */ - private function resolveParams(string $key, mixed $value, int $order, array $keys): array + private function resolveParams(string $key, mixed $value, array $keys): array { if (is_null($value)) { return $keys; } - if (is_string($value) && (str_starts_with($value, '+ ') || str_starts_with($value, '- '))) { + if (is_string($value) && $this->isMath($value)) { $keys[] = $key . '=' . $key . ' ' . $value; } else { $this->query->pushParam($value); @@ -206,16 +199,23 @@ class SqlBuilder extends Component } + /** + * @param string $value + * @return bool + */ + private function isMath(string $value): bool + { + return str_starts_with($value, '+ ') || str_starts_with($value, '- '); + } + + /** * @return string * @throws */ public function one(): string { - if (count($this->query->select) < 1) { - $this->query->select = ['*']; - } - return $this->_selectPrefix($this->query->select) . $this->_prefix() . $this->builderLimit($this->query); + return $this->makeSelect($this->query->select) . $this->make() . $this->makeLimit($this->query->limit(1)); } @@ -225,10 +225,7 @@ class SqlBuilder extends Component */ public function all(): string { - if (count($this->query->select) < 1) { - $this->query->select = ['*']; - } - return $this->_selectPrefix($this->query->select) . $this->_prefix() . $this->builderLimit($this->query); + return $this->makeSelect($this->query->select) . $this->make() . $this->makeLimit($this->query); } @@ -238,7 +235,7 @@ class SqlBuilder extends Component */ public function count(): string { - return $this->_selectPrefix(['COUNT(*) as row_count']) . $this->_prefix(); + return $this->_selectPrefix(['COUNT(*)']) . $this->make(); } @@ -256,18 +253,11 @@ class SqlBuilder extends Component * @return string * @throws */ - private function _prefix(): string + private function make(): string { - $select = ''; - if (($condition = $this->conditionToString()) != '') { - $select .= " WHERE $condition"; - } - if ($this->query->group != "") { - $select .= ' GROUP BY ' . $this->query->group; - } - if (count($this->query->order) > 0) { - $select .= ' ORDER BY ' . implode(',', $this->query->order); - } + $select = $this->makeCondition(); + $select .= $this->makeGroup(); + $select .= $this->makeOrder(); return $select; } @@ -275,7 +265,7 @@ class SqlBuilder extends Component * @param array $select * @return string */ - private function _selectPrefix(array $select = ['*']): string + private function makeSelect(array $select = ['*']): string { $select = "SELECT " . implode(',', $select) . " FROM " . $this->query->from; if ($this->query->alias != "") { @@ -288,6 +278,43 @@ class SqlBuilder extends Component } + /** + * @return string + */ + private function makeGroup(): string + { + if ($this->query->group != "") { + return ' GROUP BY ' . $this->query->group; + } + return ''; + } + + + /** + * @return string + */ + private function makeOrder(): string + { + if (count($this->query->order) > 0) { + return ' ORDER BY ' . implode(',', $this->query->order); + } + return ''; + } + + + /** + * @return string + */ + private function makeCondition(): string + { + $condition = $this->where($this->query->where); + if (empty($condition)) { + return ''; + } + return ' WHERE ' . $condition; + } + + /** * @param false $isCount * @return string @@ -313,12 +340,53 @@ class SqlBuilder extends Component /** + * @param array $where * @return string - * @throws */ - private function conditionToString(): string + private function where(array $where): string { - return $this->where($this->query->where); + if (count($where) < 1) { + return ''; + } + $_tmp = []; + foreach ($where as $key => $value) { + $_tmp[] = $this->resolveCondition($key, $value); + } + return implode(' AND ', $_tmp); } + + /** + * @param $field + * @param $condition + * @return string + */ + private function resolveCondition($field, $condition): string + { + if (is_string($field)) { + $this->query->pushParam($condition); + return $field . ' = ?'; + } else if (is_string($condition)) { + return $condition; + } else { + return implode(' AND ', $this->_hashMap($condition)); + } + } + + + /** + * @param $condition + * @return array + */ + private function _hashMap($condition): array + { + $_array = []; + foreach ($condition as $key => $value) { + $this->query->pushParam($value); + $_array[] = $key . '= ?'; + } + return $_array; + } + + } diff --git a/Traits/Builder.php b/Traits/Builder.php deleted file mode 100644 index 0ffda52..0000000 --- a/Traits/Builder.php +++ /dev/null @@ -1,200 +0,0 @@ -toSql() . ')'; - } - return " FROM " . $table; - } - - /** - * @param $join - * @return string - */ - #[Pure] private function builderJoin($join): string - { - if (!empty($join)) { - return ' ' . implode(' ', $join); - } - return ''; - } - - - /** - * @param string $select - * @return string - */ - #[Pure] private function builderSelect(string $select = "*"): string - { - return "SELECT " . $select; - } - - - /** - * @param string $group - * @return string - */ - private function builderGroup(string $group): string - { - if ($group != '') { - return ''; - } - return ' GROUP BY ' . $group; - } - - /** - * @param $order - * @return string - */ - #[Pure] private function builderOrder($order): string - { - if (!empty($order)) { - return ' ORDER BY ' . implode(',', $order); - } else { - return ''; - } - } - - /** - * @param ActiveQuery|Query $query - * @return string - */ - #[Pure] private function builderLimit(ActiveQuery|Query $query): string - { - if ($query->limit > 0) { - return ' LIMIT ' . $query->offset . ',' . $query->limit; - } else { - return ''; - } - } - - - /** - * @param array $where - * @return string - */ - private function where(array $where): string - { - if (count($where) < 1) { - return ''; - } - return implode(' AND ', $where); - } - - - /** - * @param $field - * @param $condition - * @param $_tmp - * @return string - * @throws - */ - private function resolveCondition($field, $condition, $_tmp): string - { - if (is_string($field)) { - $this->query->pushParam($condition); - return $field . ' = ?'; - } else if (is_string($condition)) { - return $condition; - } else { - return $this->_arrayMap($condition, $_tmp); - } - } - - - /** - * @param $condition - * @param $array - * @return string - * @throws - */ - private function _arrayMap($condition, $array): string - { - if (!isset($condition[0])) { - return implode(' AND ', $this->_hashMap($condition)); - } - $stroppier = strtoupper($condition[0]); - if (str_contains($stroppier, 'OR')) { - if (!is_string($condition[2])) { - $condition[2] = $this->_hashMap($condition[2]); - } - $builder = Kiri::getDi()->get(OrCondition::class); - $builder->setValue($condition[2]); - $builder->setColumn($condition[1]); - $builder->oldParams = $array; - } else if (isset(ConditionClassMap::$conditionMap[$stroppier])) { - $defaultConfig = ConditionClassMap::$conditionMap[$stroppier]; - - $class = $defaultConfig['class']; - unset($defaultConfig['class']); - - $builder = Kiri::getDi()->make($class, [], $defaultConfig); - $builder->setValue($condition[2]); - $builder->setColumn($condition[1]); - } else { - $builder = Kiri::getDi()->get(HashCondition::class); - $builder->setValue($condition); - } - - $array[] = $builder->builder(); - - return implode(' AND ', $array); - } - - - /** - * @param $condition - * @return array - */ - private function _hashMap($condition): array - { - $_array = []; - foreach ($condition as $key => $value) { - $this->query->pushParam($value); - $_array[] = $key . '= ?'; - } - return $_array; - } - - -} diff --git a/Traits/QueryTrait.php b/Traits/QueryTrait.php index 68bba64..c1fdf89 100644 --- a/Traits/QueryTrait.php +++ b/Traits/QueryTrait.php @@ -11,8 +11,8 @@ namespace Database\Traits; use Closure; -use Database\ActiveQuery; use Database\Base\ActiveQueryInterface; +use Database\Command; use Database\ISqlBuilder; use Database\ModelInterface; use Database\Query; @@ -25,20 +25,22 @@ use Kiri\Abstracts\Component; * Trait QueryTrait * @package Database\Traits */ -class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder +abstract class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder { - protected array $where = []; - protected array $select = []; - protected array $join = []; - protected array $order = []; - protected int $offset = 0; - protected int $limit = 0; - protected string $group = ''; - protected string $from = ''; - protected string $alias = 't1'; + public array $where = []; + public array $select = ['*']; + public array $join = []; + public array $order = []; + public int $offset = 0; + public int $limit = 0; + public string $group = ''; + public string $from = ''; + public string $alias = 't1'; protected array $filter = []; protected bool $lock = false; protected SqlBuilder $builder; + public array $params = []; + private array $_alias = ['t1']; /** @@ -46,21 +48,18 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder */ protected ModelInterface|string|null $modelClass; + /** - * clear + * Comply constructor. + * @throws */ - public function clear(): void + public function __construct($model = null) { - $this->where = []; - $this->select = []; - $this->join = []; - $this->order = []; - $this->offset = 0; - $this->limit = 500; - $this->group = ''; - $this->from = ''; - $this->alias = 't1'; - $this->filter = []; + if (!is_null($model)) { + $this->modelClass = $model; + } + $this->builder = SqlBuilder::builder($this); + parent::__construct(); } @@ -178,7 +177,8 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder */ public function alias(string $alias = 't1'): static { - $this->alias = $alias; + $this->alias = $alias; + $this->_alias = [$alias]; return $this; } @@ -190,7 +190,7 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder public function from(string|Closure $tableName): static { if ($tableName instanceof Closure) { - $tableName = call_user_func($tableName, $this->makeNewSqlGenerate()); + $tableName = call_user_func($tableName, $this->queryInstance()); } $this->from = $tableName; return $this; @@ -199,64 +199,90 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder /** * @param string $tableName * @param string $alias - * @param null $on - * @param array|null $param + * @param array $on + * @param array $param * @return $this * $query->join([$tableName, ['userId'=>'uuvOd']], $param) * $query->join([$tableName, ['userId'=>'uuvOd'], $param]) * $query->join($tableName, ['userId'=>'uuvOd',$param]) */ - private function join(string $tableName, string $alias, $on = NULL, array $param = NULL): static + private function join(string $tableName, string $alias, array $on, array $param = []): static { if (empty($on)) { return $this; } + + $this->_alias[] = $alias; + $join[] = $tableName . ' AS ' . $alias; - $join[] = 'ON ' . $this->onCondition($alias, $on); + $join[] = 'ON ' . $this->onCondition($on); if (empty($join)) { return $this; } $this->join[] = implode(' ', $join); if (!empty($param)) { - $this->addParams($param); + $this->bindParams($param); } return $this; } + /** - * @param $alias - * @param $on + * @param array $params + * @return void + */ + public function bindParams(array $params): void + { + foreach ($params as $param) { + $this->pushParam($param); + } + } + + + /** + * @param array $condition * @return string */ - private function onCondition($alias, $on): string + private function onCondition(array $condition): string { $array = []; - foreach ($on as $key => $item) { - if (!str_contains($item, '.')) { - $this->addParam($key, $item); + foreach ($condition as $key => $item) { + if (is_numeric($item) || !$this->isAliasField($item)) { + $array[] = $key . '= ?'; + $this->pushParam($item); } else { - $explode = explode('.', $item); - if (isset($explode[1]) && ($explode[0] == $alias || $this->alias == $explode[0])) { - $array[] = $key . '=' . $item; - } else { - $this->addParam($key, $item); - } + $array[] = $key . '=' . $item; } } return implode(' AND ', $array); } + + /** + * @param string $value + * @return bool + */ + private function isAliasField(string $value): bool + { + foreach ($this->_alias as $alias) { + if (str_starts_with($value, $alias . '.')) { + return true; + } + } + return false; + } + /** * @param string $tableName * @param string $alias - * @param $onCondition - * @param null $param + * @param array $onCondition + * @param array $param * @return $this - * @throws + * @throws Exception */ - public function leftJoin(string $tableName, string $alias, $onCondition, $param = NULL): static + public function leftJoin(string $tableName, string $alias, array $onCondition, array $param = []): static { if (class_exists($tableName)) { $model = Kiri::getDi()->get($tableName); @@ -269,14 +295,14 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder } /** - * @param $tableName - * @param $alias - * @param $onCondition - * @param null $param + * @param string $tableName + * @param string $alias + * @param array $onCondition + * @param array $param * @return $this - * @throws + * @throws Exception */ - public function rightJoin($tableName, $alias, $onCondition, $param = NULL): static + public function rightJoin(string $tableName, string $alias, array $onCondition, array $param = []): static { if (class_exists($tableName)) { $model = Kiri::getDi()->get($tableName); @@ -289,14 +315,14 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder } /** - * @param $tableName - * @param $alias - * @param $onCondition - * @param null $param + * @param string $tableName + * @param string $alias + * @param array $onCondition + * @param array $param * @return $this - * @throws + * @throws Exception */ - public function innerJoin($tableName, $alias, $onCondition, $param = NULL): static + public function innerJoin(string $tableName, string $alias, array $onCondition, array $param = []): static { if (class_exists($tableName)) { $model = Kiri::getDi()->get($tableName); @@ -332,8 +358,8 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder /** * @param string $lngField * @param string $latField - * @param int $lng1 - * @param int $lat1 + * @param int|float $lng1 + * @param int|float $lat1 * * @return $this */ @@ -389,29 +415,20 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder } /** - * @param array|string $column + * @param array $column * * @return $this */ - public function select(array|string $column = '*'): static + public function select(array $column = ['*']): static { - if ($column == '*') { - $this->select = [$column]; - } else { - if (!is_array($column)) { - $column = explode(',', $column); - } - foreach ($column as $val) { - $this->select[] = $val; - } - } + $this->select = $column; return $this; } /** * @return $this */ - public function orderRand(): static + public function rand(): static { $this->order[] = 'RAND()'; return $this; @@ -510,29 +527,13 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder } - /** - * @param $value - * @return ActiveQuery - * @throws - */ - public function makeNewQuery($value): ActiveQuery - { - $activeQuery = new ActiveQuery($this->modelClass); - call_user_func($value, $activeQuery); - if (empty($activeQuery->from)) { - $activeQuery->from($activeQuery->modelClass->getTable()); - } - return $activeQuery; - } - - /** * @return Query * @throws */ - public function makeNewSqlGenerate(): Query + public function queryInstance(): Query { - return Kiri::createObject(['class' => Query::class]); + return new Query(); } @@ -588,43 +589,13 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder return $this; } - /** - * @param array|null $params - * - * @return $this - */ - public function bindParams(?array $params = []): static - { - if ($params === null) { - return $this; - } - foreach ($params as $param) { - $this->attributes[] = $param; - } - return $this; - } - - /** - * @param string $key - * @param mixed $value - * @return $this - */ - public function bindParam(string $key, mixed $value): static - { - if (is_string($value)) { - $value = addslashes($value); - } - $this->attributes[$key] = $value; - return $this; - } - /** * @param mixed $value * @return $this */ public function pushParam(mixed $value): static { - $this->attributes[] = $value; + $this->params[] = $value; return $this; } @@ -670,13 +641,13 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder */ public function makeClosureFunction(Closure|array $closure): string { - $generate = $this->makeNewSqlGenerate(); + $generate = $this->queryInstance(); if ($closure instanceof Closure) { call_user_func($closure, $generate); } else { $generate->addArray($closure); } - return $generate->getSql(); + return $generate->build(); } @@ -766,12 +737,28 @@ class QueryTrait extends Component implements ActiveQueryInterface, ISqlBuilder /** - * @return $this + * @param string $querySql + * @param array $params + * @return Command */ - public function oneLimit(): static + public function buildCommand(string $querySql, array $params = []): Command { - $this->limit = 1; - return $this; + $connection = $this->modelClass->getConnection(); + if (count($params) > 0) { + $this->bindParams($params); + } + return $connection->createCommand($querySql, $this->params); } + + /** + * @return string + * @throws + */ + public function build(): string + { + return $this->builder->get(); + } + + }