From 8974c76bf69c385019e6106beb371adc1738dba7 Mon Sep 17 00:00:00 2001 From: Aztech Date: Thu, 23 Jul 2015 22:39:23 +0200 Subject: [PATCH] Refactor TimeGeneratorInterface - Remove UuidFactory from signature - Remove setters on UuidFactory to prevent inconsistencies (a new feature set and factory should be used instead) - Update tests to reflect those changes --- src/BinaryUtils.php | 36 ++++++++++++ src/FeatureSet.php | 12 +++- src/Generator/DefaultTimeGenerator.php | 46 ++++++++++++--- src/Generator/PeclUuidRandomGenerator.php | 2 - src/Generator/PeclUuidTimeGenerator.php | 4 +- src/Generator/TimeGeneratorFactory.php | 20 ++++++- src/Generator/TimeGeneratorInterface.php | 5 +- src/UuidFactory.php | 53 ++--------------- tests/UuidTest.php | 70 +++++++++++++++++------ 9 files changed, 160 insertions(+), 88 deletions(-) create mode 100644 src/BinaryUtils.php diff --git a/src/BinaryUtils.php b/src/BinaryUtils.php new file mode 100644 index 0000000..1b40a30 --- /dev/null +++ b/src/BinaryUtils.php @@ -0,0 +1,36 @@ +codec = $this->buildCodec($useGuids); $this->nodeProvider = $this->buildNodeProvider(); $this->randomGenerator = $this->buildRandomGenerator(); - $this->timeGenerator = $this->buildTimeGenerator(); $this->timeConverter = $this->buildTimeConverter(); $this->timeProvider = new SystemTimeProvider(); + // Called last as TimeGeneratorFactory requires nodeProvider, timeConverter, and timeProvider to be available + $this->timeGenerator = $this->buildTimeGenerator(); } public function getBuilder() @@ -121,6 +123,12 @@ class FeatureSet return $this->timeProvider; } + public function setTimeProvider(TimeProviderInterface $timeProvider) + { + $this->timeProvider = $timeProvider; + $this->timeGenerator = $this->buildTimeGenerator(); + } + protected function buildCodec($useGuids = false) { if ($useGuids) { @@ -158,7 +166,7 @@ class FeatureSet protected function buildTimeGenerator() { - return (new TimeGeneratorFactory())->getGenerator(); + return (new TimeGeneratorFactory($this))->getGenerator(); } protected function buildTimeConverter() diff --git a/src/Generator/DefaultTimeGenerator.php b/src/Generator/DefaultTimeGenerator.php index 2f1da7f..9664566 100644 --- a/src/Generator/DefaultTimeGenerator.php +++ b/src/Generator/DefaultTimeGenerator.php @@ -14,13 +14,41 @@ namespace Ramsey\Uuid\Generator; -use Ramsey\Uuid\UuidFactory; +use Ramsey\Uuid\BinaryUtils; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Provider\TimeProviderInterface; class DefaultTimeGenerator implements TimeGeneratorInterface { - public function generate(UuidFactory $factory, $node = null, $clockSeq = null) + /** + * @var NodeProviderInterface + */ + private $nodeProvider; + + /** + * @var TimeConverterInterface + */ + private $timeConverter; + + /** + * @var TimeProviderInterface + */ + private $timeProvider; + + public function __construct( + NodeProviderInterface $nodeProvider, + TimeConverterInterface $timeConverter, + TimeProviderInterface $timeProvider + ) { + $this->nodeProvider = $nodeProvider; + $this->timeConverter = $timeConverter; + $this->timeProvider = $timeProvider; + } + + public function generate($node = null, $clockSeq = null) { - $node = $this->getValidNode($node, $factory); + $node = $this->getValidNode($node); if ($clockSeq === null) { // Not using "stable storage"; see RFC 4122, Section 4.2.1.1 @@ -29,11 +57,11 @@ class DefaultTimeGenerator implements TimeGeneratorInterface // Create a 60-bit time value as a count of 100-nanosecond intervals // since 00:00:00.00, 15 October 1582 - $timeOfDay = $factory->getTimeProvider()->currentTime(); - $uuidTime = $factory->getTimeConverter()->calculateTime($timeOfDay['sec'], $timeOfDay['usec']); + $timeOfDay = $this->timeProvider->currentTime(); + $uuidTime = $this->timeConverter->calculateTime($timeOfDay['sec'], $timeOfDay['usec']); - $timeHi = $factory->applyVersion($uuidTime['hi'], 1); - $clockSeqHi = $factory->applyVariant($clockSeq >> 8); + $timeHi = BinaryUtils::applyVersion($uuidTime['hi'], 1); + $clockSeqHi = BinaryUtils::applyVariant($clockSeq >> 8); $hex = vsprintf( '%08s%04s%04s%02s%02s%012s', @@ -50,10 +78,10 @@ class DefaultTimeGenerator implements TimeGeneratorInterface return hex2bin($hex); } - protected function getValidNode($node, UuidFactory $factory) + protected function getValidNode($node) { if ($node === null) { - $node = $factory->getNodeProvider()->getNode(); + $node = $this->nodeProvider->getNode(); } // Convert the node to hex, if it is still an integer diff --git a/src/Generator/PeclUuidRandomGenerator.php b/src/Generator/PeclUuidRandomGenerator.php index b31c8f9..0c87df0 100644 --- a/src/Generator/PeclUuidRandomGenerator.php +++ b/src/Generator/PeclUuidRandomGenerator.php @@ -14,8 +14,6 @@ namespace Ramsey\Uuid\Generator; -use Ramsey\Uuid\UuidFactory; - class PeclUuidRandomGenerator implements RandomGeneratorInterface { public function generate($length) diff --git a/src/Generator/PeclUuidTimeGenerator.php b/src/Generator/PeclUuidTimeGenerator.php index 974d8cf..eafec44 100644 --- a/src/Generator/PeclUuidTimeGenerator.php +++ b/src/Generator/PeclUuidTimeGenerator.php @@ -14,11 +14,9 @@ namespace Ramsey\Uuid\Generator; -use Ramsey\Uuid\UuidFactory; - class PeclUuidTimeGenerator implements TimeGeneratorInterface { - public function generate(UuidFactory $factory, $node = null, $clockSeq = null) + public function generate($node = null, $clockSeq = null) { $uuid = uuid_create(UUID_TYPE_TIME); diff --git a/src/Generator/TimeGeneratorFactory.php b/src/Generator/TimeGeneratorFactory.php index 5b885d3..c2ba9bf 100644 --- a/src/Generator/TimeGeneratorFactory.php +++ b/src/Generator/TimeGeneratorFactory.php @@ -14,10 +14,26 @@ namespace Ramsey\Uuid\Generator; +use Ramsey\Uuid\FeatureSet; + class TimeGeneratorFactory { - public static function getGenerator() + /** + * @var FeatureSet + */ + private $featureSet; + + public function __construct(FeatureSet $featureSet) { - return new DefaultTimeGenerator(); + $this->featureSet = $featureSet; + } + + public function getGenerator() + { + return new DefaultTimeGenerator( + $this->featureSet->getNodeProvider(), + $this->featureSet->getTimeConverter(), + $this->featureSet->getTimeProvider() + ); } } diff --git a/src/Generator/TimeGeneratorInterface.php b/src/Generator/TimeGeneratorInterface.php index e912ca1..e47a246 100644 --- a/src/Generator/TimeGeneratorInterface.php +++ b/src/Generator/TimeGeneratorInterface.php @@ -14,8 +14,6 @@ namespace Ramsey\Uuid\Generator; -use Ramsey\Uuid\UuidFactory; - interface TimeGeneratorInterface { /** @@ -25,7 +23,6 @@ interface TimeGeneratorInterface * address. If $clockSeq is given, it is used as the sequence number; * otherwise a random 14-bit sequence number is chosen. * - * @param UuidFactory $factory * @param int|string $node A 48-bit number representing the hardware address * This number may be represented as an integer or a hexadecimal string. * @param int $clockSeq A 14-bit number used to help avoid duplicates that @@ -33,5 +30,5 @@ interface TimeGeneratorInterface * changes. * @return string A 16-byte binary string representing a UUID */ - public function generate(UuidFactory $factory, $node = null, $clockSeq = null); + public function generate($node = null, $clockSeq = null); } diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 0720dfc..ff70403 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -55,7 +55,7 @@ class UuidFactory implements UuidFactoryInterface */ private $timeGenerator = null; - /** + /* * * @var TimeConverterInterface */ @@ -75,7 +75,7 @@ class UuidFactory implements UuidFactoryInterface /** * Create a new a instance - * + * @param FeatureSet $features */ public function __construct(FeatureSet $features = null) { @@ -121,36 +121,16 @@ class UuidFactory implements UuidFactoryInterface return $this->timeConverter; } - public function setTimeConverter(TimeConverterInterface $converter) - { - $this->timeConverter = $converter; - } - public function getTimeProvider() { return $this->timeProvider; } - public function setTimeProvider(TimeProviderInterface $provider) - { - $this->timeProvider = $provider; - } - public function setRandomGenerator(RandomGeneratorInterface $generator) { $this->randomGenerator = $generator; } - public function setTimeGenerator(TimeGeneratorInterface $generator) - { - $this->timeGenerator = $generator; - } - - public function setNodeProvider(NodeProviderInterface $provider) - { - $this->nodeProvider = $provider; - } - public function setNumberConverter(NumberConverterInterface $converter) { $this->numberConverter = $converter; @@ -211,7 +191,7 @@ class UuidFactory implements UuidFactoryInterface */ public function uuid1($node = null, $clockSeq = null) { - $bytes = $this->timeGenerator->generate($this, $node, $clockSeq); + $bytes = $this->timeGenerator->generate($node, $clockSeq); $hex = bin2hex($bytes); return $this->uuidFromHashedName($hex, 1); @@ -266,29 +246,6 @@ class UuidFactory implements UuidFactoryInterface return $this->uuidBuilder->build($this->codec, $fields); } - public function applyVariant($clockSeqHi) - { - // Set the variant to RFC 4122 - $clockSeqHi = $clockSeqHi & 0x3f; - $clockSeqHi &= ~(0xc0); - $clockSeqHi |= 0x80; - - return $clockSeqHi; - } - - /** - * @param string $timeHi - * @param integer $version - */ - public function applyVersion($timeHi, $version) - { - $timeHi = hexdec($timeHi) & 0x0fff; - $timeHi &= ~(0xf000); - $timeHi |= $version << 12; - - return $timeHi; - } - /** * @param string $name * @param integer $version @@ -315,8 +272,8 @@ class UuidFactory implements UuidFactoryInterface */ protected function uuidFromHashedName($hash, $version) { - $timeHi = $this->applyVersion(substr($hash, 12, 4), $version); - $clockSeqHi = $this->applyVariant(hexdec(substr($hash, 16, 2))); + $timeHi = BinaryUtils::applyVersion(substr($hash, 12, 4), $version); + $clockSeqHi = BinaryUtils::applyVariant(hexdec(substr($hash, 16, 2))); $fields = array( 'time_low' => substr($hash, 0, 8), diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 4d5109b..9eb170f 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -937,8 +937,11 @@ class UuidTest extends TestCase 'dsttime' => 0, )); + $featureSet = new FeatureSet(); + $featureSet->setTimeProvider($timeOfDay); + // For usec = 277885 - Uuid::getFactory()->setTimeProvider($timeOfDay); + Uuid::setFactory(new UuidFactory($featureSet)); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); @@ -970,7 +973,6 @@ class UuidTest extends TestCase public function testCalculateUuidTimeForce32BitPath() { $this->skipIfNoMoontoastMath(); - Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); $timeOfDay = new FixedTimeProvider(array( 'sec' => 1348845514, @@ -979,8 +981,12 @@ class UuidTest extends TestCase 'dsttime' => 0, )); + $featureSet = new FeatureSet(false, true); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); + // For usec = 277885 - Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); @@ -1021,7 +1027,10 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - Uuid::getFactory()->setTimeProvider($timeOfDay); + $featureSet = new FeatureSet(); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); @@ -1037,7 +1046,9 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - Uuid::getFactory()->setTimeProvider($timeOfDay); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); @@ -1056,7 +1067,7 @@ class UuidTest extends TestCase $this->skipIfNoMoontoastMath(); $this->skip64BitTest(); - Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $featureSet = new FeatureSet(false, true); // 5235-03-31T21:20:59+00:00 $timeOfDay = new FixedTimeProvider(array( @@ -1066,7 +1077,10 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - Uuid::getFactory()->setTimeProvider($timeOfDay); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); + $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); @@ -1082,7 +1096,10 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - Uuid::getFactory()->setTimeProvider($timeOfDay); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); + $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); @@ -1096,7 +1113,6 @@ class UuidTest extends TestCase public function testCalculateUuidTimeUpperLowerBounds32Bit() { $this->skipIfNoMoontoastMath(); - Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); // 2038-01-19T03:14:07+00:00 $timeOfDay = new FixedTimeProvider(array( @@ -1106,7 +1122,11 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - Uuid::getFactory()->setTimeProvider($timeOfDay); + $featureSet = new FeatureSet(false, true); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); + $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('13813ff6-6912-11fe-9669-00007ffffffe', (string) $uuidA); @@ -1122,7 +1142,10 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - Uuid::getFactory()->setTimeProvider($timeOfDay); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); + $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('1419d680-d292-1165-9669-00007ffffffe', (string) $uuidB); @@ -1148,7 +1171,11 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - Uuid::getFactory()->setTimeProvider($timeOfDay); + $featureSet = new FeatureSet(); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); + $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('13813ff6-6912-11fe-9669-00007ffffffe', (string) $uuidA); @@ -1164,7 +1191,10 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - Uuid::getFactory()->setTimeProvider($timeOfDay); + $featureSet->setTimeProvider($timeOfDay); + + Uuid::setFactory(new UuidFactory($featureSet)); + ; $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('1419d680-d292-1165-9669-00007ffffffe', (string) $uuidB); @@ -1185,9 +1215,6 @@ class UuidTest extends TestCase $currentTime = strtotime('2012-12-11T00:00:00+00:00'); $endTime = $currentTime + 3600; - $factory = new UuidFactory(); - $smallIntFactory = new UuidFactory(new FeatureSet(false, true)); - $timeOfDay = new FixedTimeProvider(array( 'sec' => $currentTime, 'usec' => 0, @@ -1195,8 +1222,15 @@ class UuidTest extends TestCase 'dsttime' => 0, )); - $factory->setTimeProvider($timeOfDay); - $smallIntFactory->setTimeProvider($timeOfDay); + $smallIntFeatureSet = new FeatureSet(false, true); + $smallIntFeatureSet->setTimeProvider($timeOfDay); + + $smallIntFactory = new UuidFactory($smallIntFeatureSet); + + $featureSet = new FeatureSet(); + $featureSet->setTimeProvider($timeOfDay); + + $factory = new UuidFactory($featureSet); while ($currentTime <= $endTime) {