installation-bundle/src/InstallTool.php
public function hasConfigurationError(array &$context): bool
    {
        $row = $this->connection
            ->query('SELECT @@version as Version')
            ->fetch(\PDO::FETCH_OBJ)
        ;

        [$version] = explode('-', $row->Version);

        // The database version is too old
        if (version_compare($version, '5.1.0', '<')) {
            $context['errorCode'] = 1;
            $context['version'] = $version;

            return true;
        }

        $options = $this->connection->getParams()['defaultTableOptions'];

        // Check the collation if the user has configured it
        if (isset($options['collate'])) {
            $statement = $this->connection->query("SHOW COLLATION LIKE '".$options['collate']."'");

            // The configured collation is not installed
            if (false === ($row = $statement->fetch(\PDO::FETCH_OBJ))) {
                $context['errorCode'] = 2;
                $context['collation'] = $options['collate'];

                return true;
            }
        }

        // Check the engine if the user has configured it
        if (isset($options['engine'])) {
            $engineFound = false;
            $statement = $this->connection->query('SHOW ENGINES');

            while (false !== ($row = $statement->fetch(\PDO::FETCH_OBJ))) {
                if ($options['engine'] === $row->Engine) {
                    $engineFound = true;
                    break;
                }
            }

            // The configured engine is not available
            if (!$engineFound) {
                $context['errorCode'] = 3;
                $context['engine'] = $options['engine'];

                return true;
            }
        }

        // Check if utf8mb4 can be used if the user has configured it
        if (isset($options['engine'], $options['collate']) && 0 === strncmp($options['collate'], 'utf8mb4', 7)) {
            if ('innodb' !== strtolower($options['engine'])) {
                $context['errorCode'] = 4;
                $context['engine'] = $options['engine'];

                return true;
            }

            $row = $this->connection
                ->query("SHOW VARIABLES LIKE 'innodb_large_prefix'")
                ->fetch(\PDO::FETCH_OBJ)
            ;

            // The variable no longer exists as of MySQL 8 and MariaDB 10.3
            if (false === $row) {
                return false;
            }

            // As there is no reliable way to get the vendor (see #84), we are
            // guessing based on the version number. The check will not be run
            // as of MySQL 8 and MariaDB 10.3, so this should be safe.
            $vok = version_compare($version, '10', '>=') ? '10.2.2' : '5.7.7';

            // Large prefixes are always enabled as of MySQL 5.7.7 and MariaDB 10.2.2
            if (version_compare($version, $vok, '>=')) {
                return false;
            }

            // The innodb_large_prefix option is disabled
            if (!\in_array(strtolower((string) $row->Value), ['1', 'on'], true)) {
                $context['errorCode'] = 5;

                return true;
            }

            $row = $this->connection
                ->query("SHOW VARIABLES LIKE 'innodb_file_per_table'")
                ->fetch(\PDO::FETCH_OBJ)
            ;

            // The innodb_file_per_table option is disabled
            if (!\in_array(strtolower((string) $row->Value), ['1', 'on'], true)) {
                $context['errorCode'] = 6;

                return true;
            }

            $row = $this->connection
                ->query("SHOW VARIABLES LIKE 'innodb_file_format'")
                ->fetch(\PDO::FETCH_OBJ)
            ;

            // The InnoDB file format is not Barracuda
            if ('barracuda' !== strtolower((string) $row->Value)) {
                $context['errorCode'] = 6;

                return true;
            }
        }

        return false;
    }
public function hasConfigurationError(array &$context): bool
    {
        $row = $this->connection
            ->query('SELECT @@version as Version')
            ->fetch(\PDO::FETCH_OBJ)
        ;

        [$version] = explode('-', $row->Version);

        // The database version is too old
        if (version_compare($version, '5.1.0', '<')) {
            $context['errorCode'] = 1;
            $context['version'] = $version;

            return true;
        }

        $options = $this->connection->getParams()['defaultTableOptions'];

        // Check the collation if the user has configured it
        if (isset($options['collate'])) {
            $statement = $this->connection->query("SHOW COLLATION LIKE '".$options['collate']."'");

            // The configured collation is not installed
            if (false === ($row = $statement->fetch(\PDO::FETCH_OBJ))) {
                $context['errorCode'] = 2;
                $context['collation'] = $options['collate'];

                return true;
            }
        }

        // Check the engine if the user has configured it
        if (isset($options['engine'])) {
            $engineFound = false;
            $statement = $this->connection->query('SHOW ENGINES');

            while (false !== ($row = $statement->fetch(\PDO::FETCH_OBJ))) {
                if ($options['engine'] === $row->Engine) {
                    $engineFound = true;
                    break;
                }
            }

            // The configured engine is not available
            if (!$engineFound) {
                $context['errorCode'] = 3;
                $context['engine'] = $options['engine'];

                return true;
            }
        }

        // Check if utf8mb4 can be used if the user has configured it
        if (isset($options['engine'], $options['collate']) && 0 === strncmp($options['collate'], 'utf8mb4', 7)) {
            if ('innodb' !== strtolower($options['engine'])) {
                $context['errorCode'] = 4;
                $context['engine'] = $options['engine'];

                return true;
            }

            $row = $this->connection
                ->query("SHOW VARIABLES LIKE 'innodb_large_prefix'")
                ->fetch(\PDO::FETCH_OBJ)
            ;

            // The variable no longer exists as of MySQL 8 and MariaDB 10.3
            if (false === $row) {
                return false;
            }

            // As there is no reliable way to get the vendor (see #84), we are
            // guessing based on the version number. The check will not be run
            // as of MySQL 8 and MariaDB 10.3, so this should be safe.
            $vok = version_compare($version, '10', '>=') ? '10.2.2' : '5.7.7';

            // Large prefixes are always enabled as of MySQL 5.7.7 and MariaDB 10.2.2
            if (version_compare($version, $vok, '>=')) {
                return false;
            }

            // The innodb_large_prefix option is disabled
            if (!\in_array(strtolower((string) $row->Value), ['1', 'on'], true)) {
                $context['errorCode'] = 5;

                return true;
            }

            $row = $this->connection
                ->query("SHOW VARIABLES LIKE 'innodb_file_per_table'")
                ->fetch(\PDO::FETCH_OBJ)
            ;

            // The innodb_file_per_table option is disabled
            if (!\in_array(strtolower((string) $row->Value), ['1', 'on'], true)) {
                $context['errorCode'] = 6;

                return true;
            }

            $row = $this->connection
                ->query("SHOW VARIABLES LIKE 'innodb_file_format'")
                ->fetch(\PDO::FETCH_OBJ)
            ;

            // The InnoDB file format is not Barracuda
            if ('barracuda' !== strtolower((string) $row->Value)) {
                $context['errorCode'] = 6;

                return true;
            }
        }

        return false;
    }
Checks the database configuration.