Merge branch 'release/3.0.0'

This commit is contained in:
Merten Koch 2017-08-28 16:46:06 +02:00
commit 4ecdd6272c
11 changed files with 190 additions and 162 deletions

View 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
}

View file

@ -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
}

View file

@ -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
{
}

View file

@ -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,29 +14,36 @@ 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;
/** /**
* @param int $number * @param int $number
* @param string|object $type * @param string|object $type
*/ */
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;
}
} }

View file

@ -0,0 +1,12 @@
<?php
namespace DigiComp\Sequence\Service;
use Neos\Flow\Annotations as Flow;
/**
* SequenceException
*/
class Exception extends \Exception
{
}

View file

@ -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;
} }
} }

View file

@ -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'

View file

@ -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;

View file

@ -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;

View file

@ -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));
} }

View file

@ -1,50 +1,71 @@
{ {
"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": [
"authors": [ "flow",
{ "neos",
"name": "Ferdinand Kuhl", "doctrine",
"email": "f.kuhl@digital-competence.de", "sequence"
"homepage": "http://www.digital-competence.de", ],
"role": "Developer" "authors": [
} {
], "name": "Ferdinand Kuhl",
"license": "MIT", "email": "f.kuhl@digital-competence.de",
"homepage": "https://github.com/digicomp/DigiComp.Sequence", "homepage": "http://www.digital-competence.de",
"require": { "role": "Developer"
"typo3/flow": "~2.0|~3.0" }
}, ],
"require-dev": { "license": "MIT",
"phpunit/phpunit": "3.7.*", "homepage": "https://github.com/digicomp/DigiComp.Sequence",
"ext-pcntl": "*" "require": {
}, "neos/flow": "~4.1"
"autoload": {
"psr-0": {
"DigiComp\\Sequence": "Classes"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}, },
"applied-flow-migrations": [ "require-dev": {
"Inwebs.Basket-201409170938", "phpunit/phpunit": "3.7.*",
"TYPO3.FLOW3-201201261636", "ext-pcntl": "*"
"TYPO3.Fluid-201205031303", },
"TYPO3.FLOW3-201205292145", "autoload": {
"TYPO3.FLOW3-201206271128", "psr-4": {
"TYPO3.FLOW3-201209201112", "DigiComp\\Sequence\\": "Classes"
"TYPO3.Flow-201209251426", }
"TYPO3.Flow-201211151101", },
"TYPO3.Flow-201212051340", "extra": {
"TYPO3.Flow-201310031523", "branch-alias": {
"TYPO3.Flow-201405111147", "dev-master": "1.1.x-dev",
"TYPO3.Fluid-20141113120800", "dev-feature/neos-flow4": "2.0.x-dev"
"TYPO3.Flow-20141113121400", },
"TYPO3.Fluid-20141121091700", "applied-flow-migrations": [
"TYPO3.Fluid-20150214130800" "Inwebs.Basket-201409170938",
] "TYPO3.FLOW3-201201261636",
} "TYPO3.Fluid-201205031303",
"TYPO3.FLOW3-201205292145",
"TYPO3.FLOW3-201206271128",
"TYPO3.FLOW3-201209201112",
"TYPO3.Flow-201209251426",
"TYPO3.Flow-201211151101",
"TYPO3.Flow-201212051340",
"TYPO3.Flow-201310031523",
"TYPO3.Flow-201405111147",
"TYPO3.Fluid-20141113120800",
"TYPO3.Flow-20141113121400",
"TYPO3.Fluid-20141121091700",
"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"
]
}
} }