From 3be0dc7c0528f71d55071fb6747056927c0904fe Mon Sep 17 00:00:00 2001 From: Markus Klein <markus.klein@typo3.org> Date: Tue, 19 Apr 2016 15:36:26 +0200 Subject: [PATCH] [BUGFIX] Missing relations command: optimize SQL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Iterate over each result row instead of fetching the whole result into PHP memory. Resolves: #75783 Releases: master Change-Id: Icd77e5bae1839b66bb156beeef17e7d4bb7535d7 Reviewed-on: https://review.typo3.org/47786 Reviewed-by: Nicole Cordes <typo3@cordes.co> Tested-by: Nicole Cordes <typo3@cordes.co> Reviewed-by: Christoph Kratz <ckr@rtp.ch> Tested-by: Christoph Kratz <ckr@rtp.ch> Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl> Tested-by: Philipp Gampe <philipp.gampe@typo3.org> Reviewed-by: Stephan Großberndt <stephan@grossberndt.de> Tested-by: Stephan Großberndt <stephan@grossberndt.de> Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de> Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de> --- .../Classes/MissingRelationsCommand.php | 68 ++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/typo3/sysext/lowlevel/Classes/MissingRelationsCommand.php b/typo3/sysext/lowlevel/Classes/MissingRelationsCommand.php index ffbb03905b80..3bb4d46d4f1c 100644 --- a/typo3/sysext/lowlevel/Classes/MissingRelationsCommand.php +++ b/typo3/sysext/lowlevel/Classes/MissingRelationsCommand.php @@ -14,6 +14,12 @@ namespace TYPO3\CMS\Lowlevel; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Database\Query\QueryBuilder; +use TYPO3\CMS\Core\Database\ReferenceIndex; +use TYPO3\CMS\Core\Utility\GeneralUtility; + /** * Looking for missing relations. */ @@ -84,35 +90,47 @@ Reports missing relations'; 'deletedRecords_s' => array(), 'nonExistingRecords_s' => array() ); + // Select DB relations from reference table - $recs = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_refindex', 'ref_table<>' . $GLOBALS['TYPO3_DB']->fullQuoteStr('_FILE', 'sys_refindex') . ' AND ref_uid>0' . $filterClause, '', 'sorting DESC'); - // Traverse the records + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex'); + $rowIterator = $queryBuilder + ->select('ref_uid', 'ref_table', 'softref_key', 'hash', 'tablename', 'recuid', 'field', 'flexpointer', 'deleted') + ->from('sys_refindex') + ->where( + $queryBuilder->expr()->neq('ref_table', $queryBuilder->quote('_FILE')) + ) + ->andWhere( + $queryBuilder->expr()->gt('ref_uid', 0) + ) + ->orderBy('sorting', 'DESC') + ->execute(); + $tempExists = array(); - if (is_array($recs)) { - foreach ($recs as $rec) { - $suffix = $rec['softref_key'] != '' ? '_s' : '_m'; - $idx = $rec['ref_table'] . ':' . $rec['ref_uid']; - // Get referenced record: - if (!isset($tempExists[$idx])) { - $tempExists[$idx] = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordRaw($rec['ref_table'], 'uid=' . (int)$rec['ref_uid'], 'uid,pid' . ($GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] : '')); - } - // Compile info string for location of reference: - $infoString = $this->infoStr($rec); - // Handle missing file: - if ($tempExists[$idx]['uid']) { - if ($tempExists[$idx]['pid'] == -1) { - $resultArray['offlineVersionRecords' . $suffix][$idx][$rec['hash']] = $infoString; - ksort($resultArray['offlineVersionRecords' . $suffix][$idx]); - } elseif ($GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] && $tempExists[$idx][$GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete']]) { - $resultArray['deletedRecords' . $suffix][$idx][$rec['hash']] = $infoString; - ksort($resultArray['deletedRecords' . $suffix][$idx]); - } - } else { - $resultArray['nonExistingRecords' . $suffix][$idx][$rec['hash']] = $infoString; - ksort($resultArray['nonExistingRecords' . $suffix][$idx]); + while ($rec = $rowIterator->fetch()) { + $suffix = $rec['softref_key'] != '' ? '_s' : '_m'; + $idx = $rec['ref_table'] . ':' . $rec['ref_uid']; + // Get referenced record: + if (!isset($tempExists[$idx])) { + $tempExists[$idx] = BackendUtility::getRecordRaw($rec['ref_table'], 'uid=' . (int)$rec['ref_uid'], 'uid,pid' . ($GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] : '')); + } + // Compile info string for location of reference: + $infoString = $this->infoStr($rec); + // Handle missing file: + if ($tempExists[$idx]['uid']) { + if ($tempExists[$idx]['pid'] == -1) { + $resultArray['offlineVersionRecords' . $suffix][$idx][$rec['hash']] = $infoString; + ksort($resultArray['offlineVersionRecords' . $suffix][$idx]); + } elseif ($GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] && $tempExists[$idx][$GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete']]) { + $resultArray['deletedRecords' . $suffix][$idx][$rec['hash']] = $infoString; + ksort($resultArray['deletedRecords' . $suffix][$idx]); } + } else { + $resultArray['nonExistingRecords' . $suffix][$idx][$rec['hash']] = $infoString; + ksort($resultArray['nonExistingRecords' . $suffix][$idx]); } } + ksort($resultArray['offlineVersionRecords_m']); ksort($resultArray['deletedRecords_m']); ksort($resultArray['nonExistingRecords_m']); @@ -140,7 +158,7 @@ Reports missing relations'; if ($bypass = $this->cli_noExecutionCheck($recReference)) { echo $bypass; } else { - $sysRefObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\ReferenceIndex::class); + $sysRefObj = GeneralUtility::makeInstance(ReferenceIndex::class); $error = $sysRefObj->setReferenceValue($hash, null); if ($error) { echo ' TYPO3\\CMS\\Core\\Database\\ReferenceIndex::setReferenceValue(): ' . $error . LF; -- GitLab