Compare commits

..

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

20 changed files with 400 additions and 527 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 +0,0 @@
<?php
declare(strict_types=1);
namespace DigiComp\Sequence\Command;
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;
use Doctrine\ORM\EntityManagerInterface;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Cli\CommandController;
/**
* @Flow\Scope("singleton")
*/
class SequenceCommandController extends CommandController
{
/**
* @Flow\Inject
* @var SequenceGenerator
*/
protected $sequenceGenerator;
/**
* @Flow\Inject
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* Set last number for sequence generator.
*
* @param string $type
* @param int $number
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/
public function setLastNumberForCommand(string $type, int $number): void
{
if ($this->sequenceGenerator->setLastNumberFor($type, $number)) {
$this->outputLine('Last number successfully set.');
} else {
$this->outputLine('Failed to set last number.');
}
}
/**
* 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,38 @@
<?php
namespace DigiComp\Sequence\Command;
/* *
* This script belongs to the FLOW3 package "DigiComp.Sequence". *
* *
* */
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Cli\CommandController;
/**
* A database agnostic SequenceNumber generator
*
* @Flow\Scope("singleton")
*/
class SequenceCommandController extends CommandController
{
/**
* @var \DigiComp\Sequence\Service\SequenceGenerator
* @Flow\Inject
*/
protected $sequenceGenerator;
/**
* Sets minimum number for sequence generator
*
* @param int $to
* @param string $type
*/
public function advanceCommand($to, $type)
{
$this->sequenceGenerator->advanceTo($to, $type);
}
//TODO: make clean up job to delete all but the biggest number to save resources
}

View file

@ -0,0 +1,81 @@
<?php
namespace DigiComp\Sequence\Domain\Model;
/* *
* This script belongs to the FLOW3 package "DigiComp.Sequence". *
* *
* */
use TYPO3\Flow\Annotations as Flow;
use Doctrine\ORM\Mapping as ORM;
/**
* SequenceInsert
*
* @author fcool
* @Flow\Scope("prototype")
* @Flow\Entity
* @ORM\Table(indexes={@ORM\Index(name="type_idx", columns={"type"})})
*/
class Insert
{
/**
* @var int
* @ORM\Id
* @Flow\Identity
*/
protected $number;
/**
* @var string
* @ORM\Id
* @Flow\Identity
*/
protected $type;
/**
* @param int $number
* @param string|object $type
*/
public function __construct($number, $type)
{
$this->setType($type);
$this->setNumber($number);
}
/**
* @param int $number
*/
public function setNumber($number)
{
$this->number = $number;
}
/**
* @return int
*/
public function getNumber()
{
return $this->number;
}
/**
* @param string|object $type
*/
public function setType($type)
{
if (is_object($type)) {
$type = get_class($type);
}
$this->type = $type;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace DigiComp\Sequence\Service;
/* *
* This script belongs to the FLOW3 package "DigiComp.Sequence". *
* *
* */
use TYPO3\Flow\Annotations as Flow;
/**
* SequenceException
*/
class Exception extends \Exception
{
}

View file

@ -0,0 +1,126 @@
<?php
namespace DigiComp\Sequence\Service;
/* *
* This script belongs to the FLOW3 package "DigiComp.Sequence". *
* *
* */
use Doctrine\DBAL\DBALException;
use TYPO3\Flow\Annotations as Flow;
/**
* 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
* request, as we "reserved" the space between.
*
* @Flow\Scope("singleton")
*/
class SequenceGenerator
{
/**
* @var \Doctrine\Common\Persistence\ObjectManager
* @Flow\Inject
*/
protected $entityManager;
/**
* @var \TYPO3\Flow\Reflection\ReflectionService
* @Flow\Inject
*/
protected $reflectionService;
/**
* @var \TYPO3\Flow\Log\SystemLoggerInterface
* @Flow\Inject
*/
protected $systemLogger;
/**
* @param string|object $type
*
* @throws \DigiComp\Sequence\Service\Exception
* @return int
*/
public function getNextNumberFor($type)
{
$type = $this->inferTypeFromSource($type);
$count = $this->getLastNumberFor($type);
//TODO: Check for maximal tries, or similar
//TODO: Let increment be configurable per type
do {
$count = $count + 1;
} while (!$this->validateFreeNumber($count, $type));
return $count;
}
protected function validateFreeNumber($count, $type)
{
$em = $this->entityManager;
/** @var $em \Doctrine\ORM\EntityManager */
try {
$em->getConnection()->insert(
'digicomp_sequence_domain_model_insert',
['number' => $count, 'type' => $type]
);
return true;
} catch (\PDOException $e) {
return false;
} catch (DBALException $e) {
if ($e->getPrevious() && $e->getPrevious() instanceof \PDOException) {
// Do nothing, new Doctrine handling hides the above error
} else {
$this->systemLogger->logException($e);
}
} catch (\Exception $e) {
$this->systemLogger->logException($e);
}
return false;
}
public function advanceTo($to, $type)
{
$type = $this->inferTypeFromSource($type);
return ($this->validateFreeNumber($to, $type));
}
/**
* @param string|object $type
*
* @return int
*/
public function getLastNumberFor($type)
{
$type = $this->inferTypeFromSource($type);
/** @var $em \Doctrine\ORM\EntityManager */
$em = $this->entityManager;
$result = $em->getConnection()->executeQuery(
'SELECT MAX(number) AS count FROM digicomp_sequence_domain_model_insert WHERE type=:type',
['type' => $type]
);
$count = $result->fetchAll();
$count = $count[0]['count'];
return $count;
}
/**
* @param string|object $stringOrObject
*
* @throws Exception
* @return string
*/
protected function inferTypeFromSource($stringOrObject) {
if (is_object($stringOrObject)) {
$stringOrObject = $this->reflectionService->getClassNameByObject($stringOrObject);
}
if (!$stringOrObject) {
throw new Exception('No Type given');
}
return $stringOrObject;
}
}

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

@ -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,137 +0,0 @@
<?php
declare(strict_types=1);
namespace DigiComp\Sequence\Service;
use DigiComp\Sequence\Domain\Model\SequenceEntry;
use DigiComp\Sequence\Service\Exception\InvalidSourceException;
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\Utility\TypeHandling;
use Psr\Log\LoggerInterface;
/**
* A sequence number generator working for transactional databases.
*
* 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.
*
* @Flow\Scope("singleton")
*/
class SequenceGenerator
{
/**
* @Flow\Inject
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* @Flow\Inject
* @var LoggerInterface
*/
protected $logger;
/**
* @param string|object $source
* @return int
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/
public function getNextNumberFor($source): int
{
$type = $this->inferTypeFromSource($source);
$number = $this->getLastNumberFor($type);
// TODO: Check for maximal tries, or similar?
// TODO: Let increment be configurable per type?
do {
$number++;
} while (!$this->insertFor($type, $number));
return $number;
}
/**
* @param string $type
* @param int $number
* @return bool
*/
protected function insertFor(string $type, int $number): bool
{
try {
$this->entityManager->getConnection()->insert(
$this->entityManager->getClassMetadata(SequenceEntry::class)->getTableName(),
['type' => $type, 'number' => $number]
);
return true;
} catch (\PDOException $exception) {
} catch (DoctrineDBALException $exception) {
if (!$exception->getPrevious() instanceof \PDOException) {
$this->logger->critical('Exception occurred: ' . $exception->getMessage());
}
} catch (\Exception $exception) {
$this->logger->critical('Exception occurred: ' . $exception->getMessage());
}
return false;
}
/**
* @param string|object $source
* @param int $number
* @return bool
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/
public function setLastNumberFor($source, int $number): bool
{
$type = $this->inferTypeFromSource($source);
if ($this->getLastNumberFor($type) >= $number) {
return false;
}
return $this->insertFor($type, $number);
}
/**
* @param string|object $source
* @throws DoctrineDBALDriverException
* @throws DoctrineDBALException
* @throws InvalidSourceException
*/
public function getLastNumberFor($source): int
{
return (int)$this->entityManager->getConnection()->executeQuery(
'SELECT MAX(number) FROM '
. $this->entityManager->getClassMetadata(SequenceEntry::class)->getTableName()
. ' WHERE type = :type',
['type' => $this->inferTypeFromSource($source)]
)->fetchOne();
}
/**
* @param string|object $source
* @return string
* @throws InvalidSourceException
*/
protected function inferTypeFromSource($source): string
{
if (\is_string($source)) {
return $source;
}
if (\is_object($source)) {
return TypeHandling::getTypeForValue($source);
}
throw new InvalidSourceException('Could not infer type from source.', 1632216173);
}
}

View file

@ -1,6 +1,6 @@
Neos: TYPO3:
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,40 @@
<?php <?php
namespace TYPO3\Flow\Persistence\Doctrine\Migrations;
declare(strict_types=1); use Doctrine\DBAL\Migrations\AbstractMigration,
Doctrine\DBAL\Schema\Schema;
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;
/**
* Auto-generated Migration: Please modify to your need!
*/
class Version20140505093853 extends AbstractMigration class Version20140505093853 extends AbstractMigration
{ {
/** /**
* @param Schema $schema * @param Schema $schema
* @throws AbortMigrationException *
* @throws DoctrineDBALException * @return void
*/ */
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");
$this->addSql('CREATE TABLE digicomp_sequence_domain_model_insert (number INT NOT NULL, type VARCHAR(255) NOT NULL, PRIMARY KEY(number, type))'); $this->addSql(
"CREATE TABLE digicomp_sequence_domain_model_insert (number INT NOT NULL, type VARCHAR(255) NOT NULL, PRIMARY KEY(number, type)) ENGINE = InnoDB"
);
} }
/** /**
* @param Schema $schema * @param Schema $schema
* @throws AbortMigrationException *
* @throws DoctrineDBALException * @return void
*/ */
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");
$this->addSql('DROP TABLE digicomp_sequence_domain_model_insert'); $this->addSql("DROP TABLE digicomp_sequence_domain_model_insert");
} }
} }

View file

@ -1,36 +1,52 @@
<?php <?php
namespace TYPO3\Flow\Persistence\Doctrine\Migrations;
declare(strict_types=1); use Doctrine\DBAL\Migrations\AbstractMigration;
namespace Neos\Flow\Persistence\Doctrine\Migrations;
use Doctrine\DBAL\Exception as DoctrineDBALException;
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 *
* @throws DoctrineDBALException * @return void
*/ */
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 *
* @throws DoctrineDBALException * @return void
*/ */
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,40 +1,30 @@
<?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 TYPO3\Flow\Tests\FunctionalTestCase;
use Doctrine\DBAL\Exception as DoctrineDBALException;
use Neos\Flow\Tests\FunctionalTestCase;
class SequenceTest extends FunctionalTestCase class SequenceTest extends FunctionalTestCase
{ {
/**
* @inheritDoc
*/
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++) {
$sequenceGenerator->getNextNumberFor($sequenceGenerator); $sequenceGenerator->getNextNumberFor($sequenceGenerator);
@ -43,27 +33,22 @@ class SequenceTest extends FunctionalTestCase
exit; exit;
} }
} }
foreach ($pids as $pid) {
foreach ($pIds as $pId) {
$status = 0; $status = 0;
\pcntl_waitpid($pId, $status); pcntl_waitpid($pid, $status);
} }
$this->assertEquals(101, $sequenceGenerator->getLastNumberFor($sequenceGenerator));
self::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,33 @@
{ {
"name": "digicomp/sequence", "name": "digicomp/sequence",
"type": "typo3-flow-package",
"description": "Sequence is a very simple database agnostic but database based sequence generator", "description": "Sequence is a very simple database agnostic but database based sequence generator",
"type": "neos-package", "keywords": ["flow", "neos", "doctrine", "sequence"],
"keywords": [
"Neos",
"Flow",
"doctrine",
"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", "typo3/flow": "~2.0|~3.0"
"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-0": {
"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-master": "1.1.x-dev"
"dev-version/2.x-dev": "2.1.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",
@ -68,26 +44,7 @@
"TYPO3.Fluid-20141113120800", "TYPO3.Fluid-20141113120800",
"TYPO3.Flow-20141113121400", "TYPO3.Flow-20141113121400",
"TYPO3.Fluid-20141121091700", "TYPO3.Fluid-20141121091700",
"TYPO3.Fluid-20150214130800", "TYPO3.Fluid-20150214130800"
"TYPO3.Flow-20151113161300",
"TYPO3.Flow-20161115140400",
"TYPO3.Flow-20161115140430",
"Neos.Flow-20161124204700",
"Neos.Flow-20161124204701",
"Neos.Flow-20161124224015",
"Neos.Eel-20161124230101",
"Neos.Imagine-20161124231742",
"Neos.Media-20161124233100",
"Neos.Flow-20161125124112",
"Neos.SwiftMailer-20161130105617",
"TYPO3.FluidAdaptor-20161130112935",
"Neos.Media-20161219094126",
"Neos.Flow-20170125103800",
"Neos.Flow-20170127183102",
"DigiComp.SettingValidator-20170603120900",
"Neos.Flow-20180415105700",
"Neos.Flow-20190425144900",
"Neos.Flow-20190515215000"
] ]
} }
} }