/** * Constructor: builds array of $changeItems by processing the .sql files in a folder. * The folder for the Joomla core updates is `administrator/components/com_admin/sql/updates/<database>`. * * @param JDatabaseDriver $db The current database object * @param string $folder The full path to the folder containing the update queries * * @since 2.5 */ public function __construct($db, $folder = null) { $this->db = $db; $this->folder = $folder; $updateFiles = $this->getUpdateFiles(); $updateQueries = $this->getUpdateQueries($updateFiles); foreach ($updateQueries as $obj) { $changeItem = JSchemaChangeitem::getInstance($db, $obj->file, $obj->updateQuery); if ($changeItem->queryType === 'UTF8CNV') { // Execute the special update query for utf8mb4 conversion status reset try { $this->db->setQuery($changeItem->updateQuery)->execute(); } catch (RuntimeException $e) { JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); } } else { // Normal change item $this->changeItems[] = $changeItem; } } // If on mysql, add a query at the end to check for utf8mb4 conversion status $serverType = $this->db->getServerType(); if ($serverType == 'mysql') { // Let the update query be something harmless which should always succeed $tmpSchemaChangeItem = JSchemaChangeitem::getInstance($db, 'database.php', 'UPDATE ' . $this->db->quoteName('#__utf8_conversion') . ' SET ' . $this->db->quoteName('converted') . ' = 0;'); // Set to not skipped $tmpSchemaChangeItem->checkStatus = 0; // Set the check query if ($this->db->hasUTF8mb4Support()) { $converted = 2; $tmpSchemaChangeItem->queryType = 'UTF8_CONVERSION_UTF8MB4'; } else { $converted = 1; $tmpSchemaChangeItem->queryType = 'UTF8_CONVERSION_UTF8'; } $tmpSchemaChangeItem->checkQuery = 'SELECT ' . $this->db->quoteName('converted') . ' FROM ' . $this->db->quoteName('#__utf8_conversion') . ' WHERE ' . $this->db->quoteName('converted') . ' = ' . $converted; // Set expected records from check query $tmpSchemaChangeItem->checkQueryExpected = 1; $tmpSchemaChangeItem->msgElements = array(); $this->changeItems[] = $tmpSchemaChangeItem; } }
/** * Method to import a database schema from a file. * * @param JDatabaseDriver $db JDatabase object. * @param string $schema Path to the schema file. * * @return boolean True on success. * * @since 3.1 */ public function populateDatabase($db, $schema) { // Get the application /* @var InstallationApplicationWeb $app */ $app = JFactory::getApplication(); $return = true; // Get the contents of the schema file. if (!($buffer = file_get_contents($schema))) { $app->enqueueMessage($db->getErrorMsg(), 'notice'); return false; } // Get an array of queries from the schema and process them. $queries = $this->_splitQueries($buffer); foreach ($queries as $query) { // Trim any whitespace. $query = trim($query); // If the query isn't empty and is not a MySQL or PostgreSQL comment, execute it. if (!empty($query) && $query[0] != '#' && $query[0] != '-') { /** * If we don't have UTF-8 Multibyte support we'll have to convert queries to plain UTF-8 * * Note: the JDatabaseDriver::convertUtf8mb4QueryToUtf8 performs the conversion ONLY when * necessary, so there's no need to check the conditions in JInstaller. */ $query = $db->convertUtf8mb4QueryToUtf8($query); /** * This is a query which was supposed to convert tables to utf8mb4 charset but the server doesn't * support utf8mb4. Therefore we don't have to run it, it has no effect and it's a mere waste of time. */ if (!$db->hasUTF8mb4Support() && stristr($query, 'CONVERT TO CHARACTER SET utf8 ')) { continue; } // Execute the query. $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $app->enqueueMessage($e->getMessage(), 'notice'); $return = false; } } } return $return; }