diff --git a/Database/ActiveQuery.php b/Database/ActiveQuery.php index 566a7ae2..e0c4a52b 100644 --- a/Database/ActiveQuery.php +++ b/Database/ActiveQuery.php @@ -10,10 +10,8 @@ declare(strict_types=1); namespace Database; use Snowflake\Abstracts\Component; -use Database\Orm\Select; use Database\Traits\QueryTrait; use Exception; -use Snowflake\Exception\ComponentException; use Snowflake\Snowflake; /** @@ -268,8 +266,7 @@ class ActiveQuery extends Component */ public function batchUpdate(array $data): Command|array|bool|int|string { - return $this->execute($this->builder->update($data)) - ->exec(); + return $this->execute($this->builder->update($data))->exec(); } /** @@ -279,8 +276,7 @@ class ActiveQuery extends Component */ public function batchInsert(array $data): bool { - return $this->execute($this->builder->insert($data, true)) - ->exec(); + return $this->execute($this->builder->insert($data, true))->exec(); } /** diff --git a/Database/ActiveRecord.php b/Database/ActiveRecord.php index 54441b2a..c52c7751 100644 --- a/Database/ActiveRecord.php +++ b/Database/ActiveRecord.php @@ -55,7 +55,7 @@ class ActiveRecord extends BaseActiveRecord */ public function increment(string $column, int $value): bool|ActiveRecord { - if (!$this->mathematics(self::INCR, [$column => $value])) { + if (!$this->mathematics([$column => $value], '-')) { return false; } $this->{$column} += $value; @@ -71,7 +71,7 @@ class ActiveRecord extends BaseActiveRecord */ public function decrement(string $column, int $value): bool|ActiveRecord { - if (!$this->mathematics(self::DECR, [$column => $value])) { + if (!$this->mathematics([$column => $value], '-')) { return false; } $this->{$column} -= $value; @@ -86,7 +86,7 @@ class ActiveRecord extends BaseActiveRecord */ public function increments(array $columns): bool|static { - if (!$this->mathematics(self::INCR, $columns)) { + if (!$this->mathematics($columns, '+')) { return false; } foreach ($columns as $key => $attribute) { @@ -103,7 +103,7 @@ class ActiveRecord extends BaseActiveRecord */ public function decrements(array $columns): bool|static { - if (!$this->mathematics(self::DECR, $columns)) { + if (!$this->mathematics($columns, '-')) { return false; } foreach ($columns as $key => $attribute) { @@ -152,17 +152,16 @@ class ActiveRecord extends BaseActiveRecord * @return array|bool|int|string|null * @throws Exception */ - private function mathematics($action, $columns, $condition = []): int|bool|array|string|null + private function mathematics($columns, $action, $condition = []): int|bool|array|string|null { if (empty($condition)) { $condition = [$this->getPrimary() => $this->getPrimaryValue()]; } - $execute = static::getDb()->createCommand() - ->mathematics(self::getTable(), [$action => $columns], $condition); - if ($execute instanceof Command) { - return $execute->exec($this); - } - return false; + + $activeQuery = static::find()->where($condition); + return static::getDb() + ->createCommand(SqlBuilder::builder($activeQuery)->mathematics($columns, $action)) + ->exec(); } diff --git a/Database/Builder.php b/Database/Builder.php index 23d6cd32..27f90ee0 100644 --- a/Database/Builder.php +++ b/Database/Builder.php @@ -17,7 +17,6 @@ trait Builder { - /** * @param $alias * @return string @@ -35,7 +34,7 @@ trait Builder private function builderFrom($table): string { if ($table instanceof ActiveQuery) { - $table = '(' . $table->getBuild()->getQuery($table) . ')'; + $table = '(' . SqlBuilder::builder($table)->get($table) . ')'; } return " FROM " . $table; } @@ -111,7 +110,6 @@ trait Builder } - /** * @param $where * @return string diff --git a/Database/Command.php b/Database/Command.php index 1f6a4e32..913c0ccc 100644 --- a/Database/Command.php +++ b/Database/Command.php @@ -65,63 +65,6 @@ class Command extends Component return $this->execute(static::EXECUTE, $isInsert, $hasAutoIncrement); } - /** - * @param $model - * @param $attributes - * @param $condition - * @param $param - * @return Command - * @throws Exception - */ - public function update($model, $attributes, $condition, $param): Command - { - $change = $this->db->getSchema()->getChange(); - $sql = $change->update($model, $attributes, $condition, $param); - return $this->setSql($sql)->bindValues($param); - } - - - /** - * @param $tableName - * @param $attributes - * @param $condition - * @return Command - * @throws Exception - */ - public function batchUpdate($tableName, $attributes, $condition): Command - { - $change = $this->db->getSchema(); - [$sql, $param] = $change->getChange()->batchUpdate($tableName, $change, $attributes, $condition); - return $this->setSql($sql)->bindValues($param); - } - - - /** - * @param $tableName - * @param $attributes - * @return Command - * @throws Exception - */ - public function batchInsert($tableName, $attributes): Command - { - $change = $this->db->getSchema(); - [$sql, $param] = $change->getChange()->batchInsert($tableName, $change, $attributes); - return $this->setSql($sql)->bindValues($param); - } - - /** - * @param $tableName - * @param $attributes - * @param $param - * @return Command - * @throws Exception - */ - public function insert($tableName, $attributes, $param): Command - { - $sql = $this->db->getSchema() - ->getChange()->insert($tableName, $attributes, $param); - return $this->setSql($sql)->bindValues($param); - } /** * @return int|bool|array|string|null @@ -132,25 +75,6 @@ class Command extends Component return $this->execute(static::FETCH_ALL); } - /** - * @param $tableName - * @param $param - * @param $condition - * @return bool|Command - * @throws ReflectionException - * @throws NotFindClassException - * @throws Exception - */ - public function mathematics($tableName, $param, $condition): bool|static - { - $change = $this->db->getSchema()->getChange(); - $sql = $change->mathematics($tableName, $param, [$condition]); - if ($sql === false) { - return false; - } - return $this->setSql($sql); - } - /** * @return array|bool|int|string|null * @throws Exception diff --git a/Database/Connection.php b/Database/Connection.php index fbd6cb69..141211fd 100644 --- a/Database/Connection.php +++ b/Database/Connection.php @@ -14,7 +14,6 @@ namespace Database; use ReflectionException; use Snowflake\Abstracts\Component; use Database\Mysql\Schema; -use Database\Orm\Select; use Exception; use PDO; use Snowflake\Event; @@ -271,14 +270,6 @@ class Connection extends Component return $command->bindValues($attributes); } - /** - * @return Select - * @throws Exception - */ - public function getBuild(): Select - { - return $this->getSchema()->getQueryBuilder(); - } /** * diff --git a/Database/Db.php b/Database/Db.php index c560df54..36321c1b 100644 --- a/Database/Db.php +++ b/Database/Db.php @@ -104,8 +104,7 @@ class Db if (empty($db)) { $db = Snowflake::app()->database; } - $query = $db->getSchema()->getQueryBuilder(); - return $db->createCommand($query->getQuery($this)) + return $db->createCommand(SqlBuilder::builder($this)->one()) ->all(); } @@ -128,8 +127,7 @@ class Db if (empty($db)) { $db = Snowflake::app()->database; } - $query = $db->getSchema()->getQueryBuilder(); - return $db->createCommand($query->getQuery($this)) + return $db->createCommand(SqlBuilder::builder($this)->all()) ->one(); } @@ -143,9 +141,8 @@ class Db if (empty($db)) { $db = Snowflake::app()->database; } - $query = $db->getSchema()->getQueryBuilder(); - return $db->createCommand($query->count($this)) - ->rowCount(); + return $db->createCommand(SqlBuilder::builder($this)->count()) + ->exec(); } /** @@ -158,8 +155,7 @@ class Db if (empty($db)) { $db = Snowflake::app()->database; } - $query = $db->getSchema()->getQueryBuilder(); - return $db->createCommand($query->getQuery($this)) + return $db->createCommand(SqlBuilder::builder($this)->one()) ->fetchColumn(); } diff --git a/Database/Mysql/Columns.php b/Database/Mysql/Columns.php index 3dc94cfe..461e2de6 100644 --- a/Database/Mysql/Columns.php +++ b/Database/Mysql/Columns.php @@ -11,7 +11,7 @@ declare(strict_types=1); namespace Database\Mysql; - +use Database\SqlBuilder; use Snowflake\Abstracts\Component; use Database\Connection; use Exception; @@ -276,7 +276,7 @@ class Columns extends Component private function structure($table): array|static { if (!isset($this->columns[$table]) || empty($this->columns[$table])) { - $column = $this->db->createCommand($this->db->getBuild()->getColumn($table))->all(); + $column = $this->db->createCommand(SqlBuilder::builder(null)->columns($table))->all(); if (empty($column)) { throw new Exception("The table " . $table . " not exists."); } diff --git a/Database/Mysql/Schema.php b/Database/Mysql/Schema.php index 6f3f1a51..a1b82fd9 100644 --- a/Database/Mysql/Schema.php +++ b/Database/Mysql/Schema.php @@ -5,8 +5,6 @@ namespace Database\Mysql; use Snowflake\Abstracts\Component; use Database\Connection; -use Database\Orm\Change; -use Database\Orm\Select; /** * Class Schema @@ -18,37 +16,9 @@ class Schema extends Component /** @var ?Connection */ public ?Connection $db; - /** @var ?Select */ - private ?Select $_builder = null; - /** @var ?Columns $_column*/ private ?Columns $_column = null; - /** @var ?Change */ - private ?Change $_change = null; - - /** - * @return Select|null - */ - public function getQueryBuilder(): ?Select - { - if ($this->_builder === null) { - $this->_builder = new Select(); - } - return $this->_builder; - } - - /** - * @return Change - */ - public function getChange(): Change - { - if ($this->_change === null) { - $this->_change = new Change(); - } - return $this->_change; - } - /** * @return Columns|null diff --git a/Database/Orm/Change.php b/Database/Orm/Change.php deleted file mode 100644 index dab25ebd..00000000 --- a/Database/Orm/Change.php +++ /dev/null @@ -1,228 +0,0 @@ -where($condition); - } - return "UPDATE " . $model . ' SET ' . $where; - } - - /** - * @param string $table - * @param Schema $db - * @param array $attributes - * @param $condition - * @return array|string - * @throws Exception - */ - public function batchUpdate(string $table, Schema $db, array $attributes, $condition): array|string - { - $param = []; - $_attributes = []; - - $format = $db->getColumns()->table($table); - foreach ($attributes as $key => $val) { - if ($val === null) { - continue; - } - $_attributes[':' . $key] = $format->fieldFormat($key, $val); - $param[] = $key . '=:' . $key; - } - if (empty($param)) { - return ''; - } - $param = implode(',', $param); - if (!empty($condition)) { - $param .= $condition; - } - return ['UPDATE ' . $table . ' SET ' . $param, $_attributes]; - } - - /** - * @param $table - * @param $params - * @param $condition - * @return string|bool - * @throws Exception - */ - public function mathematics($table, $params, $condition): string|bool - { - $_tmp = $newParam = []; - if (isset($params['incr']) && is_array($params['incr'])) { - $_tmp = $this->assemble($params['incr'], ' + ', $_tmp); - } - if (isset($params['decr']) && is_array($params['decr'])) { - $_tmp = $this->assemble($params['decr'], ' - ', $_tmp); - } - if (empty($_tmp)) { - return $this->addError('Not has IncrBy or DecrBy values.'); - } - $_tmp = implode(',', $_tmp); - if (!empty($condition)) { - $_tmp .= $this->where($condition); - } - return 'UPDATE ' . $table . ' SET ' . $_tmp; - } - - /** - * @param $params - * @param $op - * @param array $_tmp - * @return array - * @throws Exception - */ - private function assemble($params, $op, array $_tmp): array - { - foreach ($params as $key => $val) { - $_tmp[] = sprintf('%s=%s%s%d', $key, $key, $op, $val); - } - return $_tmp; - } - - - /** - * @param $table - * @param $attributes - * @param array|null $params - * @return string - * @throws Exception - */ - public function insert($table, $attributes, array $params = NULL): string - { - $sql = $this->inserts($table, implode(',', $attributes), '(:' . implode(',:', $attributes) . ')'); - if (empty($params)) { - throw new Exception("save data param not find."); - } - foreach ($params as $key => $val) { - if (!str_contains($sql, ':' . $key)) { - throw new Exception("save $key data param not find."); - } - } - return $sql; - } - - - /** - * @param $table - * @param Schema $db - * @param array|NULL $params - * @return array - * @throws Exception - */ - public function batchInsert($table, Schema $db, array $params = NULL): array - { - if (empty($params)) { - throw new Exception("save data param not find."); - } - $insert = $insertData = []; - - $format = $db->getColumns()->table($table); - - $attributes = array_keys(current($params)); - - foreach ($params as $key => $val) { - if (!is_array($val)) { - continue; - } - array_push($insert, '(:' . implode($key . ',:', $attributes) . $key . ')'); - foreach ($attributes as $myVal) { - $insertData[':' . $myVal . $key] = $format->fieldFormat($myVal, $val[$myVal]); - } - } - if (empty($insertData) || empty($insert)) { - throw new Exception("save data is empty."); - } - $sql = $this->inserts($table, implode(',', $attributes), implode(',', $insert)); - return [$sql, $insertData]; - } - - - /** - * @param $table - * @param $fields - * @param $data - * @return string - * 构建SQL语句 - */ - #[Pure] private function inserts($table, $fields, $data): string - { - return sprintf('INSERT IGNORE INTO' . ' %s (%s) VALUES %s', $table, $fields, $data); - } - - - /** - * @param ActiveQuery $query - * @return string - * @throws Exception - */ - public function delete(ActiveQuery $query): string - { - if (empty($query->from)) { - $query->from = $query->getTable(); - } - - $condition = $this->where($query->where); - if (empty($condition) && !$query->ifNotWhere) { - throw new Exception('clear data must has condition.'); - } - $query = $this->builderFrom($query->from) . $condition; - - return 'DELETE ' . $query; - } - - /** - * @param string $tableName - * @return string - */ - public function truncate(string $tableName): string - { - return 'TRUNCATE ' . $tableName; - } - - -} diff --git a/Database/Orm/Select.php b/Database/Orm/Select.php deleted file mode 100644 index 95a10606..00000000 --- a/Database/Orm/Select.php +++ /dev/null @@ -1,86 +0,0 @@ -generate($query, false); - } - - /** - * @param ActiveQuery|Db|Sql $query - * @return string - * @throws Exception - */ - public function count(ActiveQuery|Db|Sql $query): string - { - return $this->generate($query, true); - } - - /** - * @param ActiveQuery|Db|Sql $query - * @param bool $isCount - * @return string - * @throws Exception - */ - private function generate(ActiveQuery|Db|Sql $query, $isCount = false): string - { - if (empty($query->from)) { - $query->from = $query->getTable(); - } - $builder = array_filter([ - $this->builderSelect($query->select, $isCount), - $this->builderFrom($query->from), - $this->builderAlias($query->alias), - $this->builderJoin($query->join), - $this->where($query->where), - $this->builderGroup($query->group) - ], function ($value) { - return !empty($value); - }); - if ($isCount) { - return implode('', $builder); - } - - $order = $this->builderOrder($query->order); - if (!empty($order)) { - $builder[] = $order; - } - $builder[] = $this->builderLimit($query); - - return implode('', $builder); - } - - - /** - * @param $table - * @return string - */ - public function getColumn($table): string - { - return 'SHOW FULL FIELDS FROM ' . $table; - } -} diff --git a/Database/Sql.php b/Database/Sql.php index e91acb16..f67e3f60 100644 --- a/Database/Sql.php +++ b/Database/Sql.php @@ -10,7 +10,6 @@ declare(strict_types=1); namespace Database; -use Database\Orm\Select; use Database\Traits\QueryTrait; use Exception; @@ -29,7 +28,7 @@ class Sql */ public function getSql(): string { - return (new Select())->getQuery($this); + return SqlBuilder::builder($this)->get(); } @@ -39,7 +38,7 @@ class Sql */ public function getCondition(): string { - return (new Select())->getWhere($this); + return SqlBuilder::builder($this)->getCondition(); } diff --git a/Database/SqlBuilder.php b/Database/SqlBuilder.php index 106f4784..e98eb373 100644 --- a/Database/SqlBuilder.php +++ b/Database/SqlBuilder.php @@ -4,6 +4,7 @@ namespace Database; +use Database\Traits\QueryTrait; use Exception; use JetBrains\PhpStorm\Pure; use Snowflake\Abstracts\Component; @@ -19,19 +20,29 @@ class SqlBuilder extends Component use Builder; - public ActiveQuery $query; + public ActiveQuery|Sql $query; /** * @param $query * @return $this */ - public static function builder($query): static + public static function builder(QueryTrait|null $query): static { return new static(['query' => $query]); } + /** + * @return string + * @throws Exception + */ + public function getCondition(): string + { + return $this->conditionToString(); + } + + /** * @param array $attributes * @return bool|array @@ -51,6 +62,30 @@ class SqlBuilder extends Component } + /** + * @param array $attributes + * @param string $opera + * @return bool|array + * @throws Exception + */ + public function mathematics(array $attributes, $opera = '+'): bool|array + { + $string = $array = []; + foreach ($attributes as $attribute => $value) { + $string[] = $attribute . '=' . $attribute . $opera . $value; + } + + if (empty($string) || empty($array)) { + return $this->addError('None data update.'); + } + + $update = 'UPDATE ' . $this->tableName() . ' SET ' . implode(',', $string) . $this->conditionToString(); + $update .= $this->builderLimit($this->query); + + return [$update, []]; + } + + /** * @param array $attributes * @param false $isBatch @@ -116,7 +151,8 @@ class SqlBuilder extends Component */ public function one(): string { - return $this->_prefix(true) . ' LIMIT 0,1'; + $this->query->limit(0, 1); + return $this->_prefix(true); } @@ -126,7 +162,7 @@ class SqlBuilder extends Component */ public function all(): string { - return $this->_prefix(true) . $this->builderLimit($this->query); + return $this->_prefix(true); } @@ -140,6 +176,16 @@ class SqlBuilder extends Component } + /** + * @param $table + * @return string + */ + public function columns($table): string + { + return 'SHOW FULL FIELDS FROM ' . $table; + } + + /** * @param bool $hasOrder * @return string @@ -148,6 +194,12 @@ class SqlBuilder extends Component private function _prefix($hasOrder = false): string { $select = $this->builderSelect($this->query->select) . ' FROM ' . $this->tableName(); + if (!empty($this->query->alias)) { + $select .= $this->builderAlias($this->query->alias); + } + if (!empty($this->query->join)) { + $select .= $this->builderJoin($this->query->join); + } if (!empty($condition = $this->conditionToString())) { $select = sprintf('%s%s', $select, $condition); } @@ -157,7 +209,21 @@ class SqlBuilder extends Component if ($hasOrder === true && !empty($this->query->order)) { $select .= $this->builderOrder($this->query->order); } - return $select; + return $select . $this->builderLimit($this->query); + } + + + /** + * @param false $isCount + * @return string + * @throws Exception + */ + public function get($isCount = false): string + { + if ($isCount === false) { + return $this->all(); + } + return $this->count(); } diff --git a/Database/Traits/QueryTrait.php b/Database/Traits/QueryTrait.php index c8e42c57..92d6b863 100644 --- a/Database/Traits/QueryTrait.php +++ b/Database/Traits/QueryTrait.php @@ -13,7 +13,6 @@ namespace Database\Traits; use Database\ActiveQuery; use Database\ActiveRecord; use Database\Condition\MathematicsCondition; -use Database\Orm\Select; use Exception; /**