Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QueryFactory: Cache compute result for findFrom and findFromRaw #180

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"symfony/filesystem": "^2.7 || ^3 || ^4",
"ramsey/uuid": "^3.7",
"doctrine/annotations": "^1.6",
"zendframework/zend-code": "^3.3.1",
"zendframework/zend-code": "^3.4",
"psr/container": "^1",
"ext-PDO": "*",
"ext-json": "*",
Expand Down
20 changes: 11 additions & 9 deletions src/QueryFactory/FindObjectsFromRawSqlQueryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace TheCodingMachine\TDBM\QueryFactory;

use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Schema\Schema;
use TheCodingMachine\TDBM\TDBMException;
Expand Down Expand Up @@ -39,20 +40,17 @@ class FindObjectsFromRawSqlQueryFactory implements QueryFactory
* @var string
*/
private $mainTable;

/**
* FindObjectsFromRawSqlQueryFactory constructor.
* @param TDBMService $tdbmService
* @param Schema $schema
* @param string $mainTable
* @param string $sql
* @param string $sqlCount
* @var Cache
*/
public function __construct(TDBMService $tdbmService, Schema $schema, string $mainTable, string $sql, string $sqlCount = null)
private $cache;

public function __construct(TDBMService $tdbmService, Schema $schema, string $mainTable, string $sql, ?string $sqlCount, Cache $cache)
{
$this->tdbmService = $tdbmService;
$this->schema = $schema;
$this->mainTable = $mainTable;
$this->cache = $cache;

[$this->processedSql, $this->processedSqlCount, $this->columnDescriptors] = $this->compute($sql, $sqlCount);
}
Expand Down Expand Up @@ -85,6 +83,10 @@ public function getColumnDescriptors(): array
*/
private function compute(string $sql, ?string $sqlCount): array
{
$key = 'FindObjectsFromRawSqlQueryFactory_' . dechex(crc32(var_export($sqlCount, true) . $sql));
if ($this->cache->contains($key)) {
return $this->cache->fetch($key);
}
$parser = new PHPSQLParser();
$parsedSql = $parser->parse($sql);

Expand All @@ -95,7 +97,7 @@ private function compute(string $sql, ?string $sqlCount): array
} else {
throw new TDBMException('Unable to analyze query "'.$sql.'"');
}

$this->cache->save($key, [$processedSql, $processedSqlCount, $columnDescriptors]);
return [$processedSql, $processedSqlCount, $columnDescriptors];
}

Expand Down
26 changes: 21 additions & 5 deletions src/QueryFactory/FindObjectsFromSqlQueryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ public function __construct(string $mainTable, string $from, $filterString, $ord

protected function compute(): void
{
$key = 'FindObjectsFromSqlQueryFactory_' . dechex(crc32($this->mainTable.'__'.$this->from.'__'.$this->filterString.'__'.$this->orderBy));
if ($this->cache->contains($key)) {
[
$this->magicSql,
$this->magicSqlCount,
$this->magicSqlSubQuery,
$this->columnDescList
] = $this->cache->fetch($key);
return;
}

// We quote in MySQL because of MagicQuery that will be applied.
$mySqlPlatform = new MySqlPlatform();

Expand Down Expand Up @@ -104,6 +115,13 @@ protected function compute(): void
$this->magicSqlCount = $countSql;
$this->magicSqlSubQuery = $subQuery;
$this->columnDescList = $columnDescList;

$this->cache->save($key, [
$this->magicSql,
$this->magicSqlCount,
$this->magicSqlSubQuery,
$this->columnDescList,
]);
}

/**
Expand Down Expand Up @@ -161,12 +179,10 @@ private function getChildrenRelationshipForeignKeysWithoutCache(string $tableNam
return $this->getChildrenRelationshipForeignKeys($fk->getLocalTableName());
}, $children);

$fks = array_merge($children, call_user_func_array('array_merge', $fksTables));

return $fks;
} else {
return [];
return array_merge($children, ...$fksTables);
}

return [];
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/TDBMService.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\ClearableCache;
use Doctrine\Common\Cache\VoidCache;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
Expand Down Expand Up @@ -1083,9 +1082,11 @@ private function exploreChildrenTablesRelationships(SchemaAnalyzer $schemaAnalyz
$tables = [$table];
$keys = $schemaAnalyzer->getChildrenRelationships($table);

$tmpTables = [];
foreach ($keys as $key) {
$tables = array_merge($tables, $this->exploreChildrenTablesRelationships($schemaAnalyzer, $key->getLocalTableName()));
$tmpTables[] = $this->exploreChildrenTablesRelationships($schemaAnalyzer, $key->getLocalTableName());
}
$tables = array_merge($tables, ...$tmpTables);

return $tables;
}
Expand Down Expand Up @@ -1349,7 +1350,7 @@ public function findObjectsFromRawSql(string $mainTable, string $sql, array $par

$mode = $mode ?: $this->mode;

$queryFactory = new FindObjectsFromRawSqlQueryFactory($this, $this->tdbmSchemaAnalyzer->getSchema(), $mainTable, $sql, $sqlCount);
$queryFactory = new FindObjectsFromRawSqlQueryFactory($this, $this->tdbmSchemaAnalyzer->getSchema(), $mainTable, $sql, $sqlCount, $this->cache);

return $resultIteratorClass::createResultIterator($queryFactory, $parameters, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
}
Expand Down
44 changes: 29 additions & 15 deletions src/Utils/BeanDescriptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,9 @@ private function generateBeanConstructor() : MethodGenerator
$constructorProperties = $this->getConstructorProperties();

$constructor = new MethodGenerator('__construct', [], MethodGenerator::FLAG_PUBLIC);
$constructor->setDocBlock('The constructor takes all compulsory arguments.');
$constructor->getDocBlock()->setWordWrap(false);
$constructorDocBlock = new DocBlockGenerator('The constructor takes all compulsory arguments.');
$constructorDocBlock->setWordWrap(false);
$constructor->setDocBlock($constructorDocBlock);

$assigns = [];
$parentConstructorArguments = [];
Expand All @@ -374,7 +375,7 @@ private function generateBeanConstructor() : MethodGenerator
}
$constructor->setParameter($parameter);

$constructor->getDocBlock()->setTag($property->getParamAnnotation());
$constructorDocBlock->setTag($property->getParamAnnotation());

if ($property->getTable()->getName() === $this->table->getName()) {
$assigns[] = $property->getConstructorAssignCode()."\n";
Expand Down Expand Up @@ -487,9 +488,14 @@ public function generateJsonSerialize(): MethodGenerator
$parentFk = $this->schemaAnalyzer->getParentRelationship($tableName);

$method = new MethodGenerator('jsonSerialize');
$method->setDocBlock('Serializes the object for JSON encoding.');
$method->getDocBlock()->setTag(new ParamTag('$stopRecursion', ['bool'], 'Parameter used internally by TDBM to stop embedded objects from embedding other objects.'));
$method->getDocBlock()->setTag(new ReturnTag(['array']));
$method->setDocBlock(new DocBlockGenerator(
'Serializes the object for JSON encoding.',
null,
[
new ParamTag('$stopRecursion', ['bool'], 'Parameter used internally by TDBM to stop embedded objects from embedding other objects.'),
new ReturnTag(['array'])
]
));
$method->setParameter(new ParameterGenerator('stopRecursion', 'bool', false));

if ($parentFk !== null) {
Expand Down Expand Up @@ -1409,8 +1415,11 @@ private function generateGetUsedTablesCode(): MethodGenerator
}

$method = new MethodGenerator('getUsedTables');
$method->setDocBlock('Returns an array of used tables by this bean (from parent to child relationship).');
$method->getDocBlock()->setTag(new ReturnTag(['string[]']));
$method->setDocBlock(new DocBlockGenerator(
'Returns an array of used tables by this bean (from parent to child relationship).',
null,
[new ReturnTag(['string[]'])]
));
$method->setReturnType('array');
$method->setBody($code);

Expand All @@ -1433,7 +1442,7 @@ private function generateOnDeleteCode(): ?MethodGenerator
}

$method = new MethodGenerator('onDelete');
$method->setDocBlock('Method called when the bean is removed from database.');
$method->setDocBlock(new DocBlockGenerator('Method called when the bean is removed from database.'));
$method->setReturnType('void');
$method->setBody('parent::onDelete();
'.$code);
Expand All @@ -1453,8 +1462,11 @@ private function generateGetManyToManyRelationshipDescriptorCode(array $pivotTab

$method = new MethodGenerator('_getManyToManyRelationshipDescriptor');
$method->setVisibility(AbstractMemberGenerator::VISIBILITY_PUBLIC);
$method->setDocBlock('Get the paths used for many to many relationships methods.');
$method->getDocBlock()->setTag(new GenericTag('internal'));
$method->setDocBlock(new DocBlockGenerator(
'Get the paths used for many to many relationships methods.',
null,
[new GenericTag('internal')]
));
$method->setReturnType(ManyToManyRelationshipPathDescriptor::class);

$parameter = new ParameterGenerator('pathKey');
Expand Down Expand Up @@ -1488,9 +1500,11 @@ private function generateGetManyToManyRelationshipDescriptorKeysCode(array $pivo
$method = new MethodGenerator('_getManyToManyRelationshipDescriptorKeys');
$method->setVisibility(AbstractMemberGenerator::VISIBILITY_PUBLIC);
$method->setReturnType('array');
$method->setDocBlock('Returns the list of keys supported for many to many relationships');
$method->getDocBlock()->setTag(new GenericTag('internal'));
$method->getDocBlock()->setTag(new ReturnTag('string[]'));
$method->setDocBlock(new DocBlockGenerator(
'Returns the list of keys supported for many to many relationships',
null,
[new GenericTag('internal'), new ReturnTag('string[]')]
));

$keys = [];
foreach ($pivotTableMethodsDescriptors as $pivotTableMethodsDescriptor) {
Expand Down Expand Up @@ -1664,7 +1678,7 @@ private function generateGetForeignKeys(array $fks): MethodGenerator
$method = new MethodGenerator('getForeignKeys');
$method->setVisibility(AbstractMemberGenerator::VISIBILITY_PROTECTED);
$method->setStatic(true);
$method->setDocBlock('Internal method used to retrieve the list of foreign keys attached to this bean.');
$method->setDocBlock(new DocBlockGenerator('Internal method used to retrieve the list of foreign keys attached to this bean.'));
$method->setReturnType(ForeignKeys::class);

$parameter = new ParameterGenerator('tableName');
Expand Down
16 changes: 9 additions & 7 deletions src/Utils/DirectForeignKeyMethodDescriptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use TheCodingMachine\TDBM\Utils\Annotation;
use Zend\Code\Generator\AbstractMemberGenerator;
use Zend\Code\Generator\DocBlock\Tag\ReturnTag;
use Zend\Code\Generator\DocBlockGenerator;
use Zend\Code\Generator\MethodGenerator;

/**
Expand Down Expand Up @@ -127,9 +128,11 @@ public function getCode() : array
$getter = new MethodGenerator($this->getName());

if ($this->hasLocalUniqueIndex()) {
$getter->setDocBlock(sprintf('Returns the %s pointing to this bean via the %s column.', $beanClass, implode(', ', $this->foreignKey->getUnquotedLocalColumns())));
$classType = '\\' . $this->beanNamespace . '\\' . $beanClass;
$getter->getDocBlock()->setTag(new ReturnTag([$classType . '|null']))->setWordWrap(false);
$getterDocBlock = new DocBlockGenerator(sprintf('Returns the %s pointing to this bean via the %s column.', $beanClass, implode(', ', $this->foreignKey->getUnquotedLocalColumns())));
$getterDocBlock->setTag([new ReturnTag([$classType . '|null'])]);
$getterDocBlock->setWordWrap(false);
$getter->setDocBlock($getterDocBlock);
$getter->setReturnType('?' . $classType);

$code = sprintf(
Expand All @@ -139,11 +142,10 @@ public function getCode() : array
$this->getFilters($this->foreignKey)
);
} else {
$getter->setDocBlock(sprintf('Returns the list of %s pointing to this bean via the %s column.', $beanClass, implode(', ', $this->foreignKey->getUnquotedLocalColumns())));
$getter->getDocBlock()->setTag(new ReturnTag([
$beanClass . '[]',
'\\' . AlterableResultIterator::class
]))->setWordWrap(false);
$getterDocBlock = new DocBlockGenerator(sprintf('Returns the list of %s pointing to this bean via the %s column.', $beanClass, implode(', ', $this->foreignKey->getUnquotedLocalColumns())));
$getterDocBlock->setTag(new ReturnTag([$beanClass . '[]', '\\' . AlterableResultIterator::class]));
$getterDocBlock->setWordWrap(false);
$getter->setDocBlock($getterDocBlock);
$getter->setReturnType(AlterableResultIterator::class);

$code = sprintf(
Expand Down
5 changes: 3 additions & 2 deletions src/Utils/ObjectBeanPropertyDescriptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use TheCodingMachine\TDBM\Utils\Annotation\AnnotationParser;
use TheCodingMachine\TDBM\Utils\Annotation;
use Zend\Code\Generator\AbstractMemberGenerator;
use Zend\Code\Generator\DocBlockGenerator;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Generator\ParameterGenerator;

Expand Down Expand Up @@ -159,7 +160,7 @@ public function getGetterSetterCode(): array
$referencedBeanName = $this->namingStrategy->getBeanClassName($this->foreignKey->getForeignTableName());

$getter = new MethodGenerator($getterName);
$getter->setDocBlock('Returns the ' . $referencedBeanName . ' object bound to this object via the ' . implode(' and ', $this->foreignKey->getUnquotedLocalColumns()) . ' column.');
$getter->setDocBlock(new DocBlockGenerator('Returns the ' . $referencedBeanName . ' object bound to this object via the ' . implode(' and ', $this->foreignKey->getUnquotedLocalColumns()) . ' column.'));

/*$types = [ $referencedBeanName ];
if ($isNullable) {
Expand All @@ -177,7 +178,7 @@ public function getGetterSetterCode(): array
}

$setter = new MethodGenerator($setterName);
$setter->setDocBlock('The setter for the ' . $referencedBeanName . ' object bound to this object via the ' . implode(' and ', $this->foreignKey->getUnquotedLocalColumns()) . ' column.');
$setter->setDocBlock(new DocBlockGenerator('The setter for the ' . $referencedBeanName . ' object bound to this object via the ' . implode(' and ', $this->foreignKey->getUnquotedLocalColumns()) . ' column.'));

$setter->setParameter(new ParameterGenerator('object', ($isNullable ? '?' : '') . $this->beanNamespace . '\\' . $referencedBeanName));

Expand Down
35 changes: 23 additions & 12 deletions src/Utils/PivotTableMethodsDescriptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Table;
use Zend\Code\Generator\DocBlockGenerator;
use function implode;
use function sprintf;
use TheCodingMachine\TDBM\Utils\Annotation\AnnotationParser;
Expand Down Expand Up @@ -199,39 +200,49 @@ public function getCode() : array
$localTableName = var_export($this->remoteFk->getLocalTableName(), true);

$getter = new MethodGenerator($this->getName());
$getter->setDocBlock(sprintf('Returns the list of %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
$getter->getDocBlock()->setTag(new ReturnTag([ $fqcnRemoteBeanName.'[]' ]))->setWordWrap(false);
$getterDocBlock = new DocBlockGenerator(sprintf('Returns the list of %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
$getterDocBlock->setTag(new ReturnTag([ $fqcnRemoteBeanName.'[]' ]));
$getterDocBlock->setWordWrap(false);
$getter->setDocBlock($getterDocBlock);
$getter->setReturnType('array');
$getter->setBody(sprintf('return $this->_getRelationships(%s);', $pathKey));


$adder = new MethodGenerator('add'.$singularName);
$adder->setDocBlock(sprintf('Adds a relationship with %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
$adder->getDocBlock()->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]))->setWordWrap(false);
$adderDocBlock = new DocBlockGenerator(sprintf('Adds a relationship with %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
$adderDocBlock->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]));
$adderDocBlock->setWordWrap(false);
$adder->setDocBlock($adderDocBlock);
$adder->setReturnType('void');
$adder->setParameter(new ParameterGenerator($variableName, $fqcnRemoteBeanName));
$adder->setBody(sprintf('$this->addRelationship(%s, $%s);', $localTableName, $variableName));

$remover = new MethodGenerator('remove'.$singularName);
$remover->setDocBlock(sprintf('Deletes the relationship with %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
$remover->getDocBlock()->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]))->setWordWrap(false);
$removerDocBlock = new DocBlockGenerator(sprintf('Deletes the relationship with %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
$removerDocBlock->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]));
$removerDocBlock->setWordWrap(false);
$remover->setDocBlock($removerDocBlock);
$remover->setReturnType('void');
$remover->setParameter(new ParameterGenerator($variableName, $fqcnRemoteBeanName));
$remover->setBody(sprintf('$this->_removeRelationship(%s, $%s);', $localTableName, $variableName));

$has = new MethodGenerator('has'.$singularName);
$has->setDocBlock(sprintf('Returns whether this bean is associated with %s via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
$has->getDocBlock()->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]))->setWordWrap(false);
$has->getDocBlock()->setTag(new ReturnTag([ 'bool' ]));
$hasDocBlock = new DocBlockGenerator(sprintf('Returns whether this bean is associated with %s via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
$hasDocBlock->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]));
$hasDocBlock->setTag(new ReturnTag([ 'bool' ]));
$hasDocBlock->setWordWrap(false);
$has->setDocBlock($hasDocBlock);
$has->setReturnType('bool');
$has->setParameter(new ParameterGenerator($variableName, $fqcnRemoteBeanName));
$has->setBody(sprintf('return $this->hasRelationship(%s, $%s);', $pathKey, $variableName));

$setter = new MethodGenerator('set'.$pluralName);
$setter->setDocBlock(sprintf('Sets all relationships with %s associated to this bean via the %s pivot table.
$setterDocBlock = new DocBlockGenerator(sprintf('Sets all relationships with %s associated to this bean via the %s pivot table.
Exiting relationships will be removed and replaced by the provided relationships.', $remoteBeanName, $this->pivotTable->getName()));
$setter->getDocBlock()->setTag(new ParamTag($pluralVariableName, [ $fqcnRemoteBeanName.'[]' ]))->setWordWrap(false)->setWordWrap(false);
$setter->getDocBlock()->setTag(new ReturnTag([ 'void' ]));
$setterDocBlock->setTag(new ParamTag($pluralVariableName, [ $fqcnRemoteBeanName.'[]' ]));
$setterDocBlock->setTag(new ReturnTag([ 'void' ]));
$setterDocBlock->setWordWrap(false);
$setter->setDocBlock($setterDocBlock);
$setter->setReturnType('void');
$setter->setParameter(new ParameterGenerator($pluralVariableName, 'array'));
$setter->setBody(sprintf('$this->setRelationships(%s, $%s);', $pathKey, $pluralVariableName));
Expand Down
Loading