From 103d6fc0071dbb8cc35abe2183ad37d5af290d93 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 2 Sep 2021 17:50:16 +0200 Subject: [PATCH 01/33] update composer.json --- composer.json | 54 +++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/composer.json b/composer.json index 806f08f..adbf87d 100644 --- a/composer.json +++ b/composer.json @@ -1,26 +1,10 @@ { "name": "digicomp/sequence", - "type": "neos-package", "description": "Sequence is a very simple database agnostic but database based sequence generator", - "keywords": [ - "flow", - "neos", - "doctrine", - "sequence" - ], - "authors": [ - { - "name": "Ferdinand Kuhl", - "email": "f.kuhl@digital-competence.de", - "homepage": "http://www.digital-competence.de", - "role": "Developer" - } - ], - "license": "MIT", - "homepage": "https://github.com/digicomp/DigiComp.Sequence", + "type": "neos-package", "require": { - "neos/flow": "~5.3 | ^6.3.5", - "php": "^7.4" + "neos/flow": "^5.3.0 || ^6.3.5", + "php": "~7.4.0" }, "require-dev": { "phpunit/phpunit": "3.7.*", @@ -28,14 +12,22 @@ }, "autoload": { "psr-4": { - "DigiComp\\Sequence\\": "Classes" + "DigiComp\\Sequence\\": "Classes/" + } + }, + "autoload-dev": { + "psr-4": { + "DigiComp\\Sequence\\Tests\\": "Tests/" } }, "extra": { + "neos": { + "package-key": "DigiComp.Sequence" + }, "branch-alias": { - "dev-version/1.x-dev": "1.1.x-dev", + "dev-develop": "3.0.x-dev", "dev-version/2.x-dev": "2.1.x-dev", - "dev-develop": "3.0.x-dev" + "dev-version/1.x-dev": "1.1.x-dev" }, "applied-flow-migrations": [ "Inwebs.Basket-201409170938", @@ -71,5 +63,21 @@ "DigiComp.SettingValidator-20170603120900", "Neos.Flow-20180415105700" ] - } + }, + "authors": [ + { + "name": "Ferdinand Kuhl", + "email": "f.kuhl@digital-competence.de", + "homepage": "https://www.digital-competence.de", + "role": "Developer" + } + ], + "license": "MIT", + "homepage": "https://github.com/digital-competence/DigiComp.Sequence", + "keywords": [ + "Neos", + "Flow", + "doctrine", + "sequence" + ] } From 24135e09827ba86651f05d6e955fd5ed6d682a2a Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Fri, 3 Sep 2021 10:15:46 +0200 Subject: [PATCH 02/33] update composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index adbf87d..b77183f 100644 --- a/composer.json +++ b/composer.json @@ -7,8 +7,8 @@ "php": "~7.4.0" }, "require-dev": { - "phpunit/phpunit": "3.7.*", - "ext-pcntl": "*" + "ext-pcntl": "*", + "phpunit/phpunit": "3.7.*" }, "autoload": { "psr-4": { From 258a75478890644dbfaac14af5b6c6faa7ee2b95 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Wed, 8 Sep 2021 16:42:05 +0200 Subject: [PATCH 03/33] update migrations --- Migrations/Mysql/Version20140505093853.php | 32 ++++++++-------------- Migrations/Mysql/Version20160624203903.php | 32 ++++++++-------------- 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/Migrations/Mysql/Version20140505093853.php b/Migrations/Mysql/Version20140505093853.php index 05b424e..d1aa1a3 100644 --- a/Migrations/Mysql/Version20140505093853.php +++ b/Migrations/Mysql/Version20140505093853.php @@ -2,43 +2,33 @@ namespace Neos\Flow\Persistence\Doctrine\Migrations; -use Doctrine\DBAL\Migrations\AbstractMigration; +use Doctrine\DBAL\Exception as DoctrineDBALException; +use Doctrine\DBAL\Migrations\AbortMigrationException; use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; -/** - * Auto-generated Migration: Please modify to your needs! This block will be used as the migration description if getDescription() is not used. - */ class Version20140505093853 extends AbstractMigration { - - /** - * @return string - */ - public function getDescription() - { - return ''; - } - /** * @param Schema $schema - * @return void + * @throws AbortMigrationException + * @throws DoctrineDBALException */ - public function up(Schema $schema) + public function up(Schema $schema): void { - // this up() migration is autogenerated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on "mysql".'); + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); $this->addSql('CREATE TABLE digicomp_sequence_domain_model_insert (number INT NOT NULL, type VARCHAR(255) NOT NULL, PRIMARY KEY(number, type))'); } /** * @param Schema $schema - * @return void + * @throws AbortMigrationException + * @throws DoctrineDBALException */ - public function down(Schema $schema) + public function down(Schema $schema): void { - // this down() migration is autogenerated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on "mysql".'); + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); $this->addSql('DROP TABLE digicomp_sequence_domain_model_insert'); } diff --git a/Migrations/Mysql/Version20160624203903.php b/Migrations/Mysql/Version20160624203903.php index 0d9ad16..96dcabd 100644 --- a/Migrations/Mysql/Version20160624203903.php +++ b/Migrations/Mysql/Version20160624203903.php @@ -2,43 +2,33 @@ namespace Neos\Flow\Persistence\Doctrine\Migrations; -use Doctrine\DBAL\Migrations\AbstractMigration; +use Doctrine\DBAL\Exception as DoctrineDBALException; +use Doctrine\DBAL\Migrations\AbortMigrationException; use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; -/** - * Auto-generated Migration: Please modify to your needs! This block will be used as the migration description if getDescription() is not used. - */ class Version20160624203903 extends AbstractMigration { - - /** - * @return string - */ - public function getDescription() - { - return ''; - } - /** * @param Schema $schema - * @return void + * @throws AbortMigrationException + * @throws DoctrineDBALException */ - public function up(Schema $schema) + public function up(Schema $schema): void { - // this up() migration is autogenerated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on "mysql".'); + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); $this->addSql('CREATE INDEX type_idx ON digicomp_sequence_domain_model_insert (type)'); } /** * @param Schema $schema - * @return void + * @throws AbortMigrationException + * @throws DoctrineDBALException */ - public function down(Schema $schema) + public function down(Schema $schema): void { - // this down() migration is autogenerated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on "mysql".'); + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); $this->addSql('DROP INDEX type_idx ON digicomp_sequence_domain_model_insert'); } From d5f8b671d5fd2eee8f9f2eb9fbbbb66054b941a8 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Fri, 10 Sep 2021 12:09:20 +0200 Subject: [PATCH 04/33] added CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..461f64f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] +Start of the changelog. From 83839a1582e6a6c8f03e95ad5ac2d4469423e284 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Fri, 10 Sep 2021 12:37:11 +0200 Subject: [PATCH 05/33] optimized README.md --- README.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a446bd4..36ea7c5 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,20 @@ -DigiComp.Sequence -------------------------- +# DigiComp.Sequence - -This is a very simple and stupid tool, helping in generation of gapless sequences. For this task it relies on key -integrity of the database of your choice. +This is a very simple tool, helping in generation of gapless sequences. For this task it relies on key integrity of the +database of your choice. Usage is quite simple also: +```php +/** + * @param SequenceNumberGenerator $sequenceNumberGenerator + */ +public function __construct(SequenceNumberGenerator $sequenceNumberGenerator) +{ + $this->orderId = $sequenceNumberGenerator->getNextNumberFor($this); +} +``` - /** - * @param \DigiComp\Sequence\Service\SequenceNumberGenerator $sequenceNumberGenerator - */ - public function __construct(SequenceNumberGenerator $sequenceNumberGenerator) - { - $this->orderId = $sequenceNumberGenerator->getNextNumberFor($this); - } +`getNextNumberFor` allows you to give an object (which will be resolved to its FQCN) or a custom sequence name. -``getNextNumberFor`` allows you to give an object which will be resolved to its FQCN or a custom sequence name. - -The CommandController helps you to advance the current sequence number, in case of migrations or similar. - -See ``./flow help sequence:advance`` if interested. +The `SequenceCommandController` helps you to advance the current sequence number, in case of migrations or similar. See +`./flow help sequence:advance` if interested. From fcebb743448f9b416506b1551e90b5b43f2fa341 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Fri, 10 Sep 2021 12:39:26 +0200 Subject: [PATCH 06/33] remove .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 90ec22b..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.svn From 7767091426812336b5c4b214365c48857b7d82e3 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 16 Sep 2021 15:00:42 +0200 Subject: [PATCH 07/33] fixed indentation --- Classes/Service/SequenceGenerator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/Service/SequenceGenerator.php b/Classes/Service/SequenceGenerator.php index 715e6ab..9a38752 100644 --- a/Classes/Service/SequenceGenerator.php +++ b/Classes/Service/SequenceGenerator.php @@ -106,8 +106,8 @@ class SequenceGenerator { return (int) $this->entityManager->getConnection()->executeQuery( 'SELECT MAX(number) FROM ' - . $this->entityManager->getClassMetadata(Insert::class)->getTableName() - . ' WHERE type = :type', + . $this->entityManager->getClassMetadata(Insert::class)->getTableName() + . ' WHERE type = :type', ['type' => $this->inferTypeFromSource($type)] )->fetchAll(\PDO::FETCH_COLUMN)[0]; } From 8da32c3969606a8544b63e5724b5ac89e13097c8 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 16 Sep 2021 15:30:22 +0200 Subject: [PATCH 08/33] run phpcbf --- Classes/Command/SequenceCommandController.php | 2 +- Classes/Service/SequenceGenerator.php | 8 ++++---- Tests/Functional/SequenceTest.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/Command/SequenceCommandController.php b/Classes/Command/SequenceCommandController.php index d57b4fc..dddc981 100644 --- a/Classes/Command/SequenceCommandController.php +++ b/Classes/Command/SequenceCommandController.php @@ -51,7 +51,7 @@ class SequenceCommandController extends CommandController ->createQuery('SELECT i.type, MAX(i.number) max_number FROM ' . Insert::class . ' i GROUP BY i.type') ->getScalarResult(); foreach ($results as $result) { - $cleanArray[$result['type']] = (int) $result['max_number']; + $cleanArray[$result['type']] = (int)$result['max_number']; } } else { foreach ($typesToClean as $typeToClean) { diff --git a/Classes/Service/SequenceGenerator.php b/Classes/Service/SequenceGenerator.php index 9a38752..2a808ce 100644 --- a/Classes/Service/SequenceGenerator.php +++ b/Classes/Service/SequenceGenerator.php @@ -49,7 +49,7 @@ class SequenceGenerator // TODO: Let increment be configurable per type do { $count++; - } while (! $this->validateFreeNumber($count, $type)); + } while (!$this->validateFreeNumber($count, $type)); return $count; } @@ -71,7 +71,7 @@ class SequenceGenerator } catch (\PDOException $e) { return false; } catch (DBALException $e) { - if (! $e->getPrevious() instanceof \PDOException) { + if (!$e->getPrevious() instanceof \PDOException) { $this->systemLogger->critical('Exception occured: ' . $e->getMessage()); } } catch (\Exception $e) { @@ -104,7 +104,7 @@ class SequenceGenerator */ public function getLastNumberFor($type): int { - return (int) $this->entityManager->getConnection()->executeQuery( + return (int)$this->entityManager->getConnection()->executeQuery( 'SELECT MAX(number) FROM ' . $this->entityManager->getClassMetadata(Insert::class)->getTableName() . ' WHERE type = :type', @@ -122,7 +122,7 @@ class SequenceGenerator if (\is_object($stringOrObject)) { $stringOrObject = TypeHandling::getTypeForValue($stringOrObject); } - if (! $stringOrObject) { + if (!$stringOrObject) { throw new Exception('No Type given'); } diff --git a/Tests/Functional/SequenceTest.php b/Tests/Functional/SequenceTest.php index a4ec07a..7913837 100644 --- a/Tests/Functional/SequenceTest.php +++ b/Tests/Functional/SequenceTest.php @@ -25,7 +25,7 @@ class SequenceTest extends FunctionalTestCase $pIds = []; for ($i = 0; $i < 10; $i++) { - $pId = pcntl_fork(); + $pId = \pcntl_fork(); if ($pId) { $pIds[] = $pId; } else { @@ -39,7 +39,7 @@ class SequenceTest extends FunctionalTestCase foreach ($pIds as $pId) { $status = 0; - pcntl_waitpid($pId, $status); + \pcntl_waitpid($pId, $status); } $this->assertEquals(101, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); From 41646401829352920c6e77df42c69112db4aee3f Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 16 Sep 2021 16:34:00 +0200 Subject: [PATCH 09/33] replace empty function --- Classes/Command/SequenceCommandController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Command/SequenceCommandController.php b/Classes/Command/SequenceCommandController.php index dddc981..ce884f8 100644 --- a/Classes/Command/SequenceCommandController.php +++ b/Classes/Command/SequenceCommandController.php @@ -46,7 +46,7 @@ class SequenceCommandController extends CommandController public function cleanSequenceInsertsCommand(array $typesToClean = []) { $cleanArray = []; - if (empty($typesToClean)) { + if ($typesToClean === []) { $results = $this->entityManager ->createQuery('SELECT i.type, MAX(i.number) max_number FROM ' . Insert::class . ' i GROUP BY i.type') ->getScalarResult(); From aab466ac17ea968611221bc67d977d761624f791 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Fri, 17 Sep 2021 11:22:44 +0200 Subject: [PATCH 10/33] renamed $systemLogger to $logger --- Classes/Service/SequenceGenerator.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/Service/SequenceGenerator.php b/Classes/Service/SequenceGenerator.php index 2a808ce..d0e462b 100644 --- a/Classes/Service/SequenceGenerator.php +++ b/Classes/Service/SequenceGenerator.php @@ -31,7 +31,7 @@ class SequenceGenerator * @Flow\Inject * @var LoggerInterface */ - protected $systemLogger; + protected $logger; /** * @param string|object $type @@ -72,10 +72,10 @@ class SequenceGenerator return false; } catch (DBALException $e) { if (!$e->getPrevious() instanceof \PDOException) { - $this->systemLogger->critical('Exception occured: ' . $e->getMessage()); + $this->logger->critical('Exception occured: ' . $e->getMessage()); } } catch (\Exception $e) { - $this->systemLogger->critical('Exception occured: ' . $e->getMessage()); + $this->logger->critical('Exception occured: ' . $e->getMessage()); } return false; From 2b15d25ebe1a9323a2e4542da1ecff80ac0360e8 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Mon, 20 Sep 2021 18:12:51 +0200 Subject: [PATCH 11/33] optimized use statements --- Classes/Service/SequenceGenerator.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Classes/Service/SequenceGenerator.php b/Classes/Service/SequenceGenerator.php index d0e462b..d9a3399 100644 --- a/Classes/Service/SequenceGenerator.php +++ b/Classes/Service/SequenceGenerator.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace DigiComp\Sequence\Service; use DigiComp\Sequence\Domain\Model\Insert; -use Doctrine\DBAL\Exception as DBALException; +use Doctrine\DBAL\Exception as DoctrineDBALException; use Doctrine\ORM\EntityManagerInterface; use Neos\Flow\Annotations as Flow; use Neos\Utility\TypeHandling; @@ -35,10 +35,9 @@ class SequenceGenerator /** * @param string|object $type - * * @return int * @throws Exception - * @throws DBALException + * @throws DoctrineDBALException */ public function getNextNumberFor($type): int { @@ -70,7 +69,7 @@ class SequenceGenerator return true; } catch (\PDOException $e) { return false; - } catch (DBALException $e) { + } catch (DoctrineDBALException $e) { if (!$e->getPrevious() instanceof \PDOException) { $this->logger->critical('Exception occured: ' . $e->getMessage()); } @@ -97,10 +96,9 @@ class SequenceGenerator /** * @param string|object $type - * * @return int * @throws Exception - * @throws DBALException + * @throws DoctrineDBALException */ public function getLastNumberFor($type): int { From 722111191fb7d30de7de199b2583afb6edcab997 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Tue, 21 Sep 2021 10:39:03 +0200 Subject: [PATCH 12/33] fixes with code inspection --- Classes/Command/SequenceCommandController.php | 7 +++++++ Classes/Service/SequenceGenerator.php | 9 ++++++--- Tests/Functional/SequenceTest.php | 11 ++++++++++- composer.json | 1 + 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Classes/Command/SequenceCommandController.php b/Classes/Command/SequenceCommandController.php index ce884f8..cf9dc7e 100644 --- a/Classes/Command/SequenceCommandController.php +++ b/Classes/Command/SequenceCommandController.php @@ -5,7 +5,10 @@ declare(strict_types=1); namespace DigiComp\Sequence\Command; use DigiComp\Sequence\Domain\Model\Insert; +use DigiComp\Sequence\Service\Exception as DigiCompSequenceServiceException; use DigiComp\Sequence\Service\SequenceGenerator; +use Doctrine\DBAL\Driver\Exception as DoctrineDBALDriverException; +use Doctrine\DBAL\Exception as DoctrineDBALException; use Doctrine\ORM\EntityManagerInterface; use Neos\Flow\Annotations as Flow; use Neos\Flow\Cli\CommandController; @@ -34,6 +37,7 @@ class SequenceCommandController extends CommandController * * @param int $to * @param string $type + * @throws DigiCompSequenceServiceException */ public function advanceCommand(int $to, string $type): void { @@ -42,6 +46,9 @@ class SequenceCommandController extends CommandController /** * @param string[] $typesToClean + * @throws DigiCompSequenceServiceException + * @throws DoctrineDBALDriverException + * @throws DoctrineDBALException */ public function cleanSequenceInsertsCommand(array $typesToClean = []) { diff --git a/Classes/Service/SequenceGenerator.php b/Classes/Service/SequenceGenerator.php index d9a3399..7c7b744 100644 --- a/Classes/Service/SequenceGenerator.php +++ b/Classes/Service/SequenceGenerator.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace DigiComp\Sequence\Service; use DigiComp\Sequence\Domain\Model\Insert; +use Doctrine\DBAL\Driver\Exception as DoctrineDBALDriverException; use Doctrine\DBAL\Exception as DoctrineDBALException; use Doctrine\ORM\EntityManagerInterface; use Neos\Flow\Annotations as Flow; @@ -37,6 +38,7 @@ class SequenceGenerator * @param string|object $type * @return int * @throws Exception + * @throws DoctrineDBALDriverException * @throws DoctrineDBALException */ public function getNextNumberFor($type): int @@ -71,10 +73,10 @@ class SequenceGenerator return false; } catch (DoctrineDBALException $e) { if (!$e->getPrevious() instanceof \PDOException) { - $this->logger->critical('Exception occured: ' . $e->getMessage()); + $this->logger->critical('Exception occurred: ' . $e->getMessage()); } } catch (\Exception $e) { - $this->logger->critical('Exception occured: ' . $e->getMessage()); + $this->logger->critical('Exception occurred: ' . $e->getMessage()); } return false; @@ -98,6 +100,7 @@ class SequenceGenerator * @param string|object $type * @return int * @throws Exception + * @throws DoctrineDBALDriverException * @throws DoctrineDBALException */ public function getLastNumberFor($type): int @@ -107,7 +110,7 @@ class SequenceGenerator . $this->entityManager->getClassMetadata(Insert::class)->getTableName() . ' WHERE type = :type', ['type' => $this->inferTypeFromSource($type)] - )->fetchAll(\PDO::FETCH_COLUMN)[0]; + )->fetchOne(); } /** diff --git a/Tests/Functional/SequenceTest.php b/Tests/Functional/SequenceTest.php index 7913837..b400c34 100644 --- a/Tests/Functional/SequenceTest.php +++ b/Tests/Functional/SequenceTest.php @@ -2,18 +2,24 @@ namespace DigiComp\Sequence\Tests\Functional; +use DigiComp\Sequence\Service\Exception as DigiCompSequenceServiceException; use DigiComp\Sequence\Service\SequenceGenerator; +use Doctrine\DBAL\Driver\Exception as DoctrineDBALDriverException; +use Doctrine\DBAL\Exception as DoctrineDBALException; use Neos\Flow\Tests\FunctionalTestCase; class SequenceTest extends FunctionalTestCase { /** - * @var bool + * @inheritDoc */ protected static $testablePersistenceEnabled = true; /** * @test + * @throws DigiCompSequenceServiceException + * @throws DoctrineDBALDriverException + * @throws DoctrineDBALException */ public function sequenceTest() { @@ -47,6 +53,9 @@ class SequenceTest extends FunctionalTestCase /** * @test + * @throws DigiCompSequenceServiceException + * @throws DoctrineDBALDriverException + * @throws DoctrineDBALException */ public function advanceTest() { diff --git a/composer.json b/composer.json index b77183f..cace62e 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "description": "Sequence is a very simple database agnostic but database based sequence generator", "type": "neos-package", "require": { + "ext-pdo": "*", "neos/flow": "^5.3.0 || ^6.3.5", "php": "~7.4.0" }, From ced940247c5c55bfed1147222bc0bad3f17ccab9 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Wed, 22 Sep 2021 11:34:34 +0200 Subject: [PATCH 13/33] revised code --- Classes/Command/SequenceCommandController.php | 63 ++++++----- .../Model/{Insert.php => SequenceEntry.php} | 54 +++------- Classes/Exception.php | 11 ++ Classes/Service/Exception.php | 12 --- .../Exception/InvalidSourceException.php | 11 ++ Classes/Service/SequenceGenerator.php | 100 ++++++++++-------- Configuration/Testing/Settings.yaml | 4 +- Migrations/Mysql/Version20210922110814.php | 39 +++++++ README.md | 4 +- Tests/Functional/SequenceTest.php | 20 ++-- 10 files changed, 182 insertions(+), 136 deletions(-) rename Classes/Domain/Model/{Insert.php => SequenceEntry.php} (50%) create mode 100644 Classes/Exception.php delete mode 100644 Classes/Service/Exception.php create mode 100644 Classes/Service/Exception/InvalidSourceException.php create mode 100644 Migrations/Mysql/Version20210922110814.php diff --git a/Classes/Command/SequenceCommandController.php b/Classes/Command/SequenceCommandController.php index cf9dc7e..881d3c1 100644 --- a/Classes/Command/SequenceCommandController.php +++ b/Classes/Command/SequenceCommandController.php @@ -4,8 +4,8 @@ declare(strict_types=1); namespace DigiComp\Sequence\Command; -use DigiComp\Sequence\Domain\Model\Insert; -use DigiComp\Sequence\Service\Exception as DigiCompSequenceServiceException; +use DigiComp\Sequence\Domain\Model\SequenceEntry; +use DigiComp\Sequence\Service\Exception\InvalidSourceException; use DigiComp\Sequence\Service\SequenceGenerator; use Doctrine\DBAL\Driver\Exception as DoctrineDBALDriverException; use Doctrine\DBAL\Exception as DoctrineDBALException; @@ -14,8 +14,6 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Cli\CommandController; /** - * A database agnostic SequenceNumber generator - * * @Flow\Scope("singleton") */ class SequenceCommandController extends CommandController @@ -33,42 +31,53 @@ class SequenceCommandController extends CommandController protected $entityManager; /** - * Sets minimum number for sequence generator + * Set last number for sequence generator. * - * @param int $to * @param string $type - * @throws DigiCompSequenceServiceException + * @param int $number + * @throws DoctrineDBALDriverException + * @throws DoctrineDBALException + * @throws InvalidSourceException */ - public function advanceCommand(int $to, string $type): void + public function setLastNumberForCommand(string $type, int $number): void { - $this->sequenceGenerator->advanceTo($to, $type); + if ($this->sequenceGenerator->setLastNumberFor($type, $number)) { + $this->outputLine('Last number successfully set.'); + } else { + $this->outputLine('Failed to set last number.'); + } } /** - * @param string[] $typesToClean - * @throws DigiCompSequenceServiceException + * Clean up sequence table. + * + * @param string[] $types * @throws DoctrineDBALDriverException * @throws DoctrineDBALException + * @throws InvalidSourceException */ - public function cleanSequenceInsertsCommand(array $typesToClean = []) + public function cleanUpCommand(array $types = []): void { - $cleanArray = []; - if ($typesToClean === []) { - $results = $this->entityManager - ->createQuery('SELECT i.type, MAX(i.number) max_number FROM ' . Insert::class . ' i GROUP BY i.type') - ->getScalarResult(); - foreach ($results as $result) { - $cleanArray[$result['type']] = (int)$result['max_number']; - } - } else { - foreach ($typesToClean as $typeToClean) { - $cleanArray[$typeToClean] = $this->sequenceGenerator->getLastNumberFor($typeToClean); + if ($types === []) { + foreach ( + $this + ->entityManager + ->createQuery('SELECT DISTINCT(se.type) type FROM ' . SequenceEntry::class . ' se') + ->execute() + as $result + ) { + $types[] = $result['type']; } } - foreach ($cleanArray as $typeToClean => $number) { - $this->entityManager - ->createQuery('DELETE FROM ' . Insert::class . ' i WHERE i.type = ?0 AND i.number < ?1') - ->execute([$typeToClean, $number]); + + foreach ($types as $type) { + $rowCount = $this + ->entityManager + ->createQuery('DELETE FROM ' . SequenceEntry::class . ' se WHERE se.type = ?0 AND se.number < ?1') + ->execute([$type, $this->sequenceGenerator->getLastNumberFor($type)]); + + + $this->outputLine('Deleted ' . $rowCount . ' row(s) for type "' . $type . '".'); } } } diff --git a/Classes/Domain/Model/Insert.php b/Classes/Domain/Model/SequenceEntry.php similarity index 50% rename from Classes/Domain/Model/Insert.php rename to Classes/Domain/Model/SequenceEntry.php index 97b0cb8..d010331 100644 --- a/Classes/Domain/Model/Insert.php +++ b/Classes/Domain/Model/SequenceEntry.php @@ -8,52 +8,35 @@ use Doctrine\ORM\Mapping as ORM; use Neos\Flow\Annotations as Flow; /** - * SequenceInsert - * * @Flow\Entity - * @ORM\Table(indexes={ - * @ORM\Index(name="type_idx", columns={"type"}) - * }) + * @ORM\Table( + * indexes={ + * @ORM\Index(columns={"type"}) + * }, + * uniqueConstraints={ + * @ORM\UniqueConstraint(columns={"type", "number"}) + * } + * ) */ -class Insert +class SequenceEntry { /** - * @Flow\Identity - * @ORM\Id - * @var int - */ - protected int $number; - - /** - * @Flow\Identity - * @ORM\Id * @var string */ protected string $type; /** - * @param int $number - * @param string|object $type + * @var int */ - public function __construct(int $number, $type) - { - $this->setNumber($number); - $this->setType($type); - } - - /** - * @return int - */ - public function getNumber(): int - { - return $this->number; - } + protected int $number; /** + * @param string $type * @param int $number */ - public function setNumber(int $number): void + public function __construct(string $type, int $number) { + $this->type = $type; $this->number = $number; } @@ -66,13 +49,10 @@ class Insert } /** - * @param string|object $type + * @return int */ - public function setType($type): void + public function getNumber(): int { - if (\is_object($type)) { - $type = \get_class($type); - } - $this->type = $type; + return $this->number; } } diff --git a/Classes/Exception.php b/Classes/Exception.php new file mode 100644 index 0000000..383db6f --- /dev/null +++ b/Classes/Exception.php @@ -0,0 +1,11 @@ + 1 we could return new keys immediately for this * request, as we "reserved" the space between. @@ -35,98 +37,102 @@ class SequenceGenerator protected $logger; /** - * @param string|object $type + * @param string|object $source * @return int - * @throws Exception * @throws DoctrineDBALDriverException * @throws DoctrineDBALException + * @throws InvalidSourceException */ - public function getNextNumberFor($type): int + public function getNextNumberFor($source): int { - $type = $this->inferTypeFromSource($type); - $count = $this->getLastNumberFor($type); + $type = $this->inferTypeFromSource($source); + $number = $this->getLastNumberFor($type); - // TODO: Check for maximal tries, or similar - // TODO: Let increment be configurable per type + // TODO: Check for maximal tries, or similar? + // TODO: Let increment be configurable per type? do { - $count++; - } while (!$this->validateFreeNumber($count, $type)); + $number++; + } while (!$this->insertFor($type, $number)); - return $count; + return $number; } /** - * @param int $count * @param string $type + * @param int $number * @return bool */ - protected function validateFreeNumber(int $count, string $type): bool + protected function insertFor(string $type, int $number): bool { - $em = $this->entityManager; try { - $em->getConnection()->insert( - $em->getClassMetadata(Insert::class)->getTableName(), - ['number' => $count, 'type' => $type] + $this->entityManager->getConnection()->insert( + $this->entityManager->getClassMetadata(SequenceEntry::class)->getTableName(), + ['persistence_object_identifier' => Algorithms::generateUUID(), 'number' => $number, 'type' => $type] ); + return true; - } catch (\PDOException $e) { - return false; - } catch (DoctrineDBALException $e) { - if (!$e->getPrevious() instanceof \PDOException) { - $this->logger->critical('Exception occurred: ' . $e->getMessage()); + } catch (\PDOException $exception) { + } catch (DoctrineDBALException $exception) { + if (!$exception->getPrevious() instanceof \PDOException) { + $this->logger->critical('Exception occurred: ' . $exception->getMessage()); } - } catch (\Exception $e) { - $this->logger->critical('Exception occurred: ' . $e->getMessage()); + } catch (\Exception $exception) { + $this->logger->critical('Exception occurred: ' . $exception->getMessage()); } return false; } /** - * @param int $to - * @param string|object $type - * + * @param string|object $source + * @param int $number * @return bool - * @throws Exception + * @throws DoctrineDBALDriverException + * @throws DoctrineDBALException + * @throws InvalidSourceException */ - public function advanceTo(int $to, $type): bool + public function setLastNumberFor($source, int $number): bool { - $type = $this->inferTypeFromSource($type); + $type = $this->inferTypeFromSource($source); - return $this->validateFreeNumber($to, $type); + if ($this->getLastNumberFor($type) >= $number) { + return false; + } + + return $this->insertFor($type, $number); } /** - * @param string|object $type - * @return int - * @throws Exception + * @param string|object $source * @throws DoctrineDBALDriverException * @throws DoctrineDBALException + * @throws InvalidSourceException */ - public function getLastNumberFor($type): int + public function getLastNumberFor($source): int { return (int)$this->entityManager->getConnection()->executeQuery( 'SELECT MAX(number) FROM ' - . $this->entityManager->getClassMetadata(Insert::class)->getTableName() + . $this->entityManager->getClassMetadata(SequenceEntry::class)->getTableName() . ' WHERE type = :type', - ['type' => $this->inferTypeFromSource($type)] + ['type' => $this->inferTypeFromSource($source)] )->fetchOne(); } /** - * @param string|object $stringOrObject + * @param string|object $source * @return string - * @throws Exception + * @throws InvalidSourceException */ - protected function inferTypeFromSource($stringOrObject): string + protected function inferTypeFromSource($source): string { - if (\is_object($stringOrObject)) { - $stringOrObject = TypeHandling::getTypeForValue($stringOrObject); - } - if (!$stringOrObject) { - throw new Exception('No Type given'); + if (\is_string($source)) { + return $source; } - return $stringOrObject; + if (\is_object($source)) { + return TypeHandling::getTypeForValue($source); + } + + throw new InvalidSourceException('Could not infer type from source.', 1632216173); } } diff --git a/Configuration/Testing/Settings.yaml b/Configuration/Testing/Settings.yaml index 54d2680..5d0dfb7 100644 --- a/Configuration/Testing/Settings.yaml +++ b/Configuration/Testing/Settings.yaml @@ -2,5 +2,5 @@ Neos: Flow: persistence: backendOptions: - driver: 'pdo_sqlite' - path: '%FLOW_PATH_DATA%/Temporary/testing.db' + driver: "pdo_sqlite" + path: "%FLOW_PATH_DATA%/Temporary/testing.db" diff --git a/Migrations/Mysql/Version20210922110814.php b/Migrations/Mysql/Version20210922110814.php new file mode 100644 index 0000000..e74c465 --- /dev/null +++ b/Migrations/Mysql/Version20210922110814.php @@ -0,0 +1,39 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); + + $this->addSql('CREATE TABLE digicomp_sequence_domain_model_sequenceentry (persistence_object_identifier VARCHAR(40) NOT NULL, type VARCHAR(255) NOT NULL, number INT NOT NULL, INDEX IDX_F6ADC8568CDE5729 (type), UNIQUE INDEX UNIQ_F6ADC8568CDE572996901F54 (type, number), PRIMARY KEY(persistence_object_identifier))'); + $this->addSql('INSERT INTO digicomp_sequence_domain_model_sequenceentry (persistence_object_identifier, type, number) SELECT UUID(), i.type, i.number FROM digicomp_sequence_domain_model_insert AS i'); + $this->addSql('DROP TABLE digicomp_sequence_domain_model_insert'); + } + + /** + * @param Schema $schema + * @throws AbortMigrationException + * @throws DoctrineDBALException + */ + public function down(Schema $schema): void + { + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); + + $this->addSql('CREATE TABLE digicomp_sequence_domain_model_insert (number INT NOT NULL, type VARCHAR(255) NOT NULL, INDEX type_idx (type), PRIMARY KEY(number, type))'); + $this->addSql('INSERT INTO digicomp_sequence_domain_model_insert (number, type) SELECT se.number, se.type FROM digicomp_sequence_domain_model_sequenceentry AS se'); + $this->addSql('DROP TABLE digicomp_sequence_domain_model_sequenceentry'); + } +} diff --git a/README.md b/README.md index 36ea7c5..e796736 100644 --- a/README.md +++ b/README.md @@ -16,5 +16,5 @@ public function __construct(SequenceNumberGenerator $sequenceNumberGenerator) `getNextNumberFor` allows you to give an object (which will be resolved to its FQCN) or a custom sequence name. -The `SequenceCommandController` helps you to advance the current sequence number, in case of migrations or similar. See -`./flow help sequence:advance` if interested. +The `SequenceCommandController` helps you to set the last sequence number, in case of migrations or similar. See +`./flow help sequence:setlastnumberfor` if interested. diff --git a/Tests/Functional/SequenceTest.php b/Tests/Functional/SequenceTest.php index b400c34..4fb3067 100644 --- a/Tests/Functional/SequenceTest.php +++ b/Tests/Functional/SequenceTest.php @@ -1,8 +1,10 @@ objectManager->get(SequenceGenerator::class); - $number = $sequenceGenerator->getLastNumberFor($sequenceGenerator); - $this->assertEquals(0, $number); + $this->assertEquals(0, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); $this->assertEquals(1, $sequenceGenerator->getNextNumberFor($sequenceGenerator)); $pIds = []; for ($i = 0; $i < 10; $i++) { $pId = \pcntl_fork(); - if ($pId) { + if ($pId > 0) { $pIds[] = $pId; } else { for ($j = 0; $j < 10; $j++) { @@ -53,16 +54,17 @@ class SequenceTest extends FunctionalTestCase /** * @test - * @throws DigiCompSequenceServiceException * @throws DoctrineDBALDriverException * @throws DoctrineDBALException + * @throws InvalidSourceException */ - public function advanceTest() + public function setLastNumberForTest() { $sequenceGenerator = $this->objectManager->get(SequenceGenerator::class); - $sequenceGenerator->advanceTo(100, $sequenceGenerator); + $sequenceGenerator->setLastNumberFor($sequenceGenerator, 100); + $this->assertEquals(100, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); - $this->assertEquals(0, $sequenceGenerator->getLastNumberFor('strangeOtherSequence')); + $this->assertEquals(0, $sequenceGenerator->getLastNumberFor('otherSequence')); } } From 19b58b9c267dc297ba24e7ebf9ad8ff8dee7b40e Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Wed, 22 Sep 2021 14:26:09 +0200 Subject: [PATCH 14/33] reformat @ORM\Table --- Classes/Domain/Model/SequenceEntry.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Classes/Domain/Model/SequenceEntry.php b/Classes/Domain/Model/SequenceEntry.php index d010331..ee164a9 100644 --- a/Classes/Domain/Model/SequenceEntry.php +++ b/Classes/Domain/Model/SequenceEntry.php @@ -9,14 +9,11 @@ use Neos\Flow\Annotations as Flow; /** * @Flow\Entity - * @ORM\Table( - * indexes={ - * @ORM\Index(columns={"type"}) - * }, - * uniqueConstraints={ - * @ORM\UniqueConstraint(columns={"type", "number"}) - * } - * ) + * @ORM\Table(indexes={ + * @ORM\Index(columns={"type"}) + * }, uniqueConstraints={ + * @ORM\UniqueConstraint(columns={"type", "number"}) + * }) */ class SequenceEntry { From 71748c0d758e2f9ebfcc2ef14419d38bc0f26cf0 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Wed, 22 Sep 2021 15:00:26 +0200 Subject: [PATCH 15/33] add empty line at end of License.txt --- License.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/License.txt b/License.txt index 2ffa411..ab84d82 100644 --- a/License.txt +++ b/License.txt @@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. From d46c2ca7ffc2c936013a524e3eb532f55b09ae8a Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 23 Sep 2021 08:55:03 +0200 Subject: [PATCH 16/33] add missing return type hints --- Tests/Functional/SequenceTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Functional/SequenceTest.php b/Tests/Functional/SequenceTest.php index 4fb3067..b912129 100644 --- a/Tests/Functional/SequenceTest.php +++ b/Tests/Functional/SequenceTest.php @@ -23,7 +23,7 @@ class SequenceTest extends FunctionalTestCase * @throws DoctrineDBALException * @throws InvalidSourceException */ - public function sequenceTest() + public function sequenceTest(): void { $sequenceGenerator = $this->objectManager->get(SequenceGenerator::class); @@ -58,7 +58,7 @@ class SequenceTest extends FunctionalTestCase * @throws DoctrineDBALException * @throws InvalidSourceException */ - public function setLastNumberForTest() + public function setLastNumberForTest(): void { $sequenceGenerator = $this->objectManager->get(SequenceGenerator::class); From 03672e05c58dd8cf147e1adef8a1e1fe08d5e26c Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 23 Sep 2021 16:14:00 +0200 Subject: [PATCH 17/33] TASK: Apply migration Neos.Flow-20190425144900 Adjusts code to FlashMessageContainer renaming from "\Neos\Flow\Mvc" to "\Neos\Flow\Mvc\FlashMessage". Note: This migration did not produce any changes, so the commit simply marks the migration as applied. This makes sure it will not be applied again. --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index cace62e..9cea398 100644 --- a/composer.json +++ b/composer.json @@ -62,7 +62,8 @@ "Neos.Flow-20170125103800", "Neos.Flow-20170127183102", "DigiComp.SettingValidator-20170603120900", - "Neos.Flow-20180415105700" + "Neos.Flow-20180415105700", + "Neos.Flow-20190425144900" ] }, "authors": [ @@ -81,4 +82,4 @@ "doctrine", "sequence" ] -} +} \ No newline at end of file From a34f5eb20b6cf09f005d5d7397469d8e4314c2bf Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 23 Sep 2021 16:14:01 +0200 Subject: [PATCH 18/33] TASK: Apply migration Neos.Flow-20190515215000 Adjust "Settings.yaml" to new PSR-3 logging settings (see https://github.com/neos/flow-development-collection/pull/1574) Note: This migration did not produce any changes, so the commit simply marks the migration as applied. This makes sure it will not be applied again. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9cea398..1d44ad5 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,8 @@ "Neos.Flow-20170127183102", "DigiComp.SettingValidator-20170603120900", "Neos.Flow-20180415105700", - "Neos.Flow-20190425144900" + "Neos.Flow-20190425144900", + "Neos.Flow-20190515215000" ] }, "authors": [ From 3fc0ddce1fcc6665c7794b201feb46e650751ef1 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 23 Sep 2021 16:52:53 +0200 Subject: [PATCH 19/33] add empty line at end of composer.json (was removed by flow core migrations...) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1d44ad5..d357aac 100644 --- a/composer.json +++ b/composer.json @@ -83,4 +83,4 @@ "doctrine", "sequence" ] -} \ No newline at end of file +} From f324e8c0cafa45f3ed1d3c9cecd7a5b248e99909 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Mon, 11 Oct 2021 12:23:44 +0200 Subject: [PATCH 20/33] remove unnecessary slash after %FLOW_PATH_*% --- Configuration/Testing/Settings.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Configuration/Testing/Settings.yaml b/Configuration/Testing/Settings.yaml index 5d0dfb7..3f9770d 100644 --- a/Configuration/Testing/Settings.yaml +++ b/Configuration/Testing/Settings.yaml @@ -3,4 +3,4 @@ Neos: persistence: backendOptions: driver: "pdo_sqlite" - path: "%FLOW_PATH_DATA%/Temporary/testing.db" + path: "%FLOW_PATH_DATA%Temporary/testing.db" From 586d6036500defcc0c621fbaf979ef984ef9f98b Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 10 Feb 2022 15:57:07 +0100 Subject: [PATCH 21/33] removed duplicated blank line --- Classes/Command/SequenceCommandController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Classes/Command/SequenceCommandController.php b/Classes/Command/SequenceCommandController.php index 881d3c1..1884d44 100644 --- a/Classes/Command/SequenceCommandController.php +++ b/Classes/Command/SequenceCommandController.php @@ -76,7 +76,6 @@ class SequenceCommandController extends CommandController ->createQuery('DELETE FROM ' . SequenceEntry::class . ' se WHERE se.type = ?0 AND se.number < ?1') ->execute([$type, $this->sequenceGenerator->getLastNumberFor($type)]); - $this->outputLine('Deleted ' . $rowCount . ' row(s) for type "' . $type . '".'); } } From 9263cf05969343bc94314850bee3f79886ea39d5 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 10 Feb 2022 15:57:40 +0100 Subject: [PATCH 22/33] optimized line breaks README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e796736..4030886 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ This is a very simple tool, helping in generation of gapless sequences. For this database of your choice. Usage is quite simple also: + ```php /** * @param SequenceNumberGenerator $sequenceNumberGenerator From 24016dd0606d4a90518242664f4528bae68573e6 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Thu, 3 Mar 2022 13:30:53 +0100 Subject: [PATCH 23/33] optimized php requirement --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d357aac..fd31a97 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "require": { "ext-pdo": "*", "neos/flow": "^5.3.0 || ^6.3.5", - "php": "~7.4.0" + "php": ">=7.4" }, "require-dev": { "ext-pcntl": "*", From b0dd57f693b1c7b82a3cd081e8626c623ccd609b Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Mon, 4 Apr 2022 22:41:28 +0200 Subject: [PATCH 24/33] change dependency to neos/flow --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index fd31a97..2d12076 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "neos-package", "require": { "ext-pdo": "*", - "neos/flow": "^5.3.0 || ^6.3.5", + "neos/flow": "^6.3.5", "php": ">=7.4" }, "require-dev": { From 8396fa0db75d86a328709a63ab8e7475e517c758 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Mon, 4 Apr 2022 22:42:58 +0200 Subject: [PATCH 25/33] code style --- Tests/Functional/SequenceTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/Functional/SequenceTest.php b/Tests/Functional/SequenceTest.php index b912129..1a5cd0c 100644 --- a/Tests/Functional/SequenceTest.php +++ b/Tests/Functional/SequenceTest.php @@ -61,7 +61,6 @@ class SequenceTest extends FunctionalTestCase public function setLastNumberForTest(): void { $sequenceGenerator = $this->objectManager->get(SequenceGenerator::class); - $sequenceGenerator->setLastNumberFor($sequenceGenerator, 100); $this->assertEquals(100, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); From e839d216adbe3c9ce1669dcaf361bd32ebe731d4 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Wed, 20 Apr 2022 17:36:31 +0200 Subject: [PATCH 26/33] revised code --- Classes/Domain/Model/SequenceEntry.php | 35 +++------------------- Classes/Service/SequenceGenerator.php | 3 +- Migrations/Mysql/Version20210922110814.php | 6 ++-- Tests/Functional/SequenceTest.php | 10 +++---- composer.json | 2 +- 5 files changed, 14 insertions(+), 42 deletions(-) diff --git a/Classes/Domain/Model/SequenceEntry.php b/Classes/Domain/Model/SequenceEntry.php index ee164a9..ee8c39f 100644 --- a/Classes/Domain/Model/SequenceEntry.php +++ b/Classes/Domain/Model/SequenceEntry.php @@ -8,48 +8,21 @@ use Doctrine\ORM\Mapping as ORM; use Neos\Flow\Annotations as Flow; /** + * This class is only here to set up the table. We never create an instance of this class. + * * @Flow\Entity - * @ORM\Table(indexes={ - * @ORM\Index(columns={"type"}) - * }, uniqueConstraints={ - * @ORM\UniqueConstraint(columns={"type", "number"}) - * }) */ class SequenceEntry { /** + * @ORM\Id * @var string */ protected string $type; /** + * @ORM\Id * @var int */ protected int $number; - - /** - * @param string $type - * @param int $number - */ - public function __construct(string $type, int $number) - { - $this->type = $type; - $this->number = $number; - } - - /** - * @return string - */ - public function getType(): string - { - return $this->type; - } - - /** - * @return int - */ - public function getNumber(): int - { - return $this->number; - } } diff --git a/Classes/Service/SequenceGenerator.php b/Classes/Service/SequenceGenerator.php index 45bbfac..a9ed1c7 100644 --- a/Classes/Service/SequenceGenerator.php +++ b/Classes/Service/SequenceGenerator.php @@ -10,7 +10,6 @@ use Doctrine\DBAL\Driver\Exception as DoctrineDBALDriverException; use Doctrine\DBAL\Exception as DoctrineDBALException; use Doctrine\ORM\EntityManagerInterface; use Neos\Flow\Annotations as Flow; -use Neos\Flow\Utility\Algorithms; use Neos\Utility\TypeHandling; use Psr\Log\LoggerInterface; @@ -67,7 +66,7 @@ class SequenceGenerator try { $this->entityManager->getConnection()->insert( $this->entityManager->getClassMetadata(SequenceEntry::class)->getTableName(), - ['persistence_object_identifier' => Algorithms::generateUUID(), 'number' => $number, 'type' => $type] + ['type' => $type, 'number' => $number] ); return true; diff --git a/Migrations/Mysql/Version20210922110814.php b/Migrations/Mysql/Version20210922110814.php index e74c465..7623464 100644 --- a/Migrations/Mysql/Version20210922110814.php +++ b/Migrations/Mysql/Version20210922110814.php @@ -18,8 +18,8 @@ class Version20210922110814 extends AbstractMigration { $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); - $this->addSql('CREATE TABLE digicomp_sequence_domain_model_sequenceentry (persistence_object_identifier VARCHAR(40) NOT NULL, type VARCHAR(255) NOT NULL, number INT NOT NULL, INDEX IDX_F6ADC8568CDE5729 (type), UNIQUE INDEX UNIQ_F6ADC8568CDE572996901F54 (type, number), PRIMARY KEY(persistence_object_identifier))'); - $this->addSql('INSERT INTO digicomp_sequence_domain_model_sequenceentry (persistence_object_identifier, type, number) SELECT UUID(), i.type, i.number FROM digicomp_sequence_domain_model_insert AS i'); + $this->addSql('CREATE TABLE digicomp_sequence_domain_model_sequenceentry (type VARCHAR(255) NOT NULL, number INT NOT NULL, PRIMARY KEY(type, number))'); + $this->addSql('INSERT INTO digicomp_sequence_domain_model_sequenceentry (type, number) SELECT i.type, MAX(i.number) FROM digicomp_sequence_domain_model_insert AS i GROUP BY i.type'); $this->addSql('DROP TABLE digicomp_sequence_domain_model_insert'); } @@ -33,7 +33,7 @@ class Version20210922110814 extends AbstractMigration $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); $this->addSql('CREATE TABLE digicomp_sequence_domain_model_insert (number INT NOT NULL, type VARCHAR(255) NOT NULL, INDEX type_idx (type), PRIMARY KEY(number, type))'); - $this->addSql('INSERT INTO digicomp_sequence_domain_model_insert (number, type) SELECT se.number, se.type FROM digicomp_sequence_domain_model_sequenceentry AS se'); + $this->addSql('INSERT INTO digicomp_sequence_domain_model_insert (number, type) SELECT MAX(se.number), se.type FROM digicomp_sequence_domain_model_sequenceentry AS se GROUP BY se.type'); $this->addSql('DROP TABLE digicomp_sequence_domain_model_sequenceentry'); } } diff --git a/Tests/Functional/SequenceTest.php b/Tests/Functional/SequenceTest.php index 1a5cd0c..542095e 100644 --- a/Tests/Functional/SequenceTest.php +++ b/Tests/Functional/SequenceTest.php @@ -27,8 +27,8 @@ class SequenceTest extends FunctionalTestCase { $sequenceGenerator = $this->objectManager->get(SequenceGenerator::class); - $this->assertEquals(0, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); - $this->assertEquals(1, $sequenceGenerator->getNextNumberFor($sequenceGenerator)); + self::assertEquals(0, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); + self::assertEquals(1, $sequenceGenerator->getNextNumberFor($sequenceGenerator)); $pIds = []; for ($i = 0; $i < 10; $i++) { @@ -49,7 +49,7 @@ class SequenceTest extends FunctionalTestCase \pcntl_waitpid($pId, $status); } - $this->assertEquals(101, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); + self::assertEquals(101, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); } /** @@ -63,7 +63,7 @@ class SequenceTest extends FunctionalTestCase $sequenceGenerator = $this->objectManager->get(SequenceGenerator::class); $sequenceGenerator->setLastNumberFor($sequenceGenerator, 100); - $this->assertEquals(100, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); - $this->assertEquals(0, $sequenceGenerator->getLastNumberFor('otherSequence')); + self::assertEquals(100, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); + self::assertEquals(0, $sequenceGenerator->getLastNumberFor('otherSequence')); } } diff --git a/composer.json b/composer.json index 2d12076..d955c14 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "~8.5" }, "autoload": { "psr-4": { From ab6ef4ba48dd47110d4803d6260658eb53139ceb Mon Sep 17 00:00:00 2001 From: Ferdinand Kuhl Date: Sat, 30 Apr 2022 21:38:36 +0200 Subject: [PATCH 27/33] RUN phpcbf --- Classes/Command/SequenceCommandController.php | 2 +- Classes/Domain/Model/Insert.php | 8 ++++---- Classes/Service/SequenceGenerator.php | 9 ++++----- Migrations/Mysql/Version20140505093853.php | 1 - Migrations/Mysql/Version20160624203903.php | 1 - Tests/Functional/SequenceTest.php | 4 ++-- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Classes/Command/SequenceCommandController.php b/Classes/Command/SequenceCommandController.php index 076cd53..479120f 100644 --- a/Classes/Command/SequenceCommandController.php +++ b/Classes/Command/SequenceCommandController.php @@ -14,8 +14,8 @@ use Neos\Flow\Cli\CommandController; class SequenceCommandController extends CommandController { /** - * @var SequenceGenerator * @Flow\Inject + * @var SequenceGenerator */ protected $sequenceGenerator; diff --git a/Classes/Domain/Model/Insert.php b/Classes/Domain/Model/Insert.php index 6e95e41..c82e0af 100644 --- a/Classes/Domain/Model/Insert.php +++ b/Classes/Domain/Model/Insert.php @@ -16,16 +16,16 @@ use Neos\Flow\Annotations as Flow; class Insert { /** - * @var int * @Flow\Identity * @ORM\Id + * @var int */ protected $number; /** - * @var string * @Flow\Identity * @ORM\Id + * @var string */ protected $type; @@ -68,8 +68,8 @@ class Insert */ public function setType($type) { - if (is_object($type)) { - $type = get_class($type); + if (\is_object($type)) { + $type = \get_class($type); } $this->type = $type; } diff --git a/Classes/Service/SequenceGenerator.php b/Classes/Service/SequenceGenerator.php index ba8a0ea..9787f51 100644 --- a/Classes/Service/SequenceGenerator.php +++ b/Classes/Service/SequenceGenerator.php @@ -5,7 +5,6 @@ namespace DigiComp\Sequence\Service; use DigiComp\Sequence\Domain\Model\Insert; use Doctrine\Common\Persistence\ObjectManager; use Doctrine\DBAL\DBALException; -use Doctrine\ORM\EntityManager; use Neos\Flow\Annotations as Flow; use Neos\Flow\Log\SystemLoggerInterface; use Neos\Flow\Reflection\ReflectionService; @@ -22,21 +21,21 @@ use Neos\Utility\TypeHandling; class SequenceGenerator { /** - * @var ObjectManager * @Flow\Inject + * @var ObjectManager */ protected $entityManager; /** - * @var ReflectionService * @Flow\Inject * @deprecated + * @var ReflectionService */ protected $reflectionService; /** - * @var SystemLoggerInterface * @Flow\Inject + * @var SystemLoggerInterface */ protected $systemLogger; @@ -120,7 +119,7 @@ class SequenceGenerator */ protected function inferTypeFromSource($stringOrObject) { - if (is_object($stringOrObject)) { + if (\is_object($stringOrObject)) { $stringOrObject = TypeHandling::getTypeForValue($stringOrObject); } if (! $stringOrObject) { diff --git a/Migrations/Mysql/Version20140505093853.php b/Migrations/Mysql/Version20140505093853.php index 05b424e..5f54564 100644 --- a/Migrations/Mysql/Version20140505093853.php +++ b/Migrations/Mysql/Version20140505093853.php @@ -10,7 +10,6 @@ use Doctrine\DBAL\Schema\Schema; */ class Version20140505093853 extends AbstractMigration { - /** * @return string */ diff --git a/Migrations/Mysql/Version20160624203903.php b/Migrations/Mysql/Version20160624203903.php index 0d9ad16..cd2990f 100644 --- a/Migrations/Mysql/Version20160624203903.php +++ b/Migrations/Mysql/Version20160624203903.php @@ -10,7 +10,6 @@ use Doctrine\DBAL\Schema\Schema; */ class Version20160624203903 extends AbstractMigration { - /** * @return string */ diff --git a/Tests/Functional/SequenceTest.php b/Tests/Functional/SequenceTest.php index a4ec07a..7913837 100644 --- a/Tests/Functional/SequenceTest.php +++ b/Tests/Functional/SequenceTest.php @@ -25,7 +25,7 @@ class SequenceTest extends FunctionalTestCase $pIds = []; for ($i = 0; $i < 10; $i++) { - $pId = pcntl_fork(); + $pId = \pcntl_fork(); if ($pId) { $pIds[] = $pId; } else { @@ -39,7 +39,7 @@ class SequenceTest extends FunctionalTestCase foreach ($pIds as $pId) { $status = 0; - pcntl_waitpid($pId, $status); + \pcntl_waitpid($pId, $status); } $this->assertEquals(101, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); From 8492f2f926a31effb801fcc96c5c684447adc7e0 Mon Sep 17 00:00:00 2001 From: Ferdinand Kuhl Date: Sat, 30 Apr 2022 21:45:57 +0200 Subject: [PATCH 28/33] Adding testing and code-style pipelines --- .woodpecker/code-style.yml | 7 ++++++ .woodpecker/test.yml | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 .woodpecker/code-style.yml create mode 100644 .woodpecker/test.yml diff --git a/.woodpecker/code-style.yml b/.woodpecker/code-style.yml new file mode 100644 index 0000000..453df4b --- /dev/null +++ b/.woodpecker/code-style.yml @@ -0,0 +1,7 @@ +pipeline: + code-style: + image: composer + commands: + - composer global config repositories.repo-name vcs https://git.digital-competence.de/Packages/php-codesniffer + - composer global require digicomp/php-codesniffer:@dev + - composer global exec -- phpcs --runtime-set ignore_warnings_on_exit 1 --standard=DigiComp Classes/ Migrations/ Tests/ Resources/Private/ diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml new file mode 100644 index 0000000..cd71c34 --- /dev/null +++ b/.woodpecker/test.yml @@ -0,0 +1,46 @@ +workspace: + base: /woodpecker + path: package + +matrix: + FLOW_VERSION: + - 4.3 + - 5.3 + +pipeline: + functional-tests: + image: thecodingmachine/php:7.4-v4-cli + environment: + # Enable the PDO_SQLITE extension + - "PHP_EXTENSION_PDO_SQLITE=1" + - "FLOW_VERSION=${FLOW_VERSION}" + - "NEOS_BUILD_DIR=/woodpecker/Build-${FLOW_VERSION}" + commands: + - "sudo mkdir $NEOS_BUILD_DIR" + - "sudo chown -R docker:docker $NEOS_BUILD_DIR" + - "cd $NEOS_BUILD_DIR" + - "if [ \"$FLOW_VERSION\" = \"4.3\" ]; then sudo composer self-update --1; fi" + - "composer create-project --no-install neos/flow-base-distribution:^$FLOW_VERSION ." + - "composer config repositories.repo-name path /woodpecker/package" + - "composer remove --dev neos/behat" + - "if [ \"$FLOW_VERSION\" = \"4.3\" ]; then composer require typo3fluid/fluid:2.4.3; fi" + - "composer require digicomp/sequence:@dev" + - | + if [ "$FLOW_VERSION" = "4.3" ]; then + echo 'Neos: + Flow: + persistence: + backendOptions: + dbname: "flow_functional_testing" + error: + errorHandler: + exceptionalErrors: + 0: "%E_USER_ERROR%" + 1: "%E_RECOVERABLE_ERROR%" + 2: ~ + 3: "%E_NOTICE%" + 4: "%E_USER_WARNING%" + 5: "%E_USER_NOTICE%" + 6: "%E_STRICT%"' > Configuration/Testing/Settings.yaml + fi + - "bin/phpunit --configuration Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/DigiComp.Sequence/Tests/Functional" From c74da756a6c09330fc47dec1a7d44017a0a6a1d4 Mon Sep 17 00:00:00 2001 From: Ferdinand Kuhl Date: Sat, 30 Apr 2022 21:48:56 +0200 Subject: [PATCH 29/33] Adjusting tests to work with flow 5.3 and 6.3 --- .woodpecker/test.yml | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml index cd71c34..8d5107f 100644 --- a/.woodpecker/test.yml +++ b/.woodpecker/test.yml @@ -4,8 +4,8 @@ workspace: matrix: FLOW_VERSION: - - 4.3 - 5.3 + - 6.3 pipeline: functional-tests: @@ -19,28 +19,8 @@ pipeline: - "sudo mkdir $NEOS_BUILD_DIR" - "sudo chown -R docker:docker $NEOS_BUILD_DIR" - "cd $NEOS_BUILD_DIR" - - "if [ \"$FLOW_VERSION\" = \"4.3\" ]; then sudo composer self-update --1; fi" - "composer create-project --no-install neos/flow-base-distribution:^$FLOW_VERSION ." - "composer config repositories.repo-name path /woodpecker/package" - "composer remove --dev neos/behat" - - "if [ \"$FLOW_VERSION\" = \"4.3\" ]; then composer require typo3fluid/fluid:2.4.3; fi" - "composer require digicomp/sequence:@dev" - - | - if [ "$FLOW_VERSION" = "4.3" ]; then - echo 'Neos: - Flow: - persistence: - backendOptions: - dbname: "flow_functional_testing" - error: - errorHandler: - exceptionalErrors: - 0: "%E_USER_ERROR%" - 1: "%E_RECOVERABLE_ERROR%" - 2: ~ - 3: "%E_NOTICE%" - 4: "%E_USER_WARNING%" - 5: "%E_USER_NOTICE%" - 6: "%E_STRICT%"' > Configuration/Testing/Settings.yaml - fi - "bin/phpunit --configuration Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/DigiComp.Sequence/Tests/Functional" From 55898c3f8feed50e8eb362b345664fab04d05c51 Mon Sep 17 00:00:00 2001 From: Ferdinand Kuhl Date: Sat, 30 Apr 2022 21:51:03 +0200 Subject: [PATCH 30/33] Do not check Resources/Private (not exists) --- .woodpecker/code-style.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker/code-style.yml b/.woodpecker/code-style.yml index 453df4b..f888059 100644 --- a/.woodpecker/code-style.yml +++ b/.woodpecker/code-style.yml @@ -4,4 +4,4 @@ pipeline: commands: - composer global config repositories.repo-name vcs https://git.digital-competence.de/Packages/php-codesniffer - composer global require digicomp/php-codesniffer:@dev - - composer global exec -- phpcs --runtime-set ignore_warnings_on_exit 1 --standard=DigiComp Classes/ Migrations/ Tests/ Resources/Private/ + - composer global exec -- phpcs --runtime-set ignore_warnings_on_exit 1 --standard=DigiComp Classes/ Migrations/ Tests/ From 5d7f705828de98b44b9198b21f2bd42e9134a505 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Mon, 2 May 2022 09:56:14 +0200 Subject: [PATCH 31/33] add "declare(strict_types=1);" --- Migrations/Mysql/Version20140505093853.php | 2 ++ Migrations/Mysql/Version20160624203903.php | 2 ++ Migrations/Mysql/Version20210922110814.php | 2 ++ 3 files changed, 6 insertions(+) diff --git a/Migrations/Mysql/Version20140505093853.php b/Migrations/Mysql/Version20140505093853.php index d1aa1a3..2b1ea74 100644 --- a/Migrations/Mysql/Version20140505093853.php +++ b/Migrations/Mysql/Version20140505093853.php @@ -1,5 +1,7 @@ Date: Mon, 2 May 2022 10:17:04 +0200 Subject: [PATCH 32/33] Removing Flow 5.3 building (not longer supported) --- .woodpecker/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml index 8d5107f..8a881da 100644 --- a/.woodpecker/test.yml +++ b/.woodpecker/test.yml @@ -4,7 +4,6 @@ workspace: matrix: FLOW_VERSION: - - 5.3 - 6.3 pipeline: From e9ff06a55344420f735aeafccec79b15da4599b9 Mon Sep 17 00:00:00 2001 From: Robin Krahnen Date: Wed, 4 May 2022 19:01:16 +0200 Subject: [PATCH 33/33] optimized versions in composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d955c14..89a5b5a 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "package-key": "DigiComp.Sequence" }, "branch-alias": { - "dev-develop": "3.0.x-dev", + "dev-develop": "4.0.x-dev", "dev-version/2.x-dev": "2.1.x-dev", "dev-version/1.x-dev": "1.1.x-dev" },