Skip to content

Commit

Permalink
Add mapping caching
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi committed Jan 11, 2024
1 parent 613c04b commit e1884c0
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* use `ObjectCacheFactory` to generate `ObjectCache` instances
* Update `MapperFactory` to reflect framework usage
* Use property info caching in non-framework usage
* Add mapping caching

## 0.5.2

Expand Down
9 changes: 9 additions & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Rekalogika\Mapper\MainTransformer;
use Rekalogika\Mapper\Mapper;
use Rekalogika\Mapper\MapperInterface;
use Rekalogika\Mapper\Mapping\CachingMappingFactory;
use Rekalogika\Mapper\Mapping\MappingFactory;
use Rekalogika\Mapper\Mapping\MappingFactoryInterface;
use Rekalogika\Mapper\ObjectCache\ObjectCacheFactory;
Expand Down Expand Up @@ -148,6 +149,14 @@
$services
->alias(MappingFactoryInterface::class, 'rekalogika.mapper.mapping_factory');

$services
->set('rekalogika.mapper.mapping_factory.caching', CachingMappingFactory::class)
->decorate('rekalogika.mapper.mapping_factory')
->args([
service('rekalogika.mapper.mapping_factory.caching.inner'),
service('kernel')
]);

# other services

$services
Expand Down
83 changes: 83 additions & 0 deletions src/Mapping/CachingMappingFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Mapping;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\VarExporter\VarExporter;

final class CachingMappingFactory implements
MappingFactoryInterface,
CacheWarmerInterface
{
private ?Mapping $innerMappingCache = null;

public function __construct(
private MappingFactoryInterface $realMappingFactory,
private KernelInterface $kernel,
) {
}

private function getMappingFromInnerFactory(): Mapping
{
if ($this->innerMappingCache === null) {
$this->innerMappingCache = $this->realMappingFactory->getMapping();
}

return $this->innerMappingCache;
}

private function warmUpAndGetMapping(): Mapping
{
$this->warmUp($this->kernel->getCacheDir(), $this->kernel->getBuildDir());

return $this->getMappingFromInnerFactory();
}

public function getMapping(): Mapping
{
if (!file_exists($this->getCacheFilePath())) {
return $this->warmUpAndGetMapping();
}

/** @psalm-suppress UnresolvableInclude */
$result = require $this->getCacheFilePath();

if (!$result instanceof Mapping) {
unlink($this->getCacheFilePath());

return $this->warmUpAndGetMapping();
}

return $result;
}

public function isOptional(): bool
{
return true;
}

public function getCacheFilePath(): string
{
return $this->kernel->getBuildDir() . '/rekalogika_mapper_mapping.php';
}

public function warmUp(string $cacheDir, ?string $buildDir = null): array
{
$mapping = VarExporter::export($this->realMappingFactory->getMapping());
file_put_contents($this->getCacheFilePath(), '<?php return ' . $mapping . ';');

return [];
}
}

0 comments on commit e1884c0

Please sign in to comment.