Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.50% covered (warning)
87.50%
21 / 24
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
AddIndexesCodeGenerator
87.50% covered (warning)
87.50%
21 / 24
66.67% covered (warning)
66.67%
2 / 3
7.10
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 boot
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 postRun
85.00% covered (warning)
85.00%
17 / 20
0.00% covered (danger)
0.00%
0 / 1
4.05
1<?php
2namespace Apie\StorageMetadataBuilder\CodeGenerators;
3
4use Apie\StorageMetadata\Attributes\ManyToOneAttribute;
5use Apie\StorageMetadata\Attributes\OneToManyAttribute;
6use Apie\StorageMetadataBuilder\Concerns\HasIndexes;
7use Apie\StorageMetadataBuilder\Factories\ClassTypeFactory;
8use Apie\StorageMetadataBuilder\Interfaces\BootGeneratedCodeInterface;
9use Apie\StorageMetadataBuilder\Interfaces\HasIndexInterface;
10use Apie\StorageMetadataBuilder\Interfaces\PostRunGeneratedCodeContextInterface;
11use Apie\StorageMetadataBuilder\Interfaces\RootObjectInterface;
12use Apie\StorageMetadataBuilder\Mediators\GeneratedCode;
13use Apie\StorageMetadataBuilder\Mediators\GeneratedCodeContext;
14use Nette\PhpGenerator\ClassType;
15
16/**
17 * Adds a single index table for all tables to be able to do text searches.
18 * - creates a global apie_index_table table
19 * - for every root object add HasIndexes trait and HasIndexInterface
20 * - for every root object add a nullable property in apie_index_table to reference this table.
21 */
22class AddIndexesCodeGenerator implements BootGeneratedCodeInterface, PostRunGeneratedCodeContextInterface
23{
24    public function __construct(
25        private readonly bool $singleIndexTable = true
26    ) {
27    }
28
29    public function boot(GeneratedCode $generatedCode): void
30    {
31        if ($this->singleIndexTable) {
32            $class = ClassTypeFactory::createIndexTable('apie_index_table');
33            $generatedCode->generatedCodeHashmap['apie_index_table'] = $class;
34        }
35    }
36    public function postRun(GeneratedCodeContext $generatedCodeContext): void
37    {
38        if ($this->singleIndexTable) {
39            $indexTable = $generatedCodeContext->generatedCode->generatedCodeHashmap['apie_index_table'] ?? null;
40        }
41        assert($indexTable instanceof ClassType);
42        foreach ($generatedCodeContext->generatedCode->generatedCodeHashmap->getObjectsWithInterface(RootObjectInterface::class) as $code) {
43            if (!$this->singleIndexTable) {
44                $indexName = str_replace('apie_resource__', 'apie_index__', $code->getName());
45                $indexTable = ClassTypeFactory::createIndexTable($indexName);
46                $generatedCodeContext->generatedCode->generatedCodeHashmap[$indexName] = $indexTable;
47            }
48            $code->addTrait('\\' . HasIndexes::class);
49            $code->addImplement(HasIndexInterface::class);
50            $code->addMethod('getIndexTable')
51                ->setStatic(true)
52                ->setReturnType('ReflectionClass')
53                ->setBody('return new \\ReflectionClass(' . $indexTable->getName() . '::class);');
54            $code->addProperty('_indexes')
55                ->setType('array')
56                ->addAttribute(OneToManyAttribute::class, [null, $indexTable->getName()]);
57            $indexTable->addProperty('ref_' . $code->getName(), null)
58                ->setType('?' . $code->getName())
59                ->addAttribute(ManyToOneAttribute::class, ['_indexes']);
60        }
61    }
62}