Skip to content

Commit

Permalink
Add support of older versions of Doctrine/Dbal library #175 (#176)
Browse files Browse the repository at this point in the history
Added implementation for QueryBuilder proxy supporting doctrine/dbal ^2.12.0|^3.0 (#175)
  • Loading branch information
tworzenieweb authored Aug 11, 2023
1 parent e93b8a0 commit f953e34
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 11 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
},
"require": {
"php": "^8.0",
"doctrine/dbal": "^3.3.7",
"doctrine/dbal": "^2.12.0|^3.0",
"doctrine/persistence": "^2.5",
"enqueue/amqp-ext": "^0.10.18",
"enqueue/dbal": "^0.10.17",
Expand Down
2 changes: 1 addition & 1 deletion packages/Dbal/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"require": {
"ecotone/enqueue": "~1.96.0",
"enqueue/dbal": "^0.10.17",
"doctrine/dbal": "^3.3.7"
"doctrine/dbal": "^2.12.0|^3.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
Expand Down
224 changes: 224 additions & 0 deletions packages/Dbal/src/Compatibility/QueryBuilderProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
<?php

declare(strict_types=1);

namespace Ecotone\Dbal\Compatibility;

use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\DBAL\Result;

/**
* @package Ecotone\Dbal\Compatibility
* @author Łukasz Adamczewski <tworzenieweb@gmail.com>
*
* Simple proxy class to keep the QueryBuilder API compatible with Doctrine DBAL 2.10 and 3.0
* All the parent methods need to be implemented in order to intercept and pass to the wrapped instance.
* Class supports execution of various fetch methods directly from query object that was added in version 3.1
*
* @see https://github.com/doctrine/dbal/blob/3.6.x/UPGRADE.md#upgrade-to-31
*/
final class QueryBuilderProxy extends QueryBuilder
{
public function __construct(private QueryBuilder $queryBuilder)
{
}

// override all public methods from parent class with empty body
public function select($select = null)
{
$this->queryBuilder->{__FUNCTION__}(...func_get_args());

return $this;
}

public function from($from, $alias = null)
{
$this->queryBuilder->{__FUNCTION__}($from, $alias);

return $this;
}

public function addSelect($select = null)
{
$this->queryBuilder->{__FUNCTION__}(...func_get_args());

return $this;
}

public function delete($delete = null, $alias = null)
{
$this->queryBuilder->{__FUNCTION__}($delete, $alias);

return $this;
}

public function update($update = null, $alias = null)
{
$this->queryBuilder->{__FUNCTION__}($update, $alias);

return $this;
}

public function set($key, $value)
{
$this->queryBuilder->{__FUNCTION__}($key, $value);

return $this;
}

public function where($predicates)
{
$this->queryBuilder->{__FUNCTION__}($predicates);

return $this;
}

public function andWhere($where)
{
$this->queryBuilder->{__FUNCTION__}($where);

return $this;
}

public function orWhere($where)
{
$this->queryBuilder->{__FUNCTION__}($where);

return $this;
}

public function groupBy($groupBy)
{
$this->queryBuilder->{__FUNCTION__}($groupBy);

return $this;
}

public function addGroupBy($groupBy)
{
$this->queryBuilder->{__FUNCTION__}($groupBy);

return $this;
}

public function having($having)
{
$this->queryBuilder->{__FUNCTION__}($having);

return $this;
}

public function setFirstResult($firstResult)
{
$this->queryBuilder->{__FUNCTION__}($firstResult);

return $this;
}

public function setMaxResults($maxResults)
{
$this->queryBuilder->{__FUNCTION__}($maxResults);

return $this;
}

public function setParameter($key, $value, $type = null)
{
$this->queryBuilder->{__FUNCTION__}($key, $value, $type);

return $this;
}

public function setParameters(array $params, array $types = [])
{
$this->queryBuilder->{__FUNCTION__}($params, $types);

return $this;
}

public function __clone()
{
$this->queryBuilder->{__FUNCTION__}();

return $this;
}

public function __toString()
{
$this->queryBuilder->{__FUNCTION__}();

return $this;
}

public function expr()
{
$this->queryBuilder->{__FUNCTION__}();

return $this;
}

public function resetQueryParts($queryPartNames = null)
{
$this->queryBuilder->{__FUNCTION__}($queryPartNames);

return $this;
}

public function getQueryPart($queryPartName)
{
$this->queryBuilder->{__FUNCTION__}($queryPartName);

return $this;
}

public function getSQL()
{
return $this->queryBuilder->{__FUNCTION__}();
}

public function getType()
{
return $this->queryBuilder->{__FUNCTION__}();
}

public function getState()
{
return $this->queryBuilder->{__FUNCTION__}();
}

public function execute()
{
return $this->queryBuilder->{__FUNCTION__}();
}

public function executeQuery(): Result
{
$name = method_exists($this->queryBuilder, __FUNCTION__) ? __FUNCTION__ : 'execute';

return $this->queryBuilder->{$name}();
}

public function executeStatement(): int
{
$name = method_exists($this->queryBuilder, __FUNCTION__) ? __FUNCTION__ : 'execute';

return $this->queryBuilder->{$name}();
}

public function __call($name, $arguments)
{
switch ($name) {
case 'fetchAllAssociativeIndexed':
case 'fetchAllKeyValue':
case 'fetchAllNumeric':
case 'fetchAssociative':
case 'fetchNumeric':
case 'fetchAllAssociative':
case 'fetchFirstColumn':
case 'fetchOne':
return $this->queryBuilder->execute()->$name(...$arguments);
}

throw new \InvalidArgumentException(sprintf("Not supported proxy method: %s", $name));
}
}
5 changes: 3 additions & 2 deletions packages/Dbal/src/DocumentStore/DbalDocumentStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Types;
use Ecotone\Dbal\Compatibility\QueryBuilderProxy;
use Ecotone\Enqueue\CachedConnectionFactory;
use Ecotone\Messaging\Conversion\ConversionService;
use Ecotone\Messaging\Conversion\MediaType;
Expand Down Expand Up @@ -160,7 +161,7 @@ public function countDocuments(string $collectionName): int
return 0;
}

$select = $this->getConnection()->createQueryBuilder()
$select = (new QueryBuilderProxy($this->getConnection()->createQueryBuilder()))
->select('COUNT(document_id)')
->from($this->getTableName())
->andWhere('collection = :collection')
Expand Down Expand Up @@ -272,7 +273,7 @@ private function updateDocumentInternally(object|array|string $document, string

private function getDocumentsFor(string $collectionName): \Doctrine\DBAL\Query\QueryBuilder
{
return $this->getConnection()->createQueryBuilder()
return (new QueryBuilderProxy($this->getConnection()->createQueryBuilder()))
->select('document', 'document_type')
->from($this->getTableName())
->andWhere('collection = :collection')
Expand Down
10 changes: 6 additions & 4 deletions packages/Dbal/src/Recoverability/DbalDeadLetterHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Types;
use Ecotone\Dbal\Compatibility\QueryBuilderProxy;
use Ecotone\Messaging\Conversion\ConversionService;
use Ecotone\Messaging\Gateway\MessagingEntrypoint;
use Ecotone\Messaging\Handler\Recoverability\ErrorContext;
Expand Down Expand Up @@ -47,7 +48,7 @@ public function list(int $limit, int $offset): array
return [];
}

$messages = $this->getConnection()->createQueryBuilder()
$messages = (new QueryBuilderProxy($this->getConnection()->createQueryBuilder()))
->select('*')
->from($this->getTableName())
->setMaxResults($limit)
Expand All @@ -64,7 +65,8 @@ public function list(int $limit, int $offset): array
public function show(string $messageId, ?MessageChannel $replyChannel = null): Message
{
$this->initialize();
$message = $this->getConnection()->createQueryBuilder()

$message = (new QueryBuilderProxy($this->getConnection()->createQueryBuilder()))
->select('*')
->from($this->getTableName())
->andWhere('message_id = :messageId')
Expand Down Expand Up @@ -96,7 +98,7 @@ public function count(): int
return 0;
}

return (int)$this->getConnection()->createQueryBuilder()
return (int) (new QueryBuilderProxy($this->getConnection()->createQueryBuilder()))
->select('count(*)')
->from($this->getTableName())
->executeQuery()
Expand Down Expand Up @@ -283,7 +285,7 @@ private function replyWithoutInitialization(string $messageId, MessagingEntrypoi

private function deleteGivenMessage(array|string $messageId): void
{
$this->getConnection()->createQueryBuilder()
(new QueryBuilderProxy($this->getConnection()->createQueryBuilder()))
->delete($this->getTableName())
->andWhere('message_id = :messageId')
->setParameter('messageId', $messageId, Types::TEXT)
Expand Down
2 changes: 1 addition & 1 deletion packages/Dbal/tests/DbalMessagingTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function setUp(): void

protected function checkIfTableExists(Connection $connection, string $table): bool
{
$schemaManager = $connection->createSchemaManager();
$schemaManager = method_exists($connection, 'getSchemaManager') ? $connection->getSchemaManager() : $connection->createSchemaManager();

return $schemaManager->tablesExist([$table]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public function register(string $order, OrderRegisteringGateway $orderRegisterin
#[CommandHandler('order.register_with_table_creation', 'orderRegister2')]
public function registerWithTableCreation(string $order, OrderRegisteringGateway $orderRegisteringGateway, #[Reference(DbalConnectionFactory::class)] ConnectionFactory $connection): void
{
$schemaManager = $connection->createContext()->getDbalConnection()->createSchemaManager();
$connection = $connection->createContext()->getDbalConnection();
$schemaManager = method_exists($connection, 'getSchemaManager') ? $connection->getSchemaManager() : $connection->createSchemaManager();

if ($schemaManager->tablesExist(['test_table'])) {
$schemaManager->dropTable('test_table');
Expand Down
2 changes: 1 addition & 1 deletion packages/Dbal/tests/Fixture/Transaction/OrderService.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function hasOrder(#[Reference(DbalConnectionFactory::class)] ManagerRegis

private function doesTableExists(\Doctrine\DBAL\Connection $connection)
{
$schemaManager = $connection->createSchemaManager();
$schemaManager = method_exists($connection, 'getSchemaManager') ? $connection->getSchemaManager() : $connection->createSchemaManager();

return $schemaManager->tablesExist(['orders']);
}
Expand Down

0 comments on commit f953e34

Please sign in to comment.