diff --git a/src/Plugin/Sequence.php b/src/Plugin/Sequence.php index 2a9c81e..4cff6dc 100644 --- a/src/Plugin/Sequence.php +++ b/src/Plugin/Sequence.php @@ -37,28 +37,44 @@ public function initializeSequence(Space $space) $name = $space->getName(); - if (!array_key_exists($name, $this->sequences)) { - [$primaryIndex] = $space->getIndexes(); - if (count($primaryIndex['parts']) !== 1) { - throw new Exception("Composite primary key"); - } - $this->mapper - ->getPlugin(Procedure::class) - ->get(CreateSequence::class) - ->execute($name, $primaryIndex['name'], $primaryIndex['parts'][0][0] + 1); + if (array_key_exists($name, $this->sequences)) { + // sequence exists + return; + } - $this->mapper->getRepository('_vsequence')->flushCache(); + if (array_key_exists($name . '_seq', $this->sequences)) { + // use tarantool standard sequence name + return; + } - $this->sequences[$name] = true; + [$primaryIndex] = $space->getIndexes(); + if (count($primaryIndex['parts']) !== 1) { + throw new Exception("Composite primary key"); } + + $this->mapper + ->getPlugin(Procedure::class) + ->get(CreateSequence::class) + ->execute($name, $primaryIndex['name'], $primaryIndex['parts'][0][0] + 1); + + $this->mapper->getRepository('_vsequence')->flushCache(); + + $this->sequences[$name] = true; } private function generateValue(Space $space): int { $this->initializeSequence($space); - $next = $this->mapper->getClient() - ->call('box.sequence.' . $space->getName() . ':next'); + $name = $space->getName(); + if (!array_key_exists($name, $this->sequences)) { + if (array_key_exists($name . '_seq', $this->sequences)) { + // use tarantool standard sequence name + $name .= '_seq'; + } + } + + $next = $this->mapper->getClient()->call('box.sequence.' . $name . ':next'); return $next[0]; } diff --git a/tests/SequenceTest.php b/tests/SequenceTest.php index e7f86d0..c0cfc8f 100644 --- a/tests/SequenceTest.php +++ b/tests/SequenceTest.php @@ -5,6 +5,50 @@ class SequenceTest extends TestCase { + public function testSequenceIndexing() + { + $mapper = $this->createMapper(); + $this->clean($mapper); + + // no sequences in schema + $this->assertCount(0, $mapper->find('_vsequence')); + + $mapper->getSchema()->createSpace('some_space', [ + 'if_not_exists' => true, + 'engine' => 'memtx', + 'properties' => [ + 'id' => 'unsigned', + 'value' => 'string', + ], + ]) + ->addIndex([ + 'fields' => 'id', + 'if_not_exists' => true, + 'sequence' => true, + ]); + + // sequence was created + $mapper->getRepository('_vsequence')->flushCache(); + $this->assertCount(1, $mapper->find('_vsequence')); + $seq = $mapper->findOne('_vsequence'); + $this->assertSame($seq->name, 'some_space_seq'); + + // no new sequence should be created + $mapper->getPlugin(Sequence::class); + $mapper->getRepository('_vsequence')->flushCache(); + $this->assertCount(1, $mapper->find('_vsequence')); + + $result1 = $mapper->create('some_space', ['value' => 27]); + $result2 = $mapper->create('some_space', ['value' => 42]); + + // no new sequence should be created + $mapper->getRepository('_vsequence')->flushCache(); + $this->assertCount(1, $mapper->find('_vsequence')); + + $this->assertSame($result1->id, 1); + $this->assertSame($result2->id, 2); + } + public function testInstanceOverwriteOnPluginAdd() { $mapper = $this->createMapper();