Breaking: #102875 - QueryBuilder changes
See forge#102875
Description
Doctrine DBAL 4 removed methods from the Query
which has been
adopted to the extended \TYPO3\
.
Removed methods:
Query
: Use new reset methods and normal set methods instead.Builder:: add () Query
: No replacement, internal state.Builder:: get Query Part ($part Name) Query
: No replacement, internal state.Builder:: get Query Parts () Query
: Replacement methods has been added, see list.Builder:: reset Query Part ($part Name) Query
: Replacement methods has been added, see list.Builder:: reset Query Parts () Query
: UseBuilder:: execute () Query
orBuilder:: execute Query () Query
directly.Builder:: execute Statement () Query
: UsingBuilder:: set Max Results () (int)0
asmax result
will no longer work and retrieve no records. UseNULL
instead to allow all results.
Signature changes:
Query
: Second argument has been dropped and the value must now be of typeBuilder:: quote (string $value) string
.
Impact
Calling any of the mentioned removed methods will result in a PHP error. Also signature changes introducing type hint will result in a PHP error if called with an invalid type.
Affected installations
Only those installations that use the mentioned methods.
Migration
Extension author need to replace the removed methods with the alternatives which
QueryBuilder::add('query-part-name')
Use the direct set/select methods instead:
before | after |
---|---|
->add | ->select |
->add | ->where |
->add | ->having |
->add | ->order |
->add | ->group |
Note
This can be done already in TYPO3 v12 with at least Doctrine DBAL 3.8.
QueryBuilder::resetQueryParts()
and QueryBuilder::resetQueryPart()
However, several replacements have been put in place depending on the
$query
parameter:
before | after |
---|---|
'select' | Call ->select with a new set of columns |
'distinct' | ->distinct |
'where' | ->reset |
'having' | ->reset |
'groupBy' | ->reset |
'orderBy | ->reset |
'values' | Call ->values with a new set of values. |
Note
This can be done already in TYPO3 v12 with at least Doctrine DBAL 3.8.
QueryBuilder::execute()
Doctrine DBAL 4 removed Query
in favour of the two
methods Query
for select/count and Query
for insert, delete and update queries.
Before
use TYPO3\CMS\Core\Database\ConnectionPool;
// select query
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$rows = $queryBuilder
->select('*')
->from('pages')
->execute()
->fetchAllAssociative();
// delete query
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$deletedRows = (int)$queryBuilder
->delete('pages')
->where(
$queryBuilder->expr()->eq('pid', $this->createNamedParameter(123),
)
->execute();
After
use TYPO3\CMS\Core\Database\ConnectionPool;
// select query
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$rows = $queryBuilder
->select('*')
->from('pages')
->executeQuery()
->fetchAllAssociative();
// delete query
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$deletedRows = (int)$queryBuilder
->delete('pages')
->where(
$queryBuilder->expr()->eq('pid', $this->createNamedParameter(123),
)
->executeStatement();
QueryBuilder::quote(string $value)
quote
uses Connection::
and therefore adopts the changed
signature and behaviour.
Before
use TYPO3\CMS\Core\Database\Connection as Typo3Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
// select query
$pageId = 123;
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$rows = $queryBuilder
->select('*')
->from('pages')
->where(
$queryBuilder->expr()->eq(
'uid',
$queryBuilder->quote($pageId, Typo3Connection::PARAM_INT)
),
)
->executeQuery()
->fetchAllAssociative();
After
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
// select query
$pageId = 123;
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$rows = $queryBuilder
->select('*')
->from('pages')
->where(
$queryBuilder->expr()->eq(
'uid',
$queryBuilder->quote((string)$pageId)
),
)
->executeQuery()
->fetchAllAssociative();
Tip
To provide TYPO3 v12 and v13 with one code base, ->quote
can be used to ensure dual Core compatibility.
QueryBuilder::setMaxResults()
Using (int)0
as max result
will no longer work and retrieve no records.
Use NULL
instead to allow all results.
Before
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
// select query
$pageId = 123;
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$rows = $queryBuilder
->select('*')
->from('pages')
->setFirstResult(0)
->setMaxResults(0)
->executeQuery()
->fetchAllAssociative();
After
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
// select query
$pageId = 123;
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$rows = $queryBuilder
->select('*')
->from('pages')
->setFirstResult(0)
->setMaxResults(null)
->executeQuery()
->fetchAllAssociative();