From 4352b8744b4a20804693cbddf149e886e5164a2b Mon Sep 17 00:00:00 2001 From: Anton Grabovsky Date: Mon, 10 Jul 2023 18:07:10 +0300 Subject: [PATCH] Fix #19884: Added support Enums in Query Builder --- framework/CHANGELOG.md | 1 + framework/db/Command.php | 15 +++++++++++---- tests/framework/db/CommandTest.php | 19 +++++++++++++++++++ tests/framework/db/enums/Status.php | 9 +++++++++ tests/framework/db/enums/StatusTypeInt.php | 9 +++++++++ tests/framework/db/enums/StatusTypeString.php | 9 +++++++++ 6 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 tests/framework/db/enums/Status.php create mode 100644 tests/framework/db/enums/StatusTypeInt.php create mode 100644 tests/framework/db/enums/StatusTypeString.php diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 1ee688217fd..894b1ad2a5d 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -9,6 +9,7 @@ Yii Framework 2 Change Log - Enh #19841: Allow jQuery 3.7 to be installed (wouter90) - Enh #19853: Added support for default value for `\yii\helpers\Console::select()` (rhertogh) - Bug #19868: Added whitespace sanitation for tests, due to updates in ICU 72 (schmunk42) +- Enh #19884: Added support Enums in Query Builder (sk1t0n) 2.0.48.1 May 24, 2023 diff --git a/framework/db/Command.php b/framework/db/Command.php index 0856c88ce17..72eda72e4e1 100644 --- a/framework/db/Command.php +++ b/framework/db/Command.php @@ -377,6 +377,13 @@ public function bindValues($values) $this->pendingParams[$name] = [$value->getValue(), $value->getType()]; $this->params[$name] = $value->getValue(); } else { + if (version_compare(PHP_VERSION, '8.1.0') >= 0) { + if ($value instanceof \BackedEnum) { + $value = $value->value; + } elseif ($value instanceof \UnitEnum) { + $value = $value->name; + } + } $type = $schema->getPdoType($value); $this->pendingParams[$name] = [$value, $type]; $this->params[$name] = $value; @@ -631,15 +638,15 @@ public function delete($table, $condition = '', $params = []) * * The columns in the new table should be specified as name-definition pairs (e.g. 'name' => 'string'), * where name stands for a column name which will be properly quoted by the method, and definition - * stands for the column type which must contain an abstract DB type. - * + * stands for the column type which must contain an abstract DB type. + * * The method [[QueryBuilder::getColumnType()]] will be called * to convert the abstract column types to physical ones. For example, `string` will be converted * as `varchar(255)`, and `string not null` becomes `varchar(255) not null`. * * If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly * inserted into the generated SQL. - * + * * Example usage: * ```php * Yii::$app->db->createCommand()->createTable('post', [ @@ -647,7 +654,7 @@ public function delete($table, $condition = '', $params = []) * 'title' => 'string', * 'text' => 'text', * 'column_name double precision null default null', - * ]); + * ]); * ``` * * @param string $table the name of the table to be created. The name will be properly quoted by the method. diff --git a/tests/framework/db/CommandTest.php b/tests/framework/db/CommandTest.php index 15ac5f4160f..041b788f3c1 100644 --- a/tests/framework/db/CommandTest.php +++ b/tests/framework/db/CommandTest.php @@ -1525,4 +1525,23 @@ public function testBindValuesSupportsDeprecatedPDOCastingFormat() $db->createCommand()->setSql("SELECT :p1")->bindValues([':p1' => [2, \PDO::PARAM_STR]]); $this->assertTrue(true); } + + public function testBindValuesSupportsEnums() + { + if (version_compare(PHP_VERSION, '8.1.0') >= 0) { + $db = $this->getConnection(); + $command = $db->createCommand(); + + $command->setSql('SELECT :p1')->bindValues([':p1' => enums\Status::ACTIVE]); + $this->assertSame('ACTIVE', $command->params[':p1']); + + $command->setSql('SELECT :p1')->bindValues([':p1' => enums\StatusTypeString::ACTIVE]); + $this->assertSame('active', $command->params[':p1']); + + $command->setSql('SELECT :p1')->bindValues([':p1' => enums\StatusTypeInt::ACTIVE]); + $this->assertSame(1, $command->params[':p1']); + } else { + $this->markTestSkipped('Enums are not supported in PHP < 8.1'); + } + } } diff --git a/tests/framework/db/enums/Status.php b/tests/framework/db/enums/Status.php new file mode 100644 index 00000000000..799a552319b --- /dev/null +++ b/tests/framework/db/enums/Status.php @@ -0,0 +1,9 @@ +