Skip to content

Commit

Permalink
Optimize lazy loading in DatabaseMap
Browse files Browse the repository at this point in the history
  • Loading branch information
alfredbez committed Jul 11, 2023
1 parent 011aaa7 commit ee1406b
Showing 1 changed file with 75 additions and 3 deletions.
78 changes: 75 additions & 3 deletions src/Propel/Runtime/Map/DatabaseMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ class DatabaseMap
*/
protected $tablesByPhpName = [];

/**
* True if all tables were loaded.
*
* @var bool
*/
protected $areTablesLoaded = false;

/**
* Holds all registered tables.
*
* @var array<int, class-string>
*/
protected $registeredTables = [];

/**
* Shows if the table was successfully resolved by its name.
*
* @var array<string, bool>
*/
protected $resolvedTableNames = [];

/**
* @param string $name Name of the database.
*/
Expand Down Expand Up @@ -225,7 +246,47 @@ public function registerTableMapClassByName(string $tableName, ?string $tablePhp
*/
public function registerTableMapClasses(array $tableMapClasses): void
{
array_map([$this, 'registerTableMapClass'], $tableMapClasses);
$this->registeredTables = array_unique(array_merge($this->registeredTables, $tableMapClasses));
}

/**
* Tries to resolve a table by the name via PHP name class.
*
* @return bool if the table was resolved by the name
*/
protected function loadTableMap(string $name): bool
{
if ($this->areTablesLoaded) {
return true;
}
if (isset($this->resolvedTableNames[$name])) {
return $this->resolvedTableNames[$name];
}
$className = ucfirst(str_replace('_', '', ucwords($name, '_')));
$className .= 'TableMap';
$results = array_filter($this->registeredTables, function ($registeredTableName) use ($className) {
return str_ends_with($registeredTableName, $className);
});

array_map([$this, 'registerTableMapClass'], $results);

Check failure on line 271 in src/Propel/Runtime/Map/DatabaseMap.php

View workflow job for this annotation

GitHub Actions / code-style-and-static-analysis

Parameter #1 $callback of function array_map expects (callable(class-string): mixed)|null, array{$this(Propel\Runtime\Map\DatabaseMap), 'registerTableMapCla…'} given.
$this->resolvedTableNames[$name] = count($results) > 0;

return $this->resolvedTableNames[$name];
}

/**
* Loads all registered tables classes and fills in name and PHP name lookup indices.
*
* @return void
*/
protected function loadTableMaps(): void
{
if ($this->areTablesLoaded) {
return;
}

array_map([$this, 'registerTableMapClass'], $this->registeredTables);

Check failure on line 288 in src/Propel/Runtime/Map/DatabaseMap.php

View workflow job for this annotation

GitHub Actions / code-style-and-static-analysis

Parameter #1 $callback of function array_map expects (callable(class-string): mixed)|null, array{$this(Propel\Runtime\Map\DatabaseMap), 'registerTableMapCla…'} given.
$this->areTablesLoaded = true;
}

/**
Expand All @@ -241,7 +302,11 @@ public function hasTable(string $name): bool
$name = substr($name, 0, strpos($name, '.'));
}

return isset($this->tables[$name]);
if (isset($this->tables[$name])) {
return true;
}

return $this->loadTableMap($name) && isset($this->tables[$name]);
}

/**
Expand All @@ -256,7 +321,14 @@ public function hasTable(string $name): bool
public function getTable(string $name): TableMap
{
if (!isset($this->tables[$name])) {
throw new TableNotFoundException(sprintf('Cannot fetch TableMap for undefined table `%s` in database `%s`.', $name, $this->getName()));
$this->loadTableMap($name);
if (!isset($this->tables[$name])) {
$this->loadTableMaps();
}

if (!isset($this->tables[$name])) {
throw new TableNotFoundException(sprintf('Cannot fetch TableMap for undefined table `%s` in database `%s`.', $name, $this->getName()));
}
}

$tableOrClass = $this->tables[$name];
Expand Down

0 comments on commit ee1406b

Please sign in to comment.