Skip to content

Update tdbm for Symfony 6 and doctrine v3 #288

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

Open
wants to merge 1 commit 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
9 changes: 4 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,21 @@
],
"require" : {
"php": "^7.4 || ^8.0",
"mouf/magic-query": "^1.4.3",
"mouf/magic-query": "2.0.x-dev",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once everything works:

  1. Merge changes to mouf/magic-query if there are any
  2. Release a new mouf/magic-query version (2.0.0)
  3. Require this new version here

"mouf/schema-analyzer": "^2.0",
"doctrine/dbal": "^3.0",
"psr/log": "^1 || ^2 || ^3",
"doctrine/inflector": "^1.4.3 || ^2",
"mouf/classname-mapper": "~1.0",
"doctrine/cache": "^1.6",
"greenlion/php-sql-parser": "^4.3.0",
"symfony/console": "^2 || ^3 || ^4 || ^5",
"symfony/console": "^2 || ^3 || ^4 || ^5 || ^6",
"mouf/utils.log.psr.multi-logger": "^1.0",
"symfony/filesystem": "^2.7 || ^3 || ^4 || ^5",
"symfony/filesystem": "^2.7 || ^3 || ^4 || ^5 || ^6",
"ramsey/uuid": "^3.7 || ^4.0",
"doctrine/annotations": "^1.10",
"laminas/laminas-code": "^4.7",
"psr/container": "^1 || ^2",
"brain-diminished/schema-version-control": "^1.0.5",
"ext-PDO": "*",
"ext-json": "*",
"ext-hash": "*",
Expand All @@ -47,7 +46,7 @@
"wa72/simplelogger": "^1.0",
"friendsofphp/php-cs-fixer": "^3.11",
"symfony/process": "^3 || ^4 || ^5",
"thecodingmachine/tdbm-fluid-schema-builder": "^1.0.0",
"thecodingmachine/tdbm-fluid-schema-builder": "^v2.0.0",
"phpstan/phpstan": "^0.12.81",
"thecodingmachine/phpstan-strict-rules": "^0.12.1",
"bamarni/composer-bin-plugin": "^1.4.1",
Expand Down
5 changes: 4 additions & 1 deletion src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,10 @@ public function getCodeGeneratorListener(): CodeGeneratorListenerInterface
*/
private function getConnectionUniqueId(): string
{
return hash('md4', $this->connection->getHost().'-'.$this->connection->getPort().'-'.$this->connection->getDatabase().'-'.$this->connection->getDriver()->getName());
$params = $this->connection->getParams();
$host = $params['host'] ?? null;
$port = $params['port'] ?? null;
return hash('md4', $host.'-'.$port.'-'.$this->connection->getDatabase().'-'.$this->connection->getDatabasePlatform()->getName());
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/DbRow.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public function _dbLoadIfNotLoaded(): void
$this->dbRow[$key] = $types[$key]->convertToPHPValue($value, $connection->getDatabasePlatform());
}

$result->closeCursor();
$result->free();

$this->status = TDBMObjectStateEnum::STATE_LOADED;
}
Expand Down
2 changes: 1 addition & 1 deletion src/InnerResultArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ private function toIndex($offset): void
if ($offset < 0 || filter_var($offset, FILTER_VALIDATE_INT) === false) {
throw new TDBMInvalidOffsetException('Trying to access result set using offset "'.$offset.'". An offset must be a positive integer.');
}
if ($this->statement === null) {
if ($this->result === null) {
$this->executeQuery();
}
while (!isset($this->results[$offset])) {
Expand Down
16 changes: 8 additions & 8 deletions src/InnerResultIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace TheCodingMachine\TDBM;

use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Statement;
use Mouf\Database\MagicQuery;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -35,8 +35,8 @@
*/
class InnerResultIterator implements \Iterator, InnerResultIteratorInterface
{
/** @var ResultStatement|Statement */
protected $statement;
/** @var Result */
protected $result;

/** @var bool */
protected $fetchStarted = false;
Expand Down Expand Up @@ -117,7 +117,7 @@ protected function executeQuery(): void

$this->logger->debug('Running SQL request: '.$sql);

$this->statement = $this->tdbmService->getConnection()->executeQuery($sql, $this->parameters, DbalUtils::generateTypes($this->parameters));
$this->result = $this->tdbmService->getConnection()->executeQuery($sql, $this->parameters, DbalUtils::generateTypes($this->parameters));

$this->fetchStarted = true;
}
Expand All @@ -135,8 +135,8 @@ public function count()

if ($this->fetchStarted && $this->tdbmService->getConnection()->getDatabasePlatform() instanceof MySqlPlatform) {
// Optimisation: we don't need a separate "count" SQL request in MySQL.
assert($this->statement instanceof Statement);
$this->count = (int)$this->statement->rowCount();
assert($this->result instanceof Result);
$this->count = (int)$this->result->rowCount();
return $this->count;
}
return $this->getRowCountViaSqlQuery();
Expand All @@ -152,7 +152,7 @@ private function getRowCountViaSqlQuery(): int

$this->logger->debug('Running count SQL request: '.$countSql);

$this->count = (int) $this->tdbmService->getConnection()->fetchColumn($countSql, $this->parameters, 0, DbalUtils::generateTypes($this->parameters));
$this->count = (int) $this->tdbmService->getConnection()->fetchOne($countSql, $this->parameters, DbalUtils::generateTypes($this->parameters));
return $this->count;
}

Expand Down Expand Up @@ -182,7 +182,7 @@ public function key()
*/
public function next(): void
{
$row = $this->statement->fetch(\PDO::FETCH_ASSOC);
$row = $this->result->fetchAssociative();
if ($row) {
/** @var array<string, array<string, array<string, mixed>>> $beansData array<tablegroup, array<table, array<column, value>>>*/
$beansData = [];
Expand Down
4 changes: 2 additions & 2 deletions src/QueryFactory/FindObjectsFromRawSqlQueryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ private function formatSelect(array $baseSelect): array
]
];
$formattedSelect[] = $astColumn;
if (in_array($columnName, $pkColumns)) {
if (array_key_exists($columnName, $pkColumns)) {
$formattedCountSelect[] = $astColumn;
}
$columnDescriptors[$alias] = [
Expand Down Expand Up @@ -322,7 +322,7 @@ private function generateSimpleSqlCount(array $parsedSql): array
if ($this->isDistinctQuery($parsedSql)) {
// Only MySQL can do DISTINCT counts.
// Other databases should wrap the query
if (!$this->tdbmService->getConnection()->getSchemaManager()->getDatabasePlatform() instanceof MySqlPlatform) {
if (!$this->tdbmService->getConnection()->getDatabasePlatform() instanceof MySqlPlatform) {
return $this->generateWrappedSqlCount($parsedSql);
}

Expand Down
2 changes: 1 addition & 1 deletion src/ResultIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ protected function executeCountQuery(): void
{
$sql = $this->magicQuery->buildPreparedStatement($this->queryFactory->getMagicSqlCount(), $this->parameters);
$this->logger->debug('Running count query: '.$sql);
$this->totalCount = (int) $this->tdbmService->getConnection()->fetchColumn($sql, $this->parameters, 0, DbalUtils::generateTypes($this->parameters));
$this->totalCount = (int) $this->tdbmService->getConnection()->fetchOne($sql, $this->parameters, DbalUtils::generateTypes($this->parameters));
}

/**
Expand Down
7 changes: 5 additions & 2 deletions src/SchemaLockFileDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

namespace TheCodingMachine\TDBM;

use BrainDiminished\SchemaVersionControl\SchemaVersionControlService;
use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
use TheCodingMachine\TDBM\SchemaVersionControl\SchemaVersionControlService;
use TheCodingMachine\TDBM\Utils\ColumnsReorderer;
use TheCodingMachine\TDBM\Utils\ImmutableCaster;

Expand Down Expand Up @@ -68,7 +68,10 @@ public function __construct(Connection $connection, Cache $cache, string $lockFi
public function getCachePrefix(): string
{
if ($this->cachePrefix === null) {
$this->cachePrefix = hash('md4', $this->connection->getHost().'-'.$this->connection->getPort().'-'.$this->connection->getDatabase().'-'.$this->connection->getDriver()->getName());
$params = $this->connection->getParams();
$host = $params['host'] ?? null;
$port = $params['port'] ?? null;
$this->cachePrefix = hash('md4', $host.'-'.$port.'-'.$this->connection->getDatabase().'-'.$this->connection->getDatabasePlatform()?->getName());
}

return $this->cachePrefix;
Expand Down
163 changes: 163 additions & 0 deletions src/SchemaVersionControl/SchemaBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

namespace TheCodingMachine\TDBM\SchemaVersionControl;

use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;

/**
* Database schema builder.
*
* Given a deep associative array supposed to describe a database schema, SchemaBuilder::build will construct a
* corresponding Schema object.
*/
class SchemaBuilder
{
/** @var array */
protected $schemaDesc;

/**
* Build an array descriptor into a Schema object
* @param array $schemaDesc
* @return Schema
*/
public function build(array $schemaDesc): Schema
{
$this->schemaDesc = $schemaDesc;
$schema = new Schema();
foreach ($schemaDesc['tables'] as $name => $tableDesc) {
$table = $schema->createTable($name);
$this->buildTable($tableDesc, $table);
}
return $schema;
}

protected function buildTable(array $tableDesc, Table $table)
{
$pk_columns = [];

if (isset($tableDesc['comment'])) {
$table->addOption("comment", $tableDesc['comment']);
}

foreach ($tableDesc['columns'] as $columnName => $columnDesc) {
if (!is_array($columnDesc)) {
$columnDesc = ['type' => $columnDesc];
}
if (isset($columnDesc['primary_key'])
&& $columnDesc['primary_key']) {
$pk_columns[] = $columnName;
}
$column = $table->addColumn($columnName, $columnDesc['type']);
$this->buildColumn($columnDesc, $column);
}
if (isset($tableDesc['indexes'])) {
foreach ($tableDesc['indexes'] as $indexName => $indexDesc) {
$this->buildIndex($indexDesc, $table, $indexName);
}
}
if (!empty($pk_columns)) {
$table->setPrimaryKey($pk_columns);
}
if (isset($tableDesc['foreign_keys'])) {
foreach ($tableDesc['foreign_keys'] as $constraintName => $constraintDesc) {
$this->buildForeignKeyConstraint($constraintDesc, $table, $constraintName);
}
}
}

protected function buildColumn(array $columnDesc, Column $column)
{
if (isset($columnDesc['fixed'])) {
$column->setFixed($columnDesc['fixed']);
}
if (isset($columnDesc['length'])) {
$column->setLength($columnDesc['length']);
}
if (isset($columnDesc['precision'])) {
$column->setPrecision($columnDesc['precision']);
}
if (isset($columnDesc['scale'])) {
$column->setScale($columnDesc['scale']);
}
$column->setNotnull(isset($columnDesc['not_null']) && $columnDesc['not_null']);
if (isset($columnDesc['default'])) {
$column->setDefault($columnDesc['default']);
}
if (isset($columnDesc['auto_increment'])) {
$column->setAutoincrement($columnDesc['auto_increment']);
}
if (isset($columnDesc['comment'])) {
$column->setComment($columnDesc['comment']);
}
if (isset($columnDesc['custom'])) {
$column->setCustomSchemaOptions($columnDesc['custom']);
}
}

protected function buildForeignKeyConstraint(array $constraintDesc, Table $table, string $name)
{
if (isset($constraintDesc['column'])) {
$localColumns = [$constraintDesc['column']];
} else {
$localColumns = $constraintDesc['columns'];
}
$references = $constraintDesc['references'];
if (is_array($references)) {
$foreignTable = $references['table'];
if (isset($references['column'])) {
$foreignColumns = [$references['column']];
} else {
$foreignColumns = $references['columns'];
}
} else {
$foreignTable = $references;
$foreignColumns = $this->getPrimaryKeyColumns($foreignTable);
if (!is_array($foreignColumns)) {
$foreignColumns = [$foreignColumns];
}
}
$options = array_diff_key($constraintDesc, ['column' => 0,'columns' => 0,'references' => 0]);
$table->addForeignKeyConstraint($foreignTable, $localColumns, $foreignColumns, $options, $name);
}

protected function getPrimaryKeyColumns(string $tableName)
{
$pkColumns = [];
$tableDesc = $this->schemaDesc['tables'][$tableName];
foreach ($tableDesc['columns'] as $columnName => $columnDesc) {
if (isset($columnDesc['primary_key'])
&& $columnDesc['primary_key']) {
$pkColumns[] = $columnName;
}
}
return $pkColumns;
}

protected function buildIndex($indexDesc, Table $table, $name)
{
if (!is_array($indexDesc)) {
$indexDesc = ['column' => $indexDesc];
} elseif (array_keys($indexDesc) === range(0, count($indexDesc) - 1)) {
$indexDesc = ['columns' => $indexDesc];
}

if (isset($indexDesc['column'])) {
$columns = [$indexDesc['column']];
} else {
$columns = $indexDesc['columns'];
}

if (is_int($name)) {
$name = implode('_', $columns);
}

$options = array_diff_key($indexDesc, ['column' => 0,'columns' => 0]);
if (isset($indexDesc['unique']) && $indexDesc['unique'] === true) {
$table->addUniqueIndex($columns, $name, [], $options);
} else {
$table->addIndex($columns, $name, [], $options);
}
}
}
Loading