From 36b4100ee8a1f193d5c7d1b69c3ba9cc57c8a47a Mon Sep 17 00:00:00 2001 From: Adam Rusinowski Date: Fri, 4 Aug 2023 18:09:39 +0200 Subject: [PATCH 1/8] initial update to CakePHP 5.0, updated tests --- README.md | 8 ++-- composer.json | 16 +++++-- phpunit.xml.dist | 42 +++++++---------- src/Model/Behavior/InsertBehavior.php | 47 ++++++++++--------- src/Model/Behavior/UpsertBehavior.php | 26 +++++----- tests/Fixture/ArticlesFixture.php | 13 +---- tests/Fixture/TagsFixture.php | 13 +---- .../Model/Behavior/InsertBehaviorTest.php | 21 ++++----- .../Model/Behavior/UpsertBehaviorTest.php | 36 +++++++------- tests/bootstrap.php | 24 ++++++---- tests/schema.php | 33 +++++++++++++ 11 files changed, 146 insertions(+), 133 deletions(-) create mode 100644 tests/schema.php diff --git a/README.md b/README.md index b576a78..7fe6409 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,9 @@ CakePHP behavior plugin for easily generating some complicated queries like (bul [![License](https://poser.pugx.org/itosho/easy-query/license)](https://packagist.org/packages/itosho/easy-query) ## Requirements -- PHP 7.2+ -- CakePHP 4.0+ -- MySQL 5.6+ - -:warning: For CakePHP3.x, use 1.x branch. +- PHP 8.1+ +- CakePHP 5.0+ +- MySQL 8.0+ / MariaDB 10.4+ ## Installation ```bash diff --git a/composer.json b/composer.json index bce050e..233fa74 100644 --- a/composer.json +++ b/composer.json @@ -26,13 +26,16 @@ "source": "https://github.com/itosho/easy-query" }, "require": { - "php": ">=7.2.0", - "cakephp/orm": "^4.0" + "php": ">=8.1", + "cakephp/orm": "5.x-dev" }, "require-dev": { - "cakephp/cakephp": "^4.0", - "phpunit/phpunit": "^8.5" + "cakephp/cakephp": "5.x-dev", + "phpunit/phpunit": "^10.1.0", + "cakephp/cakephp-codesniffer": "^5.0" }, + "minimum-stability": "dev", + "prefer-stable": true, "autoload": { "psr-4": { "Itosho\\EasyQuery\\": "src" @@ -42,5 +45,10 @@ "psr-4": { "Itosho\\EasyQuery\\Test\\": "tests" } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 878585e..2c4f895 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,37 +1,27 @@ - + + + + + + + - - ./tests/TestCase + tests/TestCase/ - - - - - - - - - - - - - ./src/ - - - + + + + + + src/ + + diff --git a/src/Model/Behavior/InsertBehavior.php b/src/Model/Behavior/InsertBehavior.php index 5d1c050..b8419d3 100644 --- a/src/Model/Behavior/InsertBehavior.php +++ b/src/Model/Behavior/InsertBehavior.php @@ -5,11 +5,11 @@ use Cake\Database\Expression\QueryExpression; use Cake\Database\StatementInterface; -use Cake\I18n\FrozenTime; +use Cake\Datasource\EntityInterface; +use Cake\I18n\DateTime; use Cake\ORM\Behavior; -use Cake\ORM\Entity; -use Cake\ORM\Query; -use Cake\ORM\TableRegistry; +use Cake\ORM\Locator\LocatorAwareTrait; +use Cake\ORM\Query\SelectQuery; use LogicException; /** @@ -17,21 +17,22 @@ */ class InsertBehavior extends Behavior { + use LocatorAwareTrait; /** * Default config * * @var array */ - protected $_defaultConfig = [ + protected array $_defaultConfig = [ 'event' => ['beforeSave' => true], ]; /** * execute bulk insert query * - * @param Entity[] $entities insert entities - * @throws LogicException no save data - * @return StatementInterface query result + * @param \Cake\Datasource\EntityInterface[] $entities insert entities + * @throws \LogicException no save data + * @return \Cake\Database\StatementInterface query result */ public function bulkInsert(array $entities): StatementInterface { @@ -50,7 +51,7 @@ public function bulkInsert(array $entities): StatementInterface $fields = array_keys($saveData[0]); $query = $this->_table - ->query() + ->insertQuery() ->insert($fields); $query->clause('values')->setValues($saveData); @@ -60,11 +61,11 @@ public function bulkInsert(array $entities): StatementInterface /** * execute insert select query for saving a record just once * - * @param Entity $entity insert entity + * @param \Cake\Datasource\EntityInterface $entity insert entity * @param array|null $conditions search conditions - * @return StatementInterface query result + * @return \Cake\Database\StatementInterface query result */ - public function insertOnce(Entity $entity, array $conditions = null): StatementInterface + public function insertOnce(EntityInterface $entity, array $conditions = null): StatementInterface { if ($this->_config['event']['beforeSave']) { $this->_table->dispatchEvent('Model.beforeSave', compact('entity')); @@ -72,11 +73,11 @@ public function insertOnce(Entity $entity, array $conditions = null): StatementI $entity->setVirtual([]); $insertData = $entity->toArray(); - if (isset($insertData['created']) && !is_null($insertData['created'])) { - $insertData['created'] = FrozenTime::now()->toDateTimeString(); + if (isset($insertData['created'])) { + $insertData['created'] = DateTime::now()->toDateTimeString(); } - if (isset($insertData['modified']) && !is_null($insertData['modified'])) { - $insertData['modified'] = FrozenTime::now()->toDateTimeString(); + if (isset($insertData['modified'])) { + $insertData['modified'] = DateTime::now()->toDateTimeString(); } $fields = array_keys($insertData); @@ -84,7 +85,7 @@ public function insertOnce(Entity $entity, array $conditions = null): StatementI if (is_null($existsConditions)) { $existsConditions = $this->getExistsConditions($insertData); } - $query = $this->_table->query()->insert($fields); + $query = $this->_table->insertQuery()->insert($fields); $subQuery = $this ->buildTmpTableSelectQuery($insertData) ->where(function (QueryExpression $exp) use ($existsConditions) { @@ -105,10 +106,10 @@ public function insertOnce(Entity $entity, array $conditions = null): StatementI * build tmp table's select query for insert select query * * @param array $insertData insert data - * @throws LogicException select query is invalid - * @return Query tmp table's select query + * @return \Cake\ORM\Query\SelectQuery tmp table's select query + * @throws \LogicException select query is invalid */ - private function buildTmpTableSelectQuery($insertData): Query + private function buildTmpTableSelectQuery(array $insertData): SelectQuery { $driver = $this->_table ->getConnection() @@ -118,15 +119,15 @@ private function buildTmpTableSelectQuery($insertData): Query foreach ($insertData as $key => $value) { $col = $driver->quoteIdentifier($key); if (is_null($value)) { - $schema[] = "NULL AS {$col}"; + $schema[] = "NULL AS $col"; } else { $bindKey = ':' . strtolower($key); $binds[$bindKey] = $value; - $schema[] = "{$bindKey} AS {$col}"; + $schema[] = "$bindKey AS $col"; } } - $tmpTable = TableRegistry::getTableLocator()->get('tmp', [ + $tmpTable = $this->fetchTable('tmp', [ 'schema' => $this->_table->getSchema(), ]); $query = $tmpTable diff --git a/src/Model/Behavior/UpsertBehavior.php b/src/Model/Behavior/UpsertBehavior.php index 374f7e0..7116844 100644 --- a/src/Model/Behavior/UpsertBehavior.php +++ b/src/Model/Behavior/UpsertBehavior.php @@ -6,7 +6,6 @@ use Cake\Database\StatementInterface; use Cake\Datasource\EntityInterface; use Cake\ORM\Behavior; -use Cake\ORM\Entity; use LogicException; /** @@ -19,7 +18,7 @@ class UpsertBehavior extends Behavior * * @var array */ - protected $_defaultConfig = [ + protected array $_defaultConfig = [ 'updateColumns' => null, 'uniqueColumns' => null, 'event' => ['beforeSave' => true], @@ -28,11 +27,11 @@ class UpsertBehavior extends Behavior /** * execute upsert query * - * @param Entity $entity upsert entity - * @return EntityInterface|array|null result entity - * @throws LogicException invalid config + * @param \Cake\Datasource\EntityInterface $entity upsert entity + * @return \Cake\Datasource\EntityInterface|array|null result entity + * @throws \LogicException invalid config */ - public function upsert(Entity $entity) + public function upsert(EntityInterface $entity): array|EntityInterface|null { if (!$this->isValidArrayConfig('updateColumns')) { throw new LogicException('config updateColumns is invalid.'); @@ -52,13 +51,13 @@ public function upsert(Entity $entity) $updateValues = []; foreach ($updateColumns as $column) { - $updateValues[] = "`{$column}`=VALUES(`{$column}`)"; + $updateValues[] = "`$column`=VALUES(`$column`)"; } $updateStatement = implode(', ', $updateValues); $expression = 'ON DUPLICATE KEY UPDATE ' . $updateStatement; $this->_table - ->query() + ->insertQuery() ->insert($fields) ->values($upsertData) ->epilog($expression) @@ -80,9 +79,9 @@ public function upsert(Entity $entity) /** * execute bulk upsert query * - * @param Entity[] $entities upsert entities - * @return StatementInterface query result - * @throws LogicException invalid config or no save data + * @param \Cake\Datasource\EntityInterface[] $entities upsert entities + * @return \Cake\Database\StatementInterface query result + * @throws \LogicException invalid config or no save data */ public function bulkUpsert(array $entities): StatementInterface { @@ -107,13 +106,12 @@ public function bulkUpsert(array $entities): StatementInterface $updateColumns = $this->_config['updateColumns']; $updateValues = []; foreach ($updateColumns as $column) { - $updateValues[] = "`{$column}`=VALUES(`{$column}`)"; + $updateValues[] = "`$column`=VALUES(`$column`)"; } $updateStatement = implode(', ', $updateValues); $expression = 'ON DUPLICATE KEY UPDATE ' . $updateStatement; - $query = $this->_table - ->query() + ->insertQuery() ->insert($fields) ->epilog($expression); $query->clause('values')->setValues($saveData); diff --git a/tests/Fixture/ArticlesFixture.php b/tests/Fixture/ArticlesFixture.php index 55a5835..ba6710b 100644 --- a/tests/Fixture/ArticlesFixture.php +++ b/tests/Fixture/ArticlesFixture.php @@ -7,18 +7,7 @@ class ArticlesFixture extends TestFixture { - public $fields = [ - 'id' => ['type' => 'integer'], - 'title' => ['type' => 'string', 'length' => 255, 'null' => false], - 'body' => 'text', - 'published' => ['type' => 'integer', 'default' => '0', 'null' => false], - 'created' => 'datetime', - 'modified' => 'datetime', - '_constraints' => [ - 'primary' => ['type' => 'primary', 'columns' => ['id']], - ], - ]; - public $records = [ + public array $records = [ [ 'title' => 'First Article', 'body' => 'First Article Body', diff --git a/tests/Fixture/TagsFixture.php b/tests/Fixture/TagsFixture.php index 4d11962..a9d4250 100644 --- a/tests/Fixture/TagsFixture.php +++ b/tests/Fixture/TagsFixture.php @@ -7,18 +7,7 @@ class TagsFixture extends TestFixture { - public $fields = [ - 'id' => ['type' => 'integer'], - 'name' => ['type' => 'string', 'length' => 255, 'null' => false], - 'description' => ['type' => 'string', 'length' => 255, 'null' => false], - 'created' => 'datetime', - 'modified' => 'datetime', - '_constraints' => [ - 'primary' => ['type' => 'primary', 'columns' => ['id']], - 'unique' => ['type' => 'unique', 'columns' => ['name']], - ], - ]; - public $records = [ + public array $records = [ [ 'name' => 'tag1', 'description' => 'tag1 description', diff --git a/tests/TestCase/Model/Behavior/InsertBehaviorTest.php b/tests/TestCase/Model/Behavior/InsertBehaviorTest.php index 30ed2d9..76f50ab 100644 --- a/tests/TestCase/Model/Behavior/InsertBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/InsertBehaviorTest.php @@ -3,11 +3,10 @@ namespace Itosho\EasyQuery\Test\TestCase\Model\Behavior; -use Cake\Chronos\Chronos; -use Cake\I18n\FrozenTime; +use Cake\I18n\DateTime; use Cake\ORM\Table; -use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; +use LogicException; /** * Itosho\EasyQuery\Model\Behavior\InsertBehavior Test Case @@ -19,13 +18,13 @@ class InsertBehaviorTest extends TestCase * * @var Table */ - public $Articles; + public Table $Articles; /** * Fixtures * * @var array */ - public $fixtures = ['plugin.Itosho/EasyQuery.Articles']; + public array $fixtures = ['plugin.Itosho/EasyQuery.Articles']; /** * {@inheritDoc} @@ -33,7 +32,7 @@ class InsertBehaviorTest extends TestCase public function setUp(): void { parent::setUp(); - $this->Articles = TableRegistry::getTableLocator()->get('Itosho/EasyQuery.Articles'); + $this->Articles = $this->getTableLocator()->get('Itosho/EasyQuery.Articles'); $this->Articles->addBehavior('Itosho/EasyQuery.Insert'); } @@ -43,7 +42,7 @@ public function setUp(): void public function tearDown(): void { parent::tearDown(); - TableRegistry::getTableLocator()->clear(); + $this->getTableLocator()->clear(); unset($this->Articles); } @@ -55,7 +54,7 @@ public function tearDown(): void public function testBulkInsert() { $records = $this->getBaseInsertRecords(); - $now = Chronos::now(); + $now = DateTime::now(); foreach ($records as $key => $val) { $record[$key]['created'] = $now; $record[$key]['modified'] = $now; @@ -85,7 +84,7 @@ public function testBulkInsertAddTimestamp() $records[0]['modified'] = $customNow; $expectedRecords = $this->getBaseInsertRecords(); - $now = Chronos::now(); + $now = DateTime::now(); foreach ($expectedRecords as $key => $val) { $expectedRecords[$key]['created'] = $now; $expectedRecords[$key]['modified'] = $now; @@ -146,7 +145,7 @@ public function testBulkInsertNoBeforeSave() public function testBulkInsertNoSaveData() { $this->expectExceptionMessage("entities has no save data."); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $this->Articles->bulkInsert([]); } @@ -190,7 +189,7 @@ public function testInsertOnceAddTimestampBehavior() 'published' => 1, ]; $entity = $this->Articles->newEntity($newData); - $now = FrozenTime::now(); + $now = DateTime::now(); $this->Articles->insertOnce($entity); diff --git a/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php b/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php index 4a5cbb8..d2634d8 100644 --- a/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php @@ -3,10 +3,10 @@ namespace Itosho\EasyQuery\Test\TestCase\Model\Behavior; -use Cake\Chronos\Chronos; +use Cake\I18n\DateTime; use Cake\ORM\Table; -use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; +use LogicException; /** * Itosho\EasyQuery\Model\Behavior\UpsertBehavior Test Case @@ -18,13 +18,13 @@ class UpsertBehaviorTest extends TestCase * * @var Table */ - public $Tags; + public Table $Tags; /** * Fixtures * * @var array */ - public $fixtures = ['plugin.Itosho/EasyQuery.Tags']; + public array $fixtures = ['plugin.Itosho/EasyQuery.Tags']; /** * {@inheritDoc} @@ -32,7 +32,7 @@ class UpsertBehaviorTest extends TestCase public function setUp(): void { parent::setUp(); - $this->Tags = TableRegistry::getTableLocator()->get('Itosho/EasyQuery.Tags'); + $this->Tags = $this->getTableLocator()->get('Itosho/EasyQuery.Tags'); $this->Tags->addBehavior('Itosho/EasyQuery.Upsert', [ 'uniqueColumns' => ['name'], 'updateColumns' => ['description', 'modified'], @@ -45,7 +45,7 @@ public function setUp(): void public function tearDown(): void { parent::tearDown(); - TableRegistry::getTableLocator()->clear(); + $this->getTableLocator()->clear(); unset($this->Tags); } @@ -56,7 +56,7 @@ public function tearDown(): void */ public function testUpsertByInsert() { - $now = Chronos::now(); + $now = DateTime::now(); $record = [ 'name' => 'tag4', 'description' => 'tag4 description', @@ -97,7 +97,7 @@ public function testUpsertByInsertAddTimestamp() 'name' => 'tag4', 'description' => 'tag4 description', ]; - $now = Chronos::now(); + $now = DateTime::now(); $expectedRecord = $record; $expectedRecord['created'] = $now; $expectedRecord['modified'] = $now; @@ -172,7 +172,7 @@ public function testUpsertByUpdateAddTimestamp() 'name' => 'tag1', 'description' => 'brand new tag1 description', ]; - $now = Chronos::now(); + $now = DateTime::now(); $currentCreated = '2017-09-01 00:00:00'; $expectedRecord = $record; $expectedRecord['created'] = $currentCreated; @@ -243,7 +243,7 @@ public function testUpsertNoBeforeSave() public function testUpsertInvalidUpdateColumnsConfig() { $this->expectExceptionMessage("config updateColumns is invalid."); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $this->Tags->removeBehavior('Upsert'); $this->Tags->addBehavior('Itosho/EasyQuery.Upsert', [ @@ -268,7 +268,7 @@ public function testUpsertInvalidUpdateColumnsConfig() public function testUpsertInvalidUniqueColumnsConfig() { $this->expectExceptionMessage("config uniqueColumns is invalid."); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $this->Tags->removeBehavior('Upsert'); $this->Tags->addBehavior('Itosho/EasyQuery.Upsert', [ @@ -298,7 +298,7 @@ public function testBulkUpsertByInsert() ]); $records = $this->getBaseInsertRecords(); - $now = Chronos::now(); + $now = DateTime::now(); foreach ($records as $key => $val) { $records[$key]['created'] = $now; $records[$key]['modified'] = $now; @@ -327,7 +327,7 @@ public function testBulkUpsertByInsertAddTimestamp() $this->Tags->addBehavior('Timestamp'); $records = $this->getBaseInsertRecords(); - $now = Chronos::now(); + $now = DateTime::now(); $expectedRecords = $records; foreach ($expectedRecords as $key => $val) { $expectedRecords[$key]['created'] = $now; @@ -356,7 +356,7 @@ public function testBulkUpsertByUpdate() ]); $records = $this->getBaseUpdateRecords(); - $now = Chronos::now(); + $now = DateTime::now(); foreach ($records as $key => $val) { $records[$key]['created'] = $now; $records[$key]['modified'] = $now; @@ -387,7 +387,7 @@ public function testBulkUpsertByUpdateAddTimestamp() $this->Tags->addBehavior('Timestamp'); $records = $this->getBaseUpdateRecords(); - $now = Chronos::now(); + $now = DateTime::now(); $currentCreated = '2017-09-01 00:00:00'; $expectedRecords = $records; foreach ($expectedRecords as $key => $val) { @@ -442,13 +442,13 @@ public function testBulkUpsertNoBeforeSave() public function testBulkUpsertInvalidUpdateColumnsConfig() { $this->expectExceptionMessage("config updateColumns is invalid."); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $this->Tags->removeBehavior('Upsert'); $this->Tags->addBehavior('Itosho/EasyQuery.Upsert'); $records = $this->getBaseInsertRecords(); - $now = Chronos::now(); + $now = DateTime::now(); foreach ($records as $key => $val) { $records[$key]['created'] = $now; $records[$key]['modified'] = $now; @@ -466,7 +466,7 @@ public function testBulkUpsertInvalidUpdateColumnsConfig() public function testBulkUpsertNoSaveData() { $this->expectExceptionMessage("entities has no save data."); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $this->Tags->removeBehavior('Upsert'); $this->Tags->addBehavior('Itosho/EasyQuery.Upsert', [ diff --git a/tests/bootstrap.php b/tests/bootstrap.php index e2b0179..7dfe091 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,18 +1,20 @@ Connection::class, 'driver' => Mysql::class, 'host' => getenv('db_host'), 'username' => getenv('db_user'), 'database' => getenv('db_name'), + 'password' => getenv('db_pass'), ]; ConnectionManager::drop('test'); ConnectionManager::setConfig('test', $dbConfig); + +// Create test database schema +if (env('FIXTURE_SCHEMA_METADATA')) { + $loader = new SchemaLoader(); + $loader->loadInternalFile(env('FIXTURE_SCHEMA_METADATA')); +} \ No newline at end of file diff --git a/tests/schema.php b/tests/schema.php new file mode 100644 index 0000000..c4d65d5 --- /dev/null +++ b/tests/schema.php @@ -0,0 +1,33 @@ + 'articles', + 'columns' => [ + 'id' => ['type' => 'integer'], + 'title' => ['type' => 'string', 'length' => 255, 'null' => false], + 'body' => 'text', + 'published' => ['type' => 'integer', 'default' => '0', 'null' => false], + 'created' => 'datetime', + 'modified' => 'datetime', + ], + 'constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id']], + ], + ], + [ + 'table' => 'tags', + 'columns' => [ + 'id' => ['type' => 'integer'], + 'name' => ['type' => 'string', 'length' => 255, 'null' => false], + 'description' => ['type' => 'string', 'length' => 255, 'null' => false], + 'created' => 'datetime', + 'modified' => 'datetime', + ], + 'constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id']], + 'unique' => ['type' => 'unique', 'columns' => ['name']], + ], + ], +]; From dc391165c38116c73c246fb8df982d8ddb67b674 Mon Sep 17 00:00:00 2001 From: Adam Rusinowski Date: Mon, 25 Sep 2023 10:50:02 +0200 Subject: [PATCH 2/8] updated composer.json to use stable CakePHP5, cc --- .github/workflows/ci.yml | 22 +++++++++++++++++++ .phive/phars.xml | 5 +++++ composer.json | 9 ++++---- phpcs.xml | 5 +++++ phpstan.neon | 7 ++++-- psalm.xml | 15 +++++++++++++ src/Model/Behavior/InsertBehavior.php | 7 +++--- src/Model/Behavior/UpsertBehavior.php | 5 ++--- .../Model/Behavior/InsertBehaviorTest.php | 6 ++--- .../Model/Behavior/UpsertBehaviorTest.php | 12 +++++----- tests/bootstrap.php | 3 ++- 11 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .phive/phars.xml create mode 100644 phpcs.xml create mode 100644 psalm.xml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..758f712 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,22 @@ +name: CI + +on: + push: + branches: + - master + - cake5 + pull_request: + branches: + - '*' + +permissions: + contents: read + +jobs: + testsuite: + uses: cakephp/.github/.github/workflows/testsuite-with-db.yml@5.x + secrets: inherit + + cs-stan: + uses: cakephp/.github/.github/workflows/cs-stan.yml@5.x + secrets: inherit diff --git a/.phive/phars.xml b/.phive/phars.xml new file mode 100644 index 0000000..9aa6dfe --- /dev/null +++ b/.phive/phars.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/composer.json b/composer.json index 233fa74..bcfd135 100644 --- a/composer.json +++ b/composer.json @@ -27,15 +27,14 @@ }, "require": { "php": ">=8.1", - "cakephp/orm": "5.x-dev" + "cakephp/orm": "^5.0.0" }, "require-dev": { - "cakephp/cakephp": "5.x-dev", + "cakephp/cakephp": "^5.0.0", "phpunit/phpunit": "^10.1.0", - "cakephp/cakephp-codesniffer": "^5.0" + "cakephp/cakephp-codesniffer": "^5.0", + "vimeo/psalm": "^5.15" }, - "minimum-stability": "dev", - "prefer-stable": true, "autoload": { "psr-4": { "Itosho\\EasyQuery\\": "src" diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..0737a91 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/phpstan.neon b/phpstan.neon index ca05326..fd868ae 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,6 @@ parameters: - checkMissingIterableValueType: false - ignoreErrors: [] + level: 6 + checkGenericClassInNonGenericObjectType: false + checkMissingIterableValueType: false + paths: + - src/ diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..08f635d --- /dev/null +++ b/psalm.xml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/Model/Behavior/InsertBehavior.php b/src/Model/Behavior/InsertBehavior.php index b8419d3..72e73e7 100644 --- a/src/Model/Behavior/InsertBehavior.php +++ b/src/Model/Behavior/InsertBehavior.php @@ -18,10 +18,11 @@ class InsertBehavior extends Behavior { use LocatorAwareTrait; + /** * Default config * - * @var array + * @var array */ protected array $_defaultConfig = [ 'event' => ['beforeSave' => true], @@ -30,7 +31,7 @@ class InsertBehavior extends Behavior /** * execute bulk insert query * - * @param \Cake\Datasource\EntityInterface[] $entities insert entities + * @param array<\Cake\Datasource\EntityInterface> $entities insert entities * @throws \LogicException no save data * @return \Cake\Database\StatementInterface query result */ @@ -65,7 +66,7 @@ public function bulkInsert(array $entities): StatementInterface * @param array|null $conditions search conditions * @return \Cake\Database\StatementInterface query result */ - public function insertOnce(EntityInterface $entity, array $conditions = null): StatementInterface + public function insertOnce(EntityInterface $entity, ?array $conditions = null): StatementInterface { if ($this->_config['event']['beforeSave']) { $this->_table->dispatchEvent('Model.beforeSave', compact('entity')); diff --git a/src/Model/Behavior/UpsertBehavior.php b/src/Model/Behavior/UpsertBehavior.php index 7116844..33d6f78 100644 --- a/src/Model/Behavior/UpsertBehavior.php +++ b/src/Model/Behavior/UpsertBehavior.php @@ -16,7 +16,7 @@ class UpsertBehavior extends Behavior /** * Default config * - * @var array + * @var array */ protected array $_defaultConfig = [ 'updateColumns' => null, @@ -79,7 +79,7 @@ public function upsert(EntityInterface $entity): array|EntityInterface|null /** * execute bulk upsert query * - * @param \Cake\Datasource\EntityInterface[] $entities upsert entities + * @param array<\Cake\Datasource\EntityInterface> $entities upsert entities * @return \Cake\Database\StatementInterface query result * @throws \LogicException invalid config or no save data */ @@ -123,7 +123,6 @@ public function bulkUpsert(array $entities): StatementInterface * validate config value * * @param string $configName config key - * * @return bool valid or invalid */ private function isValidArrayConfig(string $configName): bool diff --git a/tests/TestCase/Model/Behavior/InsertBehaviorTest.php b/tests/TestCase/Model/Behavior/InsertBehaviorTest.php index 76f50ab..e634eb1 100644 --- a/tests/TestCase/Model/Behavior/InsertBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/InsertBehaviorTest.php @@ -27,7 +27,7 @@ class InsertBehaviorTest extends TestCase public array $fixtures = ['plugin.Itosho/EasyQuery.Articles']; /** - * {@inheritDoc} + * @inheritDoc */ public function setUp(): void { @@ -37,7 +37,7 @@ public function setUp(): void } /** - * {@inheritDoc} + * @inheritDoc */ public function tearDown(): void { @@ -144,7 +144,7 @@ public function testBulkInsertNoBeforeSave() */ public function testBulkInsertNoSaveData() { - $this->expectExceptionMessage("entities has no save data."); + $this->expectExceptionMessage('entities has no save data.'); $this->expectException(LogicException::class); $this->Articles->bulkInsert([]); diff --git a/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php b/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php index d2634d8..3a6ffdb 100644 --- a/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php @@ -27,7 +27,7 @@ class UpsertBehaviorTest extends TestCase public array $fixtures = ['plugin.Itosho/EasyQuery.Tags']; /** - * {@inheritDoc} + * @inheritDoc */ public function setUp(): void { @@ -40,7 +40,7 @@ public function setUp(): void } /** - * {@inheritDoc} + * @inheritDoc */ public function tearDown(): void { @@ -242,7 +242,7 @@ public function testUpsertNoBeforeSave() */ public function testUpsertInvalidUpdateColumnsConfig() { - $this->expectExceptionMessage("config updateColumns is invalid."); + $this->expectExceptionMessage('config updateColumns is invalid.'); $this->expectException(LogicException::class); $this->Tags->removeBehavior('Upsert'); @@ -267,7 +267,7 @@ public function testUpsertInvalidUpdateColumnsConfig() */ public function testUpsertInvalidUniqueColumnsConfig() { - $this->expectExceptionMessage("config uniqueColumns is invalid."); + $this->expectExceptionMessage('config uniqueColumns is invalid.'); $this->expectException(LogicException::class); $this->Tags->removeBehavior('Upsert'); @@ -441,7 +441,7 @@ public function testBulkUpsertNoBeforeSave() */ public function testBulkUpsertInvalidUpdateColumnsConfig() { - $this->expectExceptionMessage("config updateColumns is invalid."); + $this->expectExceptionMessage('config updateColumns is invalid.'); $this->expectException(LogicException::class); $this->Tags->removeBehavior('Upsert'); @@ -465,7 +465,7 @@ public function testBulkUpsertInvalidUpdateColumnsConfig() */ public function testBulkUpsertNoSaveData() { - $this->expectExceptionMessage("entities has no save data."); + $this->expectExceptionMessage('entities has no save data.'); $this->expectException(LogicException::class); $this->Tags->removeBehavior('Upsert'); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 7dfe091..14be93e 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -13,6 +13,7 @@ * This function is used to find the location of CakePHP whether CakePHP * has been installed as a dependency of the plugin, or the plugin is itself * installed as a dependency of an application. + * * @throws \Exception */ $findRoot = function ($root) { @@ -52,4 +53,4 @@ if (env('FIXTURE_SCHEMA_METADATA')) { $loader = new SchemaLoader(); $loader->loadInternalFile(env('FIXTURE_SCHEMA_METADATA')); -} \ No newline at end of file +} From b9a676f004d7ca752f6beef76d25e55f78b1871e Mon Sep 17 00:00:00 2001 From: Adam Rusinowski Date: Mon, 25 Sep 2023 10:56:05 +0200 Subject: [PATCH 3/8] updated git workflow --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 758f712..bb9de13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: branches: - master - - cake5 + - 3.next pull_request: branches: - '*' From f52e00effa671b645aa9e645696f833a4eed06f3 Mon Sep 17 00:00:00 2001 From: Adam Rusinowski Date: Mon, 25 Sep 2023 11:03:52 +0200 Subject: [PATCH 4/8] removed unneded phpstan override --- phpstan-baseline.neon | 2 ++ phpstan.neon | 3 +++ src/Model/Behavior/InsertBehavior.php | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 phpstan-baseline.neon diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..f51e71c --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,2 @@ +parameters: + ignoreErrors: [] diff --git a/phpstan.neon b/phpstan.neon index fd868ae..f1af199 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,6 @@ +includes: + - phpstan-baseline.neon + parameters: level: 6 checkGenericClassInNonGenericObjectType: false diff --git a/src/Model/Behavior/InsertBehavior.php b/src/Model/Behavior/InsertBehavior.php index 72e73e7..883e77f 100644 --- a/src/Model/Behavior/InsertBehavior.php +++ b/src/Model/Behavior/InsertBehavior.php @@ -97,7 +97,7 @@ public function insertOnce(EntityInterface $entity, ?array $conditions = null): return $exp->notExists($query); }) ->limit(1); - /* @phpstan-ignore-next-line */ + $query = $query->epilog($subQuery); return $query->execute(); From 0a5566bb813a7df10c5a901a38af5035db456b07 Mon Sep 17 00:00:00 2001 From: Adam Rusinowski Date: Mon, 25 Sep 2023 11:13:54 +0200 Subject: [PATCH 5/8] updated test config --- phpunit.xml.dist | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 2c4f895..eeba8b5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,10 +5,10 @@ - - - - + + + + From 8318e6e600e009b561b709f15677a2e35b130adc Mon Sep 17 00:00:00 2001 From: Adam Rusinowski Date: Mon, 25 Sep 2023 11:24:28 +0200 Subject: [PATCH 6/8] updated test config --- phpunit.xml.dist | 4 ---- tests/bootstrap.php | 9 +-------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index eeba8b5..7acf8f8 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,10 +5,6 @@ - - - - diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 14be93e..66d427f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,8 +1,6 @@ Connection::class, - 'driver' => Mysql::class, - 'host' => getenv('db_host'), - 'username' => getenv('db_user'), - 'database' => getenv('db_name'), - 'password' => getenv('db_pass'), + 'url' => env('DB_URL'), ]; ConnectionManager::drop('test'); ConnectionManager::setConfig('test', $dbConfig); From 21ab46bf89fd34beb5cad27cce1de4e2b271e8c4 Mon Sep 17 00:00:00 2001 From: Adam Rusinowski Date: Mon, 25 Sep 2023 11:38:51 +0200 Subject: [PATCH 7/8] updated test config --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb9de13..b162abf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,9 @@ jobs: testsuite: uses: cakephp/.github/.github/workflows/testsuite-with-db.yml@5.x secrets: inherit + strategy: + matrix: + db-type: [mysql] cs-stan: uses: cakephp/.github/.github/workflows/cs-stan.yml@5.x From e3f30eaa9c6b2e3dd357f7727409646c146ffadb Mon Sep 17 00:00:00 2001 From: Adam Rusinowski Date: Mon, 25 Sep 2023 11:41:03 +0200 Subject: [PATCH 8/8] updated test config --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b162abf..bb9de13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,9 +16,6 @@ jobs: testsuite: uses: cakephp/.github/.github/workflows/testsuite-with-db.yml@5.x secrets: inherit - strategy: - matrix: - db-type: [mysql] cs-stan: uses: cakephp/.github/.github/workflows/cs-stan.yml@5.x