Merge branch 'feature/neos-flow4' into develop
This commit is contained in:
commit
33ec7a241c
11 changed files with 190 additions and 162 deletions
33
Classes/Command/SequenceCommandController.php
Normal file
33
Classes/Command/SequenceCommandController.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
namespace DigiComp\Sequence\Command;
|
||||||
|
|
||||||
|
use DigiComp\Sequence\Service\SequenceGenerator;
|
||||||
|
use Neos\Flow\Annotations as Flow;
|
||||||
|
use Neos\Flow\Cli\CommandController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A database agnostic SequenceNumber generator
|
||||||
|
*
|
||||||
|
* @Flow\Scope("singleton")
|
||||||
|
*/
|
||||||
|
class SequenceCommandController extends CommandController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var 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
|
||||||
|
}
|
|
@ -1,38 +0,0 @@
|
||||||
<?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
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?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
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,13 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
namespace DigiComp\Sequence\Domain\Model;
|
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;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Neos\Flow\Annotations as Flow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SequenceInsert
|
* SequenceInsert
|
||||||
|
@ -19,18 +14,17 @@ use Doctrine\ORM\Mapping as ORM;
|
||||||
*/
|
*/
|
||||||
class Insert
|
class Insert
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
* @ORM\Id
|
|
||||||
* @Flow\Identity
|
* @Flow\Identity
|
||||||
|
* @ORM\Id
|
||||||
*/
|
*/
|
||||||
protected $number;
|
protected $number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
* @ORM\Id
|
|
||||||
* @Flow\Identity
|
* @Flow\Identity
|
||||||
|
* @ORM\Id
|
||||||
*/
|
*/
|
||||||
protected $type;
|
protected $type;
|
||||||
|
|
||||||
|
@ -40,8 +34,16 @@ class Insert
|
||||||
*/
|
*/
|
||||||
public function __construct($number, $type)
|
public function __construct($number, $type)
|
||||||
{
|
{
|
||||||
$this->setType($type);
|
|
||||||
$this->setNumber($number);
|
$this->setNumber($number);
|
||||||
|
$this->setType($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getNumber()
|
||||||
|
{
|
||||||
|
return $this->number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,11 +55,11 @@ class Insert
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getNumber()
|
public function getType()
|
||||||
{
|
{
|
||||||
return $this->number;
|
return $this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,12 +72,4 @@ class Insert
|
||||||
}
|
}
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getType()
|
|
||||||
{
|
|
||||||
return $this->type;
|
|
||||||
}
|
|
||||||
}
|
}
|
12
Classes/Service/Exception.php
Normal file
12
Classes/Service/Exception.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
namespace DigiComp\Sequence\Service;
|
||||||
|
|
||||||
|
use Neos\Flow\Annotations as Flow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SequenceException
|
||||||
|
*/
|
||||||
|
class Exception extends \Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -1,18 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
namespace DigiComp\Sequence\Service;
|
namespace DigiComp\Sequence\Service;
|
||||||
|
|
||||||
/* *
|
use Doctrine\Common\Persistence\ObjectManager;
|
||||||
* This script belongs to the FLOW3 package "DigiComp.Sequence". *
|
|
||||||
* *
|
|
||||||
* */
|
|
||||||
|
|
||||||
use Doctrine\DBAL\DBALException;
|
use Doctrine\DBAL\DBALException;
|
||||||
use TYPO3\Flow\Annotations as Flow;
|
use Doctrine\ORM\EntityManager;
|
||||||
|
use Neos\Flow\Annotations as Flow;
|
||||||
|
use Neos\Flow\Log\SystemLoggerInterface;
|
||||||
|
use Neos\Flow\Reflection\ReflectionService;
|
||||||
|
use Neos\Utility\TypeHandling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A SequenceNumber 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.
|
||||||
*
|
*
|
||||||
|
@ -20,21 +19,20 @@ use TYPO3\Flow\Annotations as Flow;
|
||||||
*/
|
*/
|
||||||
class SequenceGenerator
|
class SequenceGenerator
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Doctrine\Common\Persistence\ObjectManager
|
* @var ObjectManager
|
||||||
* @Flow\Inject
|
* @Flow\Inject
|
||||||
*/
|
*/
|
||||||
protected $entityManager;
|
protected $entityManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \TYPO3\Flow\Reflection\ReflectionService
|
* @var ReflectionService
|
||||||
* @Flow\Inject
|
* @Flow\Inject
|
||||||
*/
|
*/
|
||||||
protected $reflectionService;
|
protected $reflectionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \TYPO3\Flow\Log\SystemLoggerInterface
|
* @var SystemLoggerInterface
|
||||||
* @Flow\Inject
|
* @Flow\Inject
|
||||||
*/
|
*/
|
||||||
protected $systemLogger;
|
protected $systemLogger;
|
||||||
|
@ -42,7 +40,8 @@ class SequenceGenerator
|
||||||
/**
|
/**
|
||||||
* @param string|object $type
|
* @param string|object $type
|
||||||
*
|
*
|
||||||
* @throws \DigiComp\Sequence\Service\Exception
|
* @throws Exception
|
||||||
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getNextNumberFor($type)
|
public function getNextNumberFor($type)
|
||||||
|
@ -50,18 +49,25 @@ class SequenceGenerator
|
||||||
$type = $this->inferTypeFromSource($type);
|
$type = $this->inferTypeFromSource($type);
|
||||||
$count = $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 {
|
||||||
$count = $count + 1;
|
$count++;
|
||||||
} while (!$this->validateFreeNumber($count, $type));
|
} while (! $this->validateFreeNumber($count, $type));
|
||||||
|
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $count
|
||||||
|
* @param string|object $type
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function validateFreeNumber($count, $type)
|
protected function validateFreeNumber($count, $type)
|
||||||
{
|
{
|
||||||
|
/** @var $em EntityManager */
|
||||||
$em = $this->entityManager;
|
$em = $this->entityManager;
|
||||||
/** @var $em \Doctrine\ORM\EntityManager */
|
|
||||||
try {
|
try {
|
||||||
$em->getConnection()->insert(
|
$em->getConnection()->insert(
|
||||||
'digicomp_sequence_domain_model_insert',
|
'digicomp_sequence_domain_model_insert',
|
||||||
|
@ -73,18 +79,27 @@ class SequenceGenerator
|
||||||
} catch (DBALException $e) {
|
} catch (DBALException $e) {
|
||||||
if ($e->getPrevious() && $e->getPrevious() instanceof \PDOException) {
|
if ($e->getPrevious() && $e->getPrevious() instanceof \PDOException) {
|
||||||
// Do nothing, new Doctrine handling hides the above error
|
// Do nothing, new Doctrine handling hides the above error
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
$this->systemLogger->logException($e);
|
$this->systemLogger->logException($e);
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->systemLogger->logException($e);
|
$this->systemLogger->logException($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $to
|
||||||
|
* @param string|object $type
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function advanceTo($to, $type)
|
public function advanceTo($to, $type)
|
||||||
{
|
{
|
||||||
$type = $this->inferTypeFromSource($type);
|
$type = $this->inferTypeFromSource($type);
|
||||||
|
|
||||||
return ($this->validateFreeNumber($to, $type));
|
return ($this->validateFreeNumber($to, $type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,16 +110,16 @@ class SequenceGenerator
|
||||||
*/
|
*/
|
||||||
public function getLastNumberFor($type)
|
public function getLastNumberFor($type)
|
||||||
{
|
{
|
||||||
$type = $this->inferTypeFromSource($type);
|
/** @var $em EntityManager */
|
||||||
/** @var $em \Doctrine\ORM\EntityManager */
|
|
||||||
$em = $this->entityManager;
|
$em = $this->entityManager;
|
||||||
|
|
||||||
$result = $em->getConnection()->executeQuery(
|
$result = $em->getConnection()->executeQuery(
|
||||||
'SELECT MAX(number) AS count FROM digicomp_sequence_domain_model_insert WHERE type=:type',
|
'SELECT MAX(number) AS count FROM digicomp_sequence_domain_model_insert WHERE type=:type',
|
||||||
['type' => $type]
|
['type' => $this->inferTypeFromSource($type)]
|
||||||
);
|
);
|
||||||
$count = $result->fetchAll();
|
$count = $result->fetchAll();
|
||||||
$count = $count[0]['count'];
|
$count = $count[0]['count'];
|
||||||
|
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,15 +127,18 @@ class SequenceGenerator
|
||||||
* @param string|object $stringOrObject
|
* @param string|object $stringOrObject
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function inferTypeFromSource($stringOrObject) {
|
protected function inferTypeFromSource($stringOrObject)
|
||||||
|
{
|
||||||
if (is_object($stringOrObject)) {
|
if (is_object($stringOrObject)) {
|
||||||
$stringOrObject = $this->reflectionService->getClassNameByObject($stringOrObject);
|
$stringOrObject = TypeHandling::getTypeForValue($stringOrObject);
|
||||||
}
|
}
|
||||||
if (!$stringOrObject) {
|
if (! $stringOrObject) {
|
||||||
throw new Exception('No Type given');
|
throw new Exception('No Type given');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $stringOrObject;
|
return $stringOrObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
TYPO3:
|
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'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace TYPO3\Flow\Persistence\Doctrine\Migrations;
|
namespace Neos\Flow\Persistence\Doctrine\Migrations;
|
||||||
|
|
||||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||||
Doctrine\DBAL\Schema\Schema;
|
Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace TYPO3\Flow\Persistence\Doctrine\Migrations;
|
namespace Neos\Flow\Persistence\Doctrine\Migrations;
|
||||||
|
|
||||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
namespace DigiComp\Sequence\Tests\Functional;
|
namespace DigiComp\Sequence\Tests\Functional;
|
||||||
|
|
||||||
use DigiComp\Sequence\Service\SequenceGenerator;
|
use DigiComp\Sequence\Service\SequenceGenerator;
|
||||||
use TYPO3\Flow\Tests\FunctionalTestCase;
|
use Neos\Flow\Tests\FunctionalTestCase;
|
||||||
|
|
||||||
class SequenceTest extends FunctionalTestCase
|
class SequenceTest extends FunctionalTestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
protected static $testablePersistenceEnabled = true;
|
protected static $testablePersistenceEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,12 +22,13 @@ class SequenceTest extends FunctionalTestCase
|
||||||
$this->assertEquals(0, $number);
|
$this->assertEquals(0, $number);
|
||||||
$this->assertEquals(1, $sequenceGenerator->getNextNumberFor($sequenceGenerator));
|
$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) {
|
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);
|
||||||
}
|
}
|
||||||
|
@ -33,10 +36,12 @@ 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));
|
$this->assertEquals(101, $sequenceGenerator->getLastNumberFor($sequenceGenerator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "digicomp/sequence",
|
"name": "digicomp/sequence",
|
||||||
"type": "typo3-flow-package",
|
"type": "neos-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",
|
||||||
"keywords": ["flow", "neos", "doctrine", "sequence"],
|
"keywords": [
|
||||||
|
"flow",
|
||||||
|
"neos",
|
||||||
|
"doctrine",
|
||||||
|
"sequence"
|
||||||
|
],
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Ferdinand Kuhl",
|
"name": "Ferdinand Kuhl",
|
||||||
|
@ -14,20 +19,21 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://github.com/digicomp/DigiComp.Sequence",
|
"homepage": "https://github.com/digicomp/DigiComp.Sequence",
|
||||||
"require": {
|
"require": {
|
||||||
"typo3/flow": "~2.0|~3.0"
|
"neos/flow": "~4.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "3.7.*",
|
"phpunit/phpunit": "3.7.*",
|
||||||
"ext-pcntl": "*"
|
"ext-pcntl": "*"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {
|
"psr-4": {
|
||||||
"DigiComp\\Sequence": "Classes"
|
"DigiComp\\Sequence\\": "Classes"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "1.1.x-dev"
|
"dev-master": "1.1.x-dev",
|
||||||
|
"dev-feature/neos-flow4": "2.0.x-dev"
|
||||||
},
|
},
|
||||||
"applied-flow-migrations": [
|
"applied-flow-migrations": [
|
||||||
"Inwebs.Basket-201409170938",
|
"Inwebs.Basket-201409170938",
|
||||||
|
@ -44,7 +50,22 @@
|
||||||
"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"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue