From: Joshua Rüsweg Date: Thu, 1 Aug 2019 09:17:40 +0000 (+0200) Subject: Use information_schema to determine fks X-Git-Tag: 5.2.0_Alpha_4~19^2~3 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=4d72e1ece36b5c07bb737ec922de9f811eabde0f;p=GitHub%2FWoltLab%2FWCF.git Use information_schema to determine fks See #2977 --- diff --git a/wcfsetup/install/files/lib/acp/page/SystemCheckPage.class.php b/wcfsetup/install/files/lib/acp/page/SystemCheckPage.class.php index 3a14e3ef2a..fd67d11d67 100644 --- a/wcfsetup/install/files/lib/acp/page/SystemCheckPage.class.php +++ b/wcfsetup/install/files/lib/acp/page/SystemCheckPage.class.php @@ -2,6 +2,7 @@ namespace wcf\acp\page; use wcf\data\application\Application; use wcf\page\AbstractPage; +use wcf\system\database\util\PreparedStatementConditionBuilder; use wcf\system\exception\SystemException; use wcf\system\Regex; use wcf\system\WCF; @@ -220,21 +221,31 @@ class SystemCheckPage extends AbstractPage { } // validate foreign keys - $this->results['mysql']['foreignKeys'] = true; + $keyCount = 0; + $conditionBuilder = new PreparedStatementConditionBuilder(true, 'OR'); foreach ($this->foreignKeys as $table => $keys) { - $sql = "SHOW CREATE TABLE ". $table; - $statement = WCF::getDB()->prepareStatement($sql); - $statement->execute(); - - $command = $statement->fetchSingleColumn(1); foreach ($keys as $column => $reference) { - if (!Regex::compile('CONSTRAINT [`"]?(.)*[`"]? FOREIGN KEY \([`"]?'. $column .'[`"]?\) REFERENCES [`"]?'. $reference['referenceTable'] .'[`"]? \([`"]?'. $reference['referenceColumn'] .'[`"]?\)')->match($command)) { - $this->results['mysql']['foreignKeys'] = false; - break 2; - } + $innerConditionBuilder = new PreparedStatementConditionBuilder(false); + $innerConditionBuilder->add('REFERENCED_TABLE_SCHEMA = ?', [WCF::getDB()->getDatabaseName()]); + $innerConditionBuilder->add('REFERENCED_TABLE_NAME = ?', [$reference['referenceTable']]); + $innerConditionBuilder->add('REFERENCED_COLUMN_NAME = ?', [$reference['referenceColumn']]); + $innerConditionBuilder->add('TABLE_NAME = ?', [$table]); + $innerConditionBuilder->add('COLUMN_NAME = ?', [$column]); + + $conditionBuilder->add('('. $innerConditionBuilder .')', $innerConditionBuilder->getParameters()); + + $keyCount++; } } + $sql = "SELECT COUNT(*) + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + ". $conditionBuilder; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute($conditionBuilder->getParameters()); + + $this->results['mysql']['foreignKeys'] = $statement->fetchSingleColumn() === $keyCount; + if ($this->results['mysql']['result'] && $this->results['mysql']['innodb'] && $this->results['mysql']['foreignKeys']) { $this->results['status']['mysql'] = true; }