Compare commits

..

No commits in common. "master" and "version/2.x" have entirely different histories.

18 changed files with 267 additions and 368 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.svn

View file

@ -1,8 +0,0 @@
pipeline:
code-style:
image: composer
commands:
- composer global config repositories.repo-name vcs https://git.digital-competence.de/Packages/php-codesniffer
- composer global config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
- composer global require digicomp/php-codesniffer:@dev
- composer global exec -- phpcs --runtime-set ignore_warnings_on_exit 1 --standard=DigiComp Classes/ Tests/

View file

@ -1,32 +0,0 @@
workspace:
base: /woodpecker
path: package
matrix:
include:
- FLOW_VERSION: 6.3
PHP_VERSION: 7.4
- FLOW_VERSION: 7.3
PHP_VERSION: 7.4
- FLOW_VERSION: 7.3
PHP_VERSION: 8.2
- FLOW_VERSION: 8.2
PHP_VERSION: 8.2
pipeline:
functional-tests:
image: "thecodingmachine/php:${PHP_VERSION}-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"
- "composer create-project --no-install neos/flow-base-distribution:^$FLOW_VERSION ."
- "composer config repositories.repo-name path /woodpecker/package"
- "composer remove --dev --no-update neos/behat || composer remove --no-update neos/behat"
- "composer require digicomp/sequence:@dev"
- "bin/phpunit --configuration Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/DigiComp.Sequence/Tests/Functional"

View file

@ -1,82 +1,34 @@
<?php <?php
declare(strict_types=1);
namespace DigiComp\Sequence\Command; namespace DigiComp\Sequence\Command;
use DigiComp\Sequence\Domain\Model\SequenceEntry;
use DigiComp\Sequence\Service\Exception\InvalidSourceException;
use DigiComp\Sequence\Service\SequenceGenerator; 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\Annotations as Flow;
use Neos\Flow\Cli\CommandController; use Neos\Flow\Cli\CommandController;
/** /**
* A database agnostic SequenceNumber generator
*
* @Flow\Scope("singleton") * @Flow\Scope("singleton")
*/ */
class SequenceCommandController extends CommandController class SequenceCommandController extends CommandController
{ {
/** /**
* @Flow\Inject
* @var SequenceGenerator * @var SequenceGenerator
* @Flow\Inject
*/ */
protected $sequenceGenerator; protected $sequenceGenerator;
/** /**
* @Flow\Inject * Sets minimum number for sequence generator
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* Set last number for sequence generator.
* *
* @param int $to
* @param string $type * @param string $type
* @param int $number
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/ */
public function setLastNumberForCommand(string $type, int $number): void public function advanceCommand($to, $type)
{ {
if ($this->sequenceGenerator->setLastNumberFor($type, $number)) { $this->sequenceGenerator->advanceTo($to, $type);
$this->outputLine('Last number successfully set.');
} else {
$this->outputLine('Failed to set last number.');
}
} }
/** // TODO: make clean up job to delete all but the biggest number to save resources
* Clean up sequence table.
*
* @param string[] $types
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/
public function cleanUpCommand(array $types = []): void
{
if ($types === []) {
foreach (
$this
->entityManager
->createQuery('SELECT DISTINCT(se.type) type FROM ' . SequenceEntry::class . ' se')
->execute()
as $result
) {
$types[] = $result['type'];
}
}
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 . '".');
}
}
} }

View file

@ -0,0 +1,76 @@
<?php
namespace DigiComp\Sequence\Domain\Model;
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"})
* })
*/
class Insert
{
/**
* @var int
* @Flow\Identity
* @ORM\Id
*/
protected $number;
/**
* @var string
* @Flow\Identity
* @ORM\Id
*/
protected $type;
/**
* @param int $number
* @param string|object $type
*/
public function __construct($number, $type)
{
$this->setNumber($number);
$this->setType($type);
}
/**
* @return int
*/
public function getNumber()
{
return $this->number;
}
/**
* @param int $number
*/
public function setNumber($number)
{
$this->number = $number;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @param string|object $type
*/
public function setType($type)
{
if (is_object($type)) {
$type = get_class($type);
}
$this->type = $type;
}
}

View file

@ -1,28 +0,0 @@
<?php
declare(strict_types=1);
namespace DigiComp\Sequence\Domain\Model;
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
*/
class SequenceEntry
{
/**
* @ORM\Id
* @var string
*/
protected string $type;
/**
* @ORM\Id
* @var int
*/
protected int $number;
}

View file

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
namespace DigiComp\Sequence;
use Neos\Flow\Exception as NeosFlowException;
class Exception extends NeosFlowException
{
}

View file

@ -0,0 +1,10 @@
<?php
namespace DigiComp\Sequence\Service;
/**
* SequenceException
*/
class Exception extends \Exception
{
}

View file

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
namespace DigiComp\Sequence\Service\Exception;
use DigiComp\Sequence\Exception;
class InvalidSourceException extends Exception
{
}

View file

@ -1,20 +1,18 @@
<?php <?php
declare(strict_types=1);
namespace DigiComp\Sequence\Service; namespace DigiComp\Sequence\Service;
use DigiComp\Sequence\Domain\Model\SequenceEntry; use DigiComp\Sequence\Domain\Model\Insert;
use DigiComp\Sequence\Service\Exception\InvalidSourceException; use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\DBAL\Driver\Exception as DoctrineDBALDriverException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Exception as DoctrineDBALException; use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Neos\Flow\Annotations as Flow; use Neos\Flow\Annotations as Flow;
use Neos\Flow\Log\SystemLoggerInterface;
use Neos\Flow\Reflection\ReflectionService;
use Neos\Utility\TypeHandling; use Neos\Utility\TypeHandling;
use Psr\Log\LoggerInterface;
/** /**
* A sequence number generator working for transactional databases. * A SequenceNumber generator working for transactional databases
* *
* Thoughts: We could make the step-range configurable, and if > 1 we could return new keys immediately for this * Thoughts: We could make the step-range configurable, and if > 1 we could return new keys immediately for this
* request, as we "reserved" the space between. * request, as we "reserved" the space between.
@ -24,114 +22,116 @@ use Psr\Log\LoggerInterface;
class SequenceGenerator class SequenceGenerator
{ {
/** /**
* @var ObjectManager
* @Flow\Inject * @Flow\Inject
* @var EntityManagerInterface
*/ */
protected $entityManager; protected $entityManager;
/** /**
* @var ReflectionService
* @Flow\Inject * @Flow\Inject
* @var LoggerInterface * @deprecated
*/ */
protected $logger; protected $reflectionService;
/** /**
* @param string|object $source * @var SystemLoggerInterface
* @Flow\Inject
*/
protected $systemLogger;
/**
* @param string|object $type
*
* @return int * @return int
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/ */
public function getNextNumberFor($source): int public function getNextNumberFor($type)
{ {
$type = $this->inferTypeFromSource($source); $type = $this->inferTypeFromSource($type);
$number = $this->getLastNumberFor($type); $count = $this->getLastNumberFor($type);
// TODO: Check for maximal tries, or similar? // TODO: Check for maximal tries, or similar
// TODO: Let increment be configurable per type? // TODO: Let increment be configurable per type
do { do {
$number++; $count++;
} while (!$this->insertFor($type, $number)); } while (! $this->validateFreeNumber($count, $type));
return $number; return $count;
} }
/** /**
* @param string $type * @param int $count
* @param int $number * @param string|object $type
*
* @return bool * @return bool
*/ */
protected function insertFor(string $type, int $number): bool protected function validateFreeNumber($count, $type)
{ {
/* @var EntityManager $em */
$em = $this->entityManager;
try { try {
$this->entityManager->getConnection()->insert( $em->getConnection()->insert(
$this->entityManager->getClassMetadata(SequenceEntry::class)->getTableName(), $em->getClassMetadata(Insert::class)->getTableName(),
['type' => $type, 'number' => $number] ['number' => $count, 'type' => $type]
); );
return true; return true;
} catch (\PDOException $exception) { } catch (\PDOException $e) {
} catch (DoctrineDBALException $exception) { return false;
if (!$exception->getPrevious() instanceof \PDOException) { } catch (DBALException $e) {
$this->logger->critical('Exception occurred: ' . $exception->getMessage()); if (! $e->getPrevious() instanceof \PDOException) {
$this->systemLogger->logException($e);
} }
} catch (\Exception $exception) { } catch (\Exception $e) {
$this->logger->critical('Exception occurred: ' . $exception->getMessage()); $this->systemLogger->logException($e);
} }
return false; return false;
} }
/** /**
* @param string|object $source * @param int $to
* @param int $number * @param string|object $type
*
* @return bool * @return bool
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/ */
public function setLastNumberFor($source, int $number): bool public function advanceTo($to, $type)
{ {
$type = $this->inferTypeFromSource($source); $type = $this->inferTypeFromSource($type);
if ($this->getLastNumberFor($type) >= $number) { return $this->validateFreeNumber($to, $type);
return false;
}
return $this->insertFor($type, $number);
} }
/** /**
* @param string|object $source * @param string|object $type
* @throws DoctrineDBALDriverException *
* @throws DoctrineDBALException * @return int
* @throws InvalidSourceException
*/ */
public function getLastNumberFor($source): int public function getLastNumberFor($type)
{ {
return (int)$this->entityManager->getConnection()->executeQuery( /* @var EntityManager $em */
'SELECT MAX(number) FROM ' $em = $this->entityManager;
. $this->entityManager->getClassMetadata(SequenceEntry::class)->getTableName()
. ' WHERE type = :type', return $em->getConnection()->executeQuery(
['type' => $this->inferTypeFromSource($source)] 'SELECT MAX(number) FROM ' . $em->getClassMetadata(Insert::class)->getTableName() . ' WHERE type = :type',
)->fetchOne(); ['type' => $this->inferTypeFromSource($type)]
)->fetchAll(\PDO::FETCH_COLUMN)[0];
} }
/** /**
* @param string|object $source * @param string|object $stringOrObject
*
* @return string * @return string
* @throws InvalidSourceException * @throws Exception
*/ */
protected function inferTypeFromSource($source): string protected function inferTypeFromSource($stringOrObject)
{ {
if (\is_string($source)) { if (is_object($stringOrObject)) {
return $source; $stringOrObject = TypeHandling::getTypeForValue($stringOrObject);
}
if (! $stringOrObject) {
throw new Exception('No Type given');
} }
if (\is_object($source)) { return $stringOrObject;
return TypeHandling::getTypeForValue($source);
}
throw new InvalidSourceException('Could not infer type from source.', 1632216173);
} }
} }

View file

@ -2,5 +2,5 @@ Neos:
Flow: Flow:
persistence: persistence:
backendOptions: backendOptions:
driver: "pdo_sqlite" driver: 'pdo_sqlite'
path: "%FLOW_PATH_DATA%Temporary/testing.db" path: '%FLOW_PATH_DATA%/Temporary/testing.db'

View file

@ -1,37 +1,46 @@
<?php <?php
declare(strict_types=1);
namespace Neos\Flow\Persistence\Doctrine\Migrations; namespace Neos\Flow\Persistence\Doctrine\Migrations;
use Doctrine\DBAL\Exception as DoctrineDBALException; use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Migrations\AbortMigrationException;
use Doctrine\DBAL\Schema\Schema; 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 class Version20140505093853 extends AbstractMigration
{ {
/**
* @param Schema $schema
* @throws AbortMigrationException
* @throws DoctrineDBALException
*/
public function up(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, PRIMARY KEY(number, type))'); /**
* @return string
*/
public function getDescription()
{
return '';
} }
/** /**
* @param Schema $schema * @param Schema $schema
* @throws AbortMigrationException * @return void
* @throws DoctrineDBALException
*/ */
public function down(Schema $schema): void public function up(Schema $schema)
{ {
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); // this up() migration is autogenerated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");
$this->addSql('DROP TABLE digicomp_sequence_domain_model_insert'); $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
*/
public function down(Schema $schema)
{
// this down() migration is autogenerated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");
$this->addSql("DROP TABLE digicomp_sequence_domain_model_insert");
} }
} }

View file

@ -1,36 +1,49 @@
<?php <?php
declare(strict_types=1);
namespace Neos\Flow\Persistence\Doctrine\Migrations; namespace Neos\Flow\Persistence\Doctrine\Migrations;
use Doctrine\DBAL\Exception as DoctrineDBALException; use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Migrations\AbortMigrationException;
use Doctrine\DBAL\Schema\Schema; 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 class Version20160624203903 extends AbstractMigration
{ {
/**
* @return string
*/
public function getDescription()
{
return '';
}
/** /**
* @param Schema $schema * @param Schema $schema
* @throws AbortMigrationException * @return void
* @throws DoctrineDBALException
*/ */
public function up(Schema $schema): void public function up(Schema $schema)
{ {
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); // 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->addSql('CREATE INDEX type_idx ON digicomp_sequence_domain_model_insert (type)'); $this->addSql('CREATE INDEX type_idx ON digicomp_sequence_domain_model_insert (type)');
} }
/** /**
* @param Schema $schema * @param Schema $schema
* @throws AbortMigrationException * @return void
* @throws DoctrineDBALException
*/ */
public function down(Schema $schema): void public function down(Schema $schema)
{ {
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); // 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->addSql('DROP INDEX type_idx ON digicomp_sequence_domain_model_insert'); $this->addSql('DROP INDEX type_idx ON digicomp_sequence_domain_model_insert');
} }

View file

@ -1,41 +0,0 @@
<?php
declare(strict_types=1);
namespace Neos\Flow\Persistence\Doctrine\Migrations;
use Doctrine\DBAL\Exception as DoctrineDBALException;
use Doctrine\DBAL\Migrations\AbortMigrationException;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
class Version20210922110814 extends AbstractMigration
{
/**
* @param Schema $schema
* @throws AbortMigrationException
* @throws DoctrineDBALException
*/
public function up(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_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');
}
/**
* @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 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');
}
}

View file

@ -1,23 +1,22 @@
# DigiComp.Sequence DigiComp.Sequence
-------------------------
![Build status](https://ci.digital-competence.de/api/badges/Packages/DigiComp.FlowObjectResolving/status.svg)
This is a very simple tool, helping in generation of gapless sequences. For this task it relies on key integrity of the This is a very simple and stupid tool, helping in generation of gapless sequences. For this task it relies on key
database of your choice. integrity of the database of your choice.
Usage is quite simple also: Usage is quite simple also:
```php
/** /**
* @param SequenceGenerator $sequenceGenerator * @param \DigiComp\Sequence\Service\SequenceNumberGenerator $sequenceNumberGenerator
*/ */
public function __construct(SequenceGenerator $sequenceNumberGenerator) public function __construct(SequenceNumberGenerator $sequenceNumberGenerator)
{ {
$this->orderId = $sequenceGenerator->getNextNumberFor($this); $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 `SequenceCommandController` helps you to set the last sequence number, in case of migrations or similar. See The CommandController helps you to advance the current sequence number, in case of migrations or similar.
`./flow help sequence:setlastnumberfor` if interested.
See ``./flow help sequence:advance`` if interested.

View file

@ -1,39 +1,32 @@
<?php <?php
declare(strict_types=1);
namespace DigiComp\Sequence\Tests\Functional; namespace DigiComp\Sequence\Tests\Functional;
use DigiComp\Sequence\Service\Exception\InvalidSourceException;
use DigiComp\Sequence\Service\SequenceGenerator; use DigiComp\Sequence\Service\SequenceGenerator;
use Doctrine\DBAL\Driver\Exception as DoctrineDBALDriverException;
use Doctrine\DBAL\Exception as DoctrineDBALException;
use Neos\Flow\Tests\FunctionalTestCase; use Neos\Flow\Tests\FunctionalTestCase;
class SequenceTest extends FunctionalTestCase class SequenceTest extends FunctionalTestCase
{ {
/** /**
* @inheritDoc * @var bool
*/ */
protected static $testablePersistenceEnabled = true; protected static $testablePersistenceEnabled = true;
/** /**
* @test * @test
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/ */
public function sequenceTest(): void public function sequenceTest()
{ {
$sequenceGenerator = $this->objectManager->get(SequenceGenerator::class); $sequenceGenerator = $this->objectManager->get(SequenceGenerator::class);
self::assertEquals(0, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); $number = $sequenceGenerator->getLastNumberFor($sequenceGenerator);
self::assertEquals(1, $sequenceGenerator->getNextNumberFor($sequenceGenerator)); $this->assertEquals(0, $number);
$this->assertEquals(1, $sequenceGenerator->getNextNumberFor($sequenceGenerator));
$pIds = []; $pIds = [];
for ($i = 0; $i < 10; $i++) { for ($i = 0; $i < 10; $i++) {
$pId = \pcntl_fork(); $pId = pcntl_fork();
if ($pId > 0) { if ($pId) {
$pIds[] = $pId; $pIds[] = $pId;
} else { } else {
for ($j = 0; $j < 10; $j++) { for ($j = 0; $j < 10; $j++) {
@ -46,24 +39,21 @@ class SequenceTest extends FunctionalTestCase
foreach ($pIds as $pId) { foreach ($pIds as $pId) {
$status = 0; $status = 0;
\pcntl_waitpid($pId, $status); pcntl_waitpid($pId, $status);
} }
self::assertEquals(101, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); $this->assertEquals(101, $sequenceGenerator->getLastNumberFor($sequenceGenerator));
} }
/** /**
* @test * @test
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/ */
public function setLastNumberForTest(): void public function advanceTest()
{ {
$sequenceGenerator = $this->objectManager->get(SequenceGenerator::class); $sequenceGenerator = $this->objectManager->get(SequenceGenerator::class);
$sequenceGenerator->setLastNumberFor($sequenceGenerator, 100);
self::assertEquals(100, $sequenceGenerator->getLastNumberFor($sequenceGenerator)); $sequenceGenerator->advanceTo(100, $sequenceGenerator);
self::assertEquals(0, $sequenceGenerator->getLastNumberFor('otherSequence')); $this->assertEquals(100, $sequenceGenerator->getLastNumberFor($sequenceGenerator));
$this->assertEquals(0, $sequenceGenerator->getLastNumberFor('strangeOtherSequence'));
} }
} }

View file

@ -1,57 +1,39 @@
{ {
"name": "digicomp/sequence", "name": "digicomp/sequence",
"description": "Sequence is a very simple database agnostic but database based sequence generator",
"type": "neos-package", "type": "neos-package",
"description": "Sequence is a very simple database agnostic but database based sequence generator",
"keywords": [ "keywords": [
"Neos", "flow",
"Flow", "neos",
"doctrine", "doctrine",
"sequence" "sequence"
], ],
"homepage": "https://github.com/digital-competence/DigiComp.Sequence",
"license": "MIT",
"authors": [ "authors": [
{ {
"name": "Ferdinand Kuhl", "name": "Ferdinand Kuhl",
"email": "f.kuhl@digital-competence.de", "email": "f.kuhl@digital-competence.de",
"homepage": "https://www.digital-competence.de", "homepage": "http://www.digital-competence.de",
"role": "Developer" "role": "Developer"
} }
], ],
"license": "MIT",
"homepage": "https://github.com/digicomp/DigiComp.Sequence",
"require": { "require": {
"php": ">=7.4.0", "neos/flow": "~4.1|~5.3"
"ext-pdo": "*",
"neos/flow": "^6.3.5 || ^7.0 || ^8.0"
}, },
"require-dev": { "require-dev": {
"ext-pcntl": "*", "phpunit/phpunit": "3.7.*",
"mikey179/vfsstream": "^1.6.1", "ext-pcntl": "*"
"neos/buildessentials": "^7.0.0",
"phpunit/phpunit": "~8.5",
"vimeo/psalm": "~4.22.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"DigiComp\\Sequence\\": "Classes/" "DigiComp\\Sequence\\": "Classes"
} }
}, },
"autoload-dev": {
"psr-4": {
"DigiComp\\Sequence\\Tests\\": "Tests/"
}
},
"config": {
"sort-packages": true,
"platform-check": true
},
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-develop": "4.0.x-dev", "dev-version/1.x-dev": "1.1.x-dev",
"dev-version/2.x-dev": "2.1.x-dev", "dev-develop": "2.0.x-dev"
"dev-version/1.x-dev": "1.1.x-dev"
},
"neos": {
"package-key": "DigiComp.Sequence"
}, },
"applied-flow-migrations": [ "applied-flow-migrations": [
"Inwebs.Basket-201409170938", "Inwebs.Basket-201409170938",
@ -85,9 +67,7 @@
"Neos.Flow-20170125103800", "Neos.Flow-20170125103800",
"Neos.Flow-20170127183102", "Neos.Flow-20170127183102",
"DigiComp.SettingValidator-20170603120900", "DigiComp.SettingValidator-20170603120900",
"Neos.Flow-20180415105700", "Neos.Flow-20180415105700"
"Neos.Flow-20190425144900",
"Neos.Flow-20190515215000"
] ]
} }
} }