From b7e59d1c965aab102ca5e2d93fb2c5e2898c068d Mon Sep 17 00:00:00 2001 From: whwyy Date: Tue, 30 Jun 2026 23:06:55 +0800 Subject: [PATCH] eee --- SqlBuilder.php | 717 +++++++++++++++++++++++++------------------------ 1 file changed, 362 insertions(+), 355 deletions(-) diff --git a/SqlBuilder.php b/SqlBuilder.php index 2901e79..5bc49fc 100644 --- a/SqlBuilder.php +++ b/SqlBuilder.php @@ -19,240 +19,247 @@ use Database\Traits\QueryTrait; class SqlBuilder extends Component { - /** - * @var ActiveQuery|Query|ISqlBuilder|null - */ - public ActiveQuery|Query|ISqlBuilder|null $query; + /** + * @var ActiveQuery|Query|ISqlBuilder|null + */ + public ActiveQuery|Query|ISqlBuilder|null $query; - /** - * @param ActiveQuery|Query|ISqlBuilder|null $config - */ - public function __construct(ActiveQuery|Query|null|ISqlBuilder $config) - { - parent::__construct(); + /** + * @param ActiveQuery|Query|ISqlBuilder|null $config + */ + public function __construct(ActiveQuery|Query|null|ISqlBuilder $config) + { + parent::__construct(); - $this->query = $config; - } + $this->query = $config; + } - /** - * @param ISqlBuilder|null $query - * @return $this - * @throws - */ - public static function builder(ISqlBuilder|null $query): static - { - return new static($query); - } + /** + * @param ISqlBuilder|null $query + * @return $this + * @throws + */ + public static function builder(ISqlBuilder|null $query): static + { + return new static($query); + } - /** - * @return string - * @throws - */ - public function getCondition(): string - { - return $this->where($this->query->where); - } + /** + * @return string + * @throws + */ + public function getCondition(): string + { + return $this->where($this->query->where); + } - /** - * @param array $compiler - * @return string - * @throws - */ - public function hashCompiler(array $compiler): string - { - return $this->where($compiler); - } + /** + * @param array $compiler + * @return string + * @throws + */ + public function hashCompiler(array $compiler): string + { + return $this->where($compiler); + } - /** - * @param array $attributes - * @return bool|array - * @throws - */ - public function update(array $attributes): bool|string - { - return $this->__updateBuilder($this->makeParams($attributes)); - } + /** + * @param array $attributes + * @return bool|array + * @throws + */ + public function update(array $attributes): bool|string + { + $params = $this->query->params; + $this->query->params = []; + $array = $this->makeParams($attributes); + foreach ($array as $name => $value) { + $this->query->pushParam($value); + } + return $this->__updateBuilder($array); + } - /** - * @param array $attributes - * @param string $opera - * @return bool|array - * @throws - */ - public function mathematics(array $attributes, string $opera = '+'): bool|string - { - $string = []; - foreach ($attributes as $attribute => $value) { - $string[] = $attribute . '=' . $attribute . $opera . $value; - } - return $this->__updateBuilder($string); - } + /** + * @param array $attributes + * @param string $opera + * @return bool|array + * @throws + */ + public function mathematics(array $attributes, string $opera = '+'): bool|string + { + $string = []; + foreach ($attributes as $attribute => $value) { + $string[] = $attribute . '=' . $attribute . $opera . $value; + } + return $this->__updateBuilder($string); + } - /** - * @param array $string - * @return string|bool - * @throws - */ - private function __updateBuilder(array $string): string|bool - { - if (empty($string)) { - return Kiri::getLogger()->logCategory('None data update.'); - } + /** + * @param array $string + * @return string|bool + * @throws + */ + private function __updateBuilder(array $string): string|bool + { + if (empty($string)) { + return Kiri::getLogger()->logCategory('None data update.'); + } - var_dump($string, $this->query); + var_dump($string, $this->query); $sql = 'UPDATE ' . $this->getFromAlias() . ' SET ' . implode(',', $string) . $this->make(); var_dump($string, $this); return $sql; - } + } - /** - * @param array $attributes - * @param false $isBatch - * @return array - * @throws - */ - public function insert(array $attributes, bool $isBatch = false): string - { - $update = 'INSERT INTO ' . $this->getFromAlias(); - if ($isBatch === false) { - $attributes = [$attributes]; - } - $update .= '(' . implode(',', $this->getFields($attributes)) . ') VALUES '; + /** + * @param array $attributes + * @param false $isBatch + * @return array + * @throws + */ + public function insert(array $attributes, bool $isBatch = false): string + { + $update = 'INSERT INTO ' . $this->getFromAlias(); + if ($isBatch === false) { + $attributes = [$attributes]; + } + $update .= '(' . implode(',', $this->getFields($attributes)) . ') VALUES '; - $keys = []; - foreach ($attributes as $attribute) { - $_keys = $this->makeParams($attribute, true); + $keys = []; + foreach ($attributes as $attribute) { + $_keys = $this->makeParams($attribute, true); - $keys[] = implode(',', $_keys); - } - return $update . '(' . implode('),(', $keys) . ')'; - } + $keys[] = implode(',', $_keys); + } + return $update . '(' . implode('),(', $keys) . ')'; + } - /** - * @return string - * @throws - */ - public function delete(): string - { - return 'DELETE FROM ' . $this->getFromAlias() . $this->make(); - } + /** + * @return string + * @throws + */ + public function delete(): string + { + return 'DELETE FROM ' . $this->getFromAlias() . $this->make(); + } - /** - * @param $attributes - * @return array - */ - #[Pure] private function getFields(array $attributes): array - { - return array_keys(current($attributes)); - } + /** + * @param $attributes + * @return array + */ + #[Pure] + private function getFields(array $attributes): array + { + return array_keys(current($attributes)); + } - /** - * @param array $attributes - * @param bool $isInsert - * @return array[] - * a=:b, - */ - private function makeParams(array $attributes, bool $isInsert = false): array - { - $keys = []; - foreach ($attributes as $key => $value) { - if ($isInsert === true) { - $keys[] = '?'; - $this->query->pushParam($value); - } else { - $keys = $this->resolveParams($key, $value, $keys); - } - } - return $keys; - } + /** + * @param array $attributes + * @param bool $isInsert + * @return array[] + * a=:b, + */ + private function makeParams(array $attributes, bool $isInsert = false): array + { + $keys = []; + foreach ($attributes as $key => $value) { + if ($isInsert === true) { + $keys[] = '?'; + $this->query->pushParam($value); + } else { + $keys = $this->resolveParams($key, $value, $keys); + } + } + return $keys; + } - /** - * @param string $key - * @param mixed $value - * @param array $keys - * @return array - */ - private function resolveParams(string $key, mixed $value, array $keys): array - { - if (is_null($value)) { - return $keys; - } - if (preg_match('/^[+|-]\s\d+$/', (string)$value)) { - $keys[] = $key . '=' . $key . ' ' . $value; - } else { - $this->query->pushParam($value); - $keys[] = $key . '= ?'; - } - return $keys; - } + /** + * @param string $key + * @param mixed $value + * @param array $keys + * @return array + */ + private function resolveParams(string $key, mixed $value, array $keys): array + { + if (is_null($value)) { + return $keys; + } + if (preg_match('/^[+|-]\s\d+$/', (string)$value)) { + $keys[] = $key . '=' . $key . ' ' . $value; + } else { + $this->query->pushParam($value); + $keys[] = $key . '= ?'; + } + return $keys; + } - /** - * @return string - * @throws - */ - public function one(): string - { - $this->query->offset(0)->limit(1); - return $this->makeSelect($this->query) . $this->make() . $this->makeLimit(); - } + /** + * @return string + * @throws + */ + public function one(): string + { + $this->query->offset(0)->limit(1); + return $this->makeSelect($this->query) . $this->make() . $this->makeLimit(); + } - /** - * @return string - * @throws - */ - public function all(): string - { - return $this->makeSelect($this->query) . $this->make() . $this->makeLimit(); - } + /** + * @return string + * @throws + */ + public function all(): string + { + return $this->makeSelect($this->query) . $this->make() . $this->makeLimit(); + } - /** - * @return string - * @throws - */ - public function count(): string - { - return $this->makeSelect(['COUNT(*)']) . $this->make(); - } + /** + * @return string + * @throws + */ + public function count(): string + { + return $this->makeSelect(['COUNT(*)']) . $this->make(); + } - /** - * @return string - * @throws - */ - public function exists(): string - { - return $this->makeSelect(['0']) . $this->make(); - } + /** + * @return string + * @throws + */ + public function exists(): string + { + return $this->makeSelect(['0']) . $this->make(); + } - /** - * @param string $table - * @return string - * @throws - */ - public function columns(string $table): string - { - $driver = $this->getDriver(); - if (in_array($driver, ['pgsql', 'postgresql'])) { - $tableName = trim($table, '"`'); - return "SELECT + /** + * @param string $table + * @return string + * @throws + */ + public function columns(string $table): string + { + $driver = $this->getDriver(); + if (in_array($driver, ['pgsql', 'postgresql'])) { + $tableName = trim($table, '"`'); + return "SELECT column_name as Field, data_type as Type, is_nullable as Null, @@ -262,194 +269,194 @@ class SqlBuilder extends Component FROM information_schema.columns WHERE table_name = '$tableName' ORDER BY ordinal_position"; - } - return 'SHOW FULL FIELDS FROM ' . $table; - } + } + return 'SHOW FULL FIELDS FROM ' . $table; + } - /** - * @return string - * @throws - */ - private function make(): string - { - $select = $this->makeCondition(); - $select .= $this->makeGroup(); - $select .= $this->makeOrder(); - return $select; - } + /** + * @return string + * @throws + */ + private function make(): string + { + $select = $this->makeCondition(); + $select .= $this->makeGroup(); + $select .= $this->makeOrder(); + return $select; + } - /** - * @param mixed $select 列名数组或 QueryTrait 对象 - * @return string - */ - private function makeSelect(mixed $select = ['*']): string - { - if (!is_array($select)) { - $select = ['*']; - } - $sql = "SELECT " . implode(',', $select) . " FROM " . $this->getFromAlias(); - if ($this->query->join !== []) { - $sql .= ' ' . implode(' ', $this->query->join); - } - return $sql; - } + /** + * @param mixed $select 列名数组或 QueryTrait 对象 + * @return string + */ + private function makeSelect(mixed $select = ['*']): string + { + if (!is_array($select)) { + $select = ['*']; + } + $sql = "SELECT " . implode(',', $select) . " FROM " . $this->getFromAlias(); + if ($this->query->join !== []) { + $sql .= ' ' . implode(' ', $this->query->join); + } + return $sql; + } - /** - * @return string - */ - private function makeGroup(): string - { - if ($this->query->group !== '' && $this->query->group !== '0') { - return ' GROUP BY ' . $this->query->group; - } - return ''; - } + /** + * @return string + */ + private function makeGroup(): string + { + if ($this->query->group !== '' && $this->query->group !== '0') { + 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 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; - } + /** + * @return string + */ + private function makeCondition(): string + { + $condition = $this->where($this->query->where); + if (empty($condition)) { + return ''; + } + return ' WHERE ' . $condition; + } - /** - * @return string - * @throws - */ - private function makeLimit(): string - { - if ($this->query->offset >= 0 && $this->query->limit >= 1) { - $driver = $this->getDriver(); - if (in_array($driver, ['pgsql', 'postgresql'])) { - return ' LIMIT ' . $this->query->limit . ' OFFSET ' . $this->query->offset; - } - return ' LIMIT ' . $this->query->offset . ',' . $this->query->limit; - } - return ''; - } + /** + * @return string + * @throws + */ + private function makeLimit(): string + { + if ($this->query->offset >= 0 && $this->query->limit >= 1) { + $driver = $this->getDriver(); + if (in_array($driver, ['pgsql', 'postgresql'])) { + return ' LIMIT ' . $this->query->limit . ' OFFSET ' . $this->query->offset; + } + return ' LIMIT ' . $this->query->offset . ',' . $this->query->limit; + } + return ''; + } - /** - * @param false $isCount - * @return string - * @throws - */ - public function get(bool $isCount = false): string - { - if ($isCount === false) { - return $this->all(); - } - return $this->count(); - } + /** + * @param false $isCount + * @return string + * @throws + */ + public function get(bool $isCount = false): string + { + if ($isCount === false) { + return $this->all(); + } + return $this->count(); + } - /** - * @return string - * @throws - */ - public function truncate(): string - { - return sprintf('TRUNCATE %s', $this->getFromAlias()); - } + /** + * @return string + * @throws + */ + public function truncate(): string + { + return sprintf('TRUNCATE %s', $this->getFromAlias()); + } - /** - * @param array $where - * @return string - */ - private function where(array $where): string - { - if (count($where) < 1) { - return ''; - } - $_tmp = []; - foreach ($where as $key => $value) { - $_tmp[] = $this->resolveCondition($key, $value); - } - return implode(' AND ', $_tmp); - } + /** + * @param array $where + * @return string + */ + private function where(array $where): string + { + if (count($where) < 1) { + return ''; + } + $_tmp = []; + foreach ($where as $key => $value) { + $_tmp[] = $this->resolveCondition($key, $value); + } + return implode(' AND ', $_tmp); + } - /** - * @param string $field - * @param mixed $condition - * @return string - */ - private function resolveCondition(string|int $field, mixed $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 string $field + * @param mixed $condition + * @return string + */ + private function resolveCondition(string|int $field, mixed $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(array $condition): array - { - $_array = []; - foreach ($condition as $key => $value) { - $this->query->pushParam($value); - $_array[] = $key . '= ?'; - } - return $_array; - } + /** + * @param $condition + * @return array + */ + private function _hashMap(array $condition): array + { + $_array = []; + foreach ($condition as $key => $value) { + $this->query->pushParam($value); + $_array[] = $key . '= ?'; + } + return $_array; + } - /** - * 获取数据库驱动类型 - * @return string - * @throws - */ - private function getDriver(): string - { - try { - if ($this->query instanceof ActiveQuery && $this->query->modelClass !== null) { - if ($this->query->modelClass instanceof Model) { - $connection = $this->query->modelClass->getConnection(); - if ($connection instanceof Connection) { - return strtolower($connection->driver ?? 'mysql'); - } - } - } - if (method_exists($this->query, 'getConnection')) { - $connection = $this->query->getConnection(); - if ($connection instanceof Connection) { - return strtolower($connection->driver ?? 'mysql'); - } - } - } catch (\Throwable $e) { + /** + * 获取数据库驱动类型 + * @return string + * @throws + */ + private function getDriver(): string + { + try { + if ($this->query instanceof ActiveQuery && $this->query->modelClass !== null) { + if ($this->query->modelClass instanceof Model) { + $connection = $this->query->modelClass->getConnection(); + if ($connection instanceof Connection) { + return strtolower($connection->driver ?? 'mysql'); + } + } + } + if (method_exists($this->query, 'getConnection')) { + $connection = $this->query->getConnection(); + if ($connection instanceof Connection) { + return strtolower($connection->driver ?? 'mysql'); + } + } + } catch (\Throwable $e) { $this->getLogger()->json_log($e); } - return 'mysql'; - } + return 'mysql'; + } /**