diff --git a/src/Libs/Mappers/Import/MemoryMapper.php b/src/Libs/Mappers/Import/MemoryMapper.php index 3c0faa8f..a4a317cb 100644 --- a/src/Libs/Mappers/Import/MemoryMapper.php +++ b/src/Libs/Mappers/Import/MemoryMapper.php @@ -46,13 +46,7 @@ final class MemoryMapper implements ImportInterface public function loadData(DateTimeInterface|null $date = null): self { - if (!empty($this->objects)) { - return $this; - } - - if (null === $date) { - $this->fullyLoaded = true; - } + $this->fullyLoaded = null === $date; foreach ($this->storage->getAll($date, $this->options['class'] ?? null) as $entity) { if (null !== ($this->objects[$entity->id] ?? null)) { @@ -65,16 +59,6 @@ final class MemoryMapper implements ImportInterface return $this; } - public function getObjects(array $opts = []): array - { - return $this->objects; - } - - public function getObjectsCount(): int - { - return count($this->objects); - } - public function add(string $bucket, string $name, StateInterface $entity, array $opts = []): self { if (!$entity->hasGuids()) { @@ -152,17 +136,6 @@ final class MemoryMapper implements ImportInterface return $this; } - public function commit(): mixed - { - $state = $this->storage->commit( - array_intersect_key($this->objects, $this->changed) - ); - - $this->reset(); - - return $state; - } - public function get(StateInterface $entity): null|StateInterface { foreach ($entity->getPointers() as $key) { @@ -185,11 +158,6 @@ final class MemoryMapper implements ImportInterface return null; } - public function has(StateInterface $entity): bool - { - return null !== $this->get($entity); - } - public function remove(StateInterface $entity): bool { if (false === ($pointer = $this->getPointer($entity))) { @@ -206,16 +174,47 @@ final class MemoryMapper implements ImportInterface unset($this->objects[$pointer]); + if (null !== ($this->changed[$pointer] ?? null)) { + unset($this->changed[$pointer]); + } + return true; } + public function commit(): mixed + { + $state = $this->storage->commit( + array_intersect_key($this->objects, $this->changed) + ); + + $this->reset(); + + return $state; + } + + public function has(StateInterface $entity): bool + { + return null !== $this->get($entity); + } + public function reset(): self { + $this->fullyLoaded = false; $this->objects = $this->changed = $this->guids = []; return $this; } + public function getObjects(array $opts = []): array + { + return $this->objects; + } + + public function getObjectsCount(): int + { + return count($this->objects); + } + public function count(): int { return count($this->changed); @@ -265,4 +264,11 @@ final class MemoryMapper implements ImportInterface $this->guids[$key] = $pointer; } } + + public function __destruct() + { + if (false === ($this->options['disable_autocommit'] ?? false) && $this->count() >= 1) { + $this->commit(); + } + } } diff --git a/src/Libs/Mappers/ImportInterface.php b/src/Libs/Mappers/ImportInterface.php index 7a41d231..7ffe8a45 100644 --- a/src/Libs/Mappers/ImportInterface.php +++ b/src/Libs/Mappers/ImportInterface.php @@ -43,13 +43,6 @@ interface ImportInterface extends Countable */ public function add(string $bucket, string $name, StateInterface $entity, array $opts = []): self; - /** - * Commit Entities to storage backend. - * - * @return mixed - */ - public function commit(): mixed; - /** * Get Entity. * @@ -59,6 +52,22 @@ interface ImportInterface extends Countable */ public function get(StateInterface $entity): null|StateInterface; + /** + * Remove Entity. + * + * @param StateInterface $entity + * + * @return bool + */ + public function remove(StateInterface $entity): bool; + + /** + * Commit Entities to storage backend. + * + * @return mixed + */ + public function commit(): mixed; + /** * Has Entity. * @@ -68,14 +77,6 @@ interface ImportInterface extends Countable */ public function has(StateInterface $entity): bool; - /** - * Remove Entity. - * - * @param StateInterface $entity - * - * @return bool - */ - public function remove(StateInterface $entity): bool; /** * Reset Mapper State. diff --git a/tests/Mappers/Import/MemoryMapperTest.php b/tests/Mappers/Import/MemoryMapperTest.php index c5a82a3e..08783bb6 100644 --- a/tests/Mappers/Import/MemoryMapperTest.php +++ b/tests/Mappers/Import/MemoryMapperTest.php @@ -77,6 +77,7 @@ class MemoryMapperTest extends TestCase $this->assertSame(2, $this->mapper->getObjectsCount()); } + public function test_loadData_date_conditions(): void { $time = time(); @@ -132,6 +133,134 @@ class MemoryMapperTest extends TestCase ], $this->mapper->commit() ); + $this->assertCount(0, $this->mapper); } + + public function test_get_conditions(): void + { + $testMovie = new StateEntity($this->testMovie); + $testEpisode = new StateEntity($this->testEpisode); + + // -- expect null as we haven't added anything to db yet. + $this->assertNull($this->mapper->get($testEpisode)); + + $this->storage->commit([$testEpisode, $testMovie]); + + clone $testMovie2 = $testMovie; + clone $testEpisode2 = $testEpisode; + $testMovie2->id = 2; + $testEpisode2->id = 1; + + $this->assertSame($testEpisode2->getAll(), $this->mapper->get($testEpisode)->getAll()); + $this->assertSame($testMovie2->getAll(), $this->mapper->get($testMovie)->getAll()); + } + + public function test_get_fully_loaded_conditions(): void + { + $time = time(); + + $testMovie = new StateEntity($this->testMovie); + $testEpisode = new StateEntity($this->testEpisode); + $testEpisode->updated = $time; + + $this->mapper->loadData(); + + $this->storage->commit([$testEpisode, $testMovie]); + + $this->assertNull($this->mapper->get($testMovie)); + $this->assertNull($this->mapper->get($testEpisode)); + + $this->mapper->loadData(makeDate($time - 1)); + $this->assertInstanceOf(StateInterface::class, $this->mapper->get($testEpisode)); + } + + public function test_commit_conditions(): void + { + $testMovie = new StateEntity($this->testMovie); + $testEpisode = new StateEntity($this->testEpisode); + + $this->mapper->add('test', 'movie', $testMovie) + ->add('test', 'episode', $testEpisode); + + $this->assertSame( + [ + StateInterface::TYPE_MOVIE => ['added' => 1, 'updated' => 0, 'failed' => 0], + StateInterface::TYPE_EPISODE => ['added' => 1, 'updated' => 0, 'failed' => 0], + ], + $this->mapper->commit() + ); + + $testMovie->guid_anidb = StateInterface::TYPE_MOVIE . '/1'; + $testEpisode->guid_anidb = StateInterface::TYPE_EPISODE . '/1'; + + $this->assertSame( + [ + StateInterface::TYPE_MOVIE => ['added' => 0, 'updated' => 1, 'failed' => 0], + StateInterface::TYPE_EPISODE => ['added' => 0, 'updated' => 1, 'failed' => 0], + ], + $this->mapper->add('test', 'movie', $testMovie)->add('test', 'episode', $testEpisode)->commit() + ); + } + + public function test_remove_conditions(): void + { + $testMovie = new StateEntity($this->testMovie); + $testEpisode = new StateEntity($this->testEpisode); + + $this->assertFalse($this->mapper->remove($testEpisode)); + $this->mapper->add('test', 'episode', $testEpisode)->add('test', 'movie', $testMovie)->commit(); + $this->assertTrue($this->mapper->remove($testEpisode)); + } + + public function test_has_conditions(): void + { + $testEpisode = new StateEntity($this->testEpisode); + $this->assertFalse($this->mapper->has($testEpisode)); + $this->storage->commit([$testEpisode]); + $this->assertTrue($this->mapper->has($testEpisode)); + } + + public function test_has_fully_loaded_conditions(): void + { + $time = time(); + + $testMovie = new StateEntity($this->testMovie); + $testEpisode = new StateEntity($this->testEpisode); + $testEpisode->updated = $time; + + $this->mapper->loadData(); + $this->storage->commit([$testEpisode, $testMovie]); + $this->assertFalse($this->mapper->has($testEpisode)); + $this->mapper->loadData(makeDate($time - 1)); + $this->assertTrue($this->mapper->has($testEpisode)); + } + + public function test_reset_conditions(): void + { + $testEpisode = new StateEntity($this->testEpisode); + $this->assertCount(0, $this->mapper); + + $this->mapper->add('test', 'episode', $testEpisode); + $this->assertCount(1, $this->mapper); + + $this->mapper->reset(); + $this->assertCount(0, $this->mapper); + } + + public function test_getObjects_conditions(): void + { + $testMovie = new StateEntity($this->testMovie); + $testEpisode = new StateEntity($this->testEpisode); + + $this->assertCount(0, $this->mapper->getObjects()); + + $this->storage->commit([$testMovie, $testEpisode]); + + $this->mapper->loadData(); + + $this->assertCount(2, $this->mapper->getObjects()); + $this->assertCount(0, $this->mapper->reset()->getObjects()); + } + }