This commit is contained in:
2023-12-13 14:47:23 +08:00
parent 85eaeba8ba
commit 3179e95a82
15 changed files with 467 additions and 1019 deletions
+53 -137
View File
@@ -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();
}
}
+7 -20
View File
@@ -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();
}
+10 -9
View File
@@ -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
+29 -27
View File
@@ -1,4 +1,4 @@
<?php
<?php /** @noinspection ALL */
/**
* Created by PhpStorm.
* User: whwyy
@@ -178,7 +178,7 @@ abstract class Model extends Component implements ModelInterface, ArrayAccess, \
*/
public function getLastError(): string
{
return Kiri::getLogger()->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();
}
+30 -49
View File
@@ -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);
}
+45 -40
View File
@@ -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;
}
}
-2
View File
@@ -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;
+18 -42
View File
@@ -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.');
}
+44 -64
View File
@@ -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);
}
-28
View File
@@ -1,28 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Orm;
use Database\Traits\Builder;
/**
* Trait Condition
* @package Database\Orm
*/
trait Condition
{
use Builder;
/**
* @param $query
* @return string
* @throws
*/
public function getWhere($query): string
{
return $this->where($query);
}
}
-206
View File
@@ -1,206 +0,0 @@
<?php
declare(strict_types=1);
namespace Database;
use Closure;
use Exception;
use Kiri\Abstracts\Component;
/**
* Class Pagination
* @package Database
*/
class Pagination extends Component
{
/** @var ActiveQuery */
private ActiveQuery $activeQuery;
/** @var int 从第几个开始查 */
private int $_offset = 0;
/** @var int 每页数量 */
private int $_limit = 100;
/** @var int 最大查询数量 */
private int $_max = 0;
/** @var int 当前已查询数量 */
private int $_length = 0;
/** @var Closure */
private Closure $_callback;
/**
* PaginationIteration constructor.
* @param ActiveQuery $activeQuery
* @param array $config
* @throws
*/
public function __construct(ActiveQuery $activeQuery, array $config = [])
{
parent::__construct();
$this->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];
}
}
-19
View File
@@ -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
+116 -48
View File
@@ -1,12 +1,12 @@
<?php
<?php /** @noinspection ALL */
declare(strict_types=1);
namespace Database;
use Database\Traits\Builder;
use JetBrains\PhpStorm\Pure;
use Kiri;
use Kiri\Abstracts\Component;
@@ -17,9 +17,6 @@ use Kiri\Abstracts\Component;
class SqlBuilder extends Component
{
use Builder;
/**
* @var ActiveQuery|Query|ISqlBuilder|null
*/
@@ -54,7 +51,7 @@ class SqlBuilder extends Component
*/
public function getCondition(): string
{
return $this->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;
}
}
-200
View File
@@ -1,200 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Traits;
use Database\ActiveQuery;
use Database\Base\ConditionClassMap;
use Database\Condition\HashCondition;
use Database\Condition\OrCondition;
use Database\Query;
use Exception;
use JetBrains\PhpStorm\Pure;
use Kiri\Exception\NotFindClassException;
use Kiri;
use ReflectionException;
/**
* Trait Builder
* @package Database\Traits
*/
trait Builder
{
/**
* @param $alias
* @return string
*/
private function builderAlias($alias): string
{
return " AS " . $alias;
}
/**
* @param $table
* @return string
* @throws
*/
private function builderFrom($table): string
{
if ($table instanceof ActiveQuery) {
$table = '(' . $table->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;
}
}
+115 -128
View File
@@ -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();
}
}