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

load databases without accessing classes #1910

Merged
Show file tree
Hide file tree
Changes from 3 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
80 changes: 52 additions & 28 deletions src/Propel/Generator/Builder/Om/TableMapLoaderScriptBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
use Propel\Common\Util\PathTrait;
use Propel\Generator\Builder\Util\PropelTemplate;
use Propel\Generator\Config\GeneratorConfigInterface;
use Propel\Generator\Exception\BuildException;
use Propel\Generator\Model\Database;
use Propel\Generator\Model\Table;
use Propel\Runtime\Map\DatabaseMap;
use SplFileInfo;

/**
Expand Down Expand Up @@ -46,65 +49,86 @@ public function __construct(GeneratorConfigInterface $generatorConfig)
*/
public function build(array $schemas): string
{
$vars = $this->buildVars($schemas);
$templatePath = $this->getTemplatePath(__DIR__);

$filePath = $templatePath . 'tableMapLoaderScript.php';
$template = new PropelTemplate();
$template->setTemplateFile($filePath);

return $this->renderTemplate($vars);
$vars = [
'databaseNameToTableMapDumps' => $this->buildDatabaseNameToTableMapDumps($schemas),
];

return $template->render($vars);
}

/**
* @param array<\Propel\Generator\Model\Schema> $schemas
*
* @throws \Propel\Generator\Exception\BuildException
*
* @return array
*/
protected function buildVars(array $schemas): array
protected function buildDatabaseNameToTableMapDumps(array $schemas): array
{
$databaseNameToTableMapNames = [];

$entries = [];
foreach ($schemas as $schema) {
foreach ($schema->getDatabases(false) as $database) {
$databaseName = $database->getName();
$tableMapNames = array_map([$this, 'getFullyQualifiedTableMapClassName'], $database->getTables());
if (array_key_exists($databaseName, $databaseNameToTableMapNames)) {
$existing = $databaseNameToTableMapNames[$databaseName];
$tableMapNames = array_merge($existing, $tableMapNames);
if (!$databaseName) {
throw new BuildException('Cannot build table map of unnamed database');
}
sort($tableMapNames);
$databaseNameToTableMapNames[$databaseName] = $tableMapNames;
$tableMapDumps = $this->buildDatabaseMap($database)->dumpMaps();
$entries[] = [$databaseName => $tableMapDumps];
}
}
$databaseNameToTableMapDumps = array_merge_recursive(...$entries);
$this->sortRecursive($databaseNameToTableMapDumps);

return [
'databaseNameToTableMapNames' => $databaseNameToTableMapNames,
];
return $databaseNameToTableMapDumps;
}

/**
* @param \Propel\Generator\Model\Table $table
* @param \Propel\Generator\Model\Database $database
*
* @return string
* @return \Propel\Runtime\Map\DatabaseMap
*/
protected function getFullyQualifiedTableMapClassName(Table $table): string
protected function buildDatabaseMap(Database $database): DatabaseMap
{
$builder = new TableMapBuilder($table);
$builder->setGeneratorConfig($this->generatorConfig);
$databaseName = $database->getName();
$databaseMap = new DatabaseMap($databaseName);
foreach ($database->getTables() as $table) {
$tableName = $table->getName();
$phpName = $table->getPhpName();
$tableMapClass = $this->getFullyQualifiedTableMapClassName($table);
$databaseMap->registerTableMapClassByName($tableName, $phpName, $tableMapClass);
}

return $builder->getFullyQualifiedClassName();
return $databaseMap;
}

/**
* @param array $vars
* @param array $array
*
* @return string
* @return void
*/
protected function renderTemplate(array $vars): string
protected function sortRecursive(array &$array): void
{
$templatePath = $this->getTemplatePath(__DIR__);
ksort($array, SORT_STRING);
array_walk($array, fn (&$value) => is_array($value) && $this->sortRecursive($value));
}

$filePath = $templatePath . 'tableMapLoaderScript.php';
$template = new PropelTemplate();
$template->setTemplateFile($filePath);
/**
* @param \Propel\Generator\Model\Table $table
*
* @return string
*/
protected function getFullyQualifiedTableMapClassName(Table $table): string
{
$builder = new TableMapBuilder($table);
$builder->setGeneratorConfig($this->generatorConfig);

return $template->render($vars);
return $builder->getFullyQualifiedClassName();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Propel/Generator/Manager/AbstractManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use Propel\Generator\Exception\EngineException;
use Propel\Generator\Model\Database;
use Propel\Generator\Model\Schema;
use XsltProcessor;
use XSLTProcessor;

/**
* An abstract base Propel manager to perform work related to the XML schema
Expand Down Expand Up @@ -323,7 +323,7 @@ protected function loadDataModels(): void
// normalize the document using normalizer stylesheet
$xslDom = new DOMDocument('1.0', 'UTF-8');
$xslDom->load($this->xsl->getAbsolutePath());
$xsl = new XsltProcessor();
$xsl = new XSLTProcessor();
$xsl->importStyleSheet($xslDom);
$dom = $xsl->transformToDoc($dom);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Propel/Generator/Model/Table.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<?php

declare(strict_types=1);

/**
* MIT License. This file is part of the Propel package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Propel\Generator\Model;

use Propel\Generator\Config\GeneratorConfigInterface;
Expand Down
4 changes: 3 additions & 1 deletion src/Propel/Generator/Util/QuickBuilder.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php declare(strict_types = 1);
<?php

/**
* MIT License. This file is part of the Propel package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Propel\Generator\Util;

use Exception;
Expand Down
4 changes: 3 additions & 1 deletion src/Propel/Generator/Util/VfsTrait.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php declare(strict_types = 1);
<?php

/**
* MIT License. This file is part of the Propel package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Propel\Generator\Util;

use org\bovigo\vfs\vfsStream;
Expand Down
2 changes: 1 addition & 1 deletion src/Propel/Runtime/Connection/ConnectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static function create(
): ConnectionInterface {
if (static::$useProfilerConnection) {
$connectionClass = ProfilerConnectionWrapper::class;
} else if (isset($configuration['classname'])) {
} elseif (isset($configuration['classname'])) {
$connectionClass = $configuration['classname'];
} else {
$connectionClass = $defaultConnectionClass;
Expand Down
68 changes: 62 additions & 6 deletions src/Propel/Runtime/Map/DatabaseMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
* @author Hans Lellelid <hans@xmpl.org> (Propel)
* @author John D. McNally <jmcnally@collab.net> (Torque)
* @author Daniel Rall <dlr@collab.net> (Torque)
*
* @psalm-consistent-constructor (instantiated by class name in StandardServiceContainer without arguments)
*
* @psalm-type \Propel\Runtime\Map\MapType = 'tablesByName' | 'tablesByPhpName'
* @psalm-type \Propel\Runtime\Map\TableMapDump array<\Propel\Runtime\Map\MapType, array<string, class-string<\Propel\Runtime\Map\TableMap>>>
*/
class DatabaseMap
{
Expand All @@ -38,14 +43,14 @@ class DatabaseMap
/**
* Tables in the database, using table name as key
*
* @var array<\Propel\Runtime\Map\TableMap|class-string<\Propel\Runtime\Map\TableMap>>
* @var array<string, \Propel\Runtime\Map\TableMap|class-string<\Propel\Runtime\Map\TableMap>>
*/
protected $tables = [];

/**
* Tables in the database, using table phpName as key
*
* @var array<\Propel\Runtime\Map\TableMap|class-string<\Propel\Runtime\Map\TableMap>>
* @var array<string, \Propel\Runtime\Map\TableMap|class-string<\Propel\Runtime\Map\TableMap>>
*/
protected $tablesByPhpName = [];

Expand Down Expand Up @@ -121,7 +126,7 @@ protected function addTableByPhpName(?string $phpName, $tableOrClassMap): void
/**
* Add a new table to the database, using the tablemap class name.
*
* @param string $tableMapClass The name of the table map to add
* @param class-string<\Propel\Runtime\Map\TableMap> $tableMapClass The name of the table map to add
*
* @return \Propel\Runtime\Map\TableMap The TableMap object
*/
Expand All @@ -134,6 +139,38 @@ public function addTableFromMapClass(string $tableMapClass): TableMap
return $this->getTable($table->getName());
}

/**
* Dump table maps. Used during configuration generation.
*
* @return \Propel\Runtime\Map\TableMapDump A dump that can be loaded again with {@link DatabaseMap::loadMapsFromDump()}
dereuromark marked this conversation as resolved.
Show resolved Hide resolved
*/
public function dumpMaps(): array
{
/**
* @param $tableMap class-string<\Propel\Runtime\Map\TableMap>|\Propel\Runtime\Map\TableMap
* @return class-string<\Propel\Runtime\Map\TableMap>
*/
$toClassString = fn ($tableMap) => is_string($tableMap) ? $tableMap : get_class($tableMap);

return [
'tablesByName' => array_map($toClassString, $this->tables),
'tablesByPhpName' => array_map($toClassString, $this->tablesByPhpName),
];
}

/**
* Load internal table maps from dump. Used during Propel initialization.
*
* @param \Propel\Runtime\Map\TableMapDump|array $mapsDump Table map dump as created by {@link DatabaseMap::dumpMaps()}
*
* @return void
*/
public function loadMapsFromDump(array $mapsDump): void
{
$this->tables = $mapsDump['tablesByName'];
$this->tablesByPhpName = $mapsDump['tablesByPhpName'];
}

/**
* Registers a table map classes (by qualified name) as table belonging
* to this database.
Expand All @@ -150,17 +187,36 @@ public function addTableFromMapClass(string $tableMapClass): TableMap
public function registerTableMapClass(string $tableMapClass): void
{
$tableName = $tableMapClass::TABLE_NAME;
$this->tables[$tableName] = $tableMapClass;

$tablePhpName = $tableMapClass::TABLE_PHP_NAME;
$this->registerTableMapClassByName($tableName, $tablePhpName, $tableMapClass);
}

/**
* Registers a table map classes (by qualified name) as table belonging
* to this database.
*
* Classes added like this will only be instantiated when accessed
* through {@link DatabaseMap::getTable()},
* {@link DatabaseMap::getTableByPhpName()}, or
* {@link DatabaseMap::getTables()}
*
* @param string $tableName Internal name of the table, i.e. 'bookstore_schemas.book'
* @param string|null $tablePhpName PHP name of the table, i.e. 'Book'
* @param class-string<\Propel\Runtime\Map\TableMap> $tableMapClass The name of the table map to add
*
* @return void
*/
public function registerTableMapClassByName(string $tableName, ?string $tablePhpName, string $tableMapClass): void
{
$this->tables[$tableName] = $tableMapClass;
$this->addTableByPhpName($tablePhpName, $tableMapClass);
}

/**
* Registers a list of table map classes (by qualified name) as table maps
* belonging to this database.
*
* @param array<class-string> $tableMapClasses
* @param array<class-string<\Propel\Runtime\Map\TableMap>> $tableMapClasses
*
* @return void
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ interface ServiceContainerInterface
*
* @var string
*/
public const DEFAULT_DATABASE_MAP_CLASS = '\Propel\Runtime\Map\DatabaseMap';
public const DEFAULT_DATABASE_MAP_CLASS = DatabaseMap::class;

/**
* The name of the default datasource.
Expand All @@ -50,7 +50,7 @@ interface ServiceContainerInterface
*
* @var string
*/
public const DEFAULT_PROFILER_CLASS = '\Propel\Runtime\Util\Profiler';
public const DEFAULT_PROFILER_CLASS = Profiler::class;

/**
* @return string
Expand Down
Loading