diff options
Diffstat (limited to 'core/Updater.php')
-rw-r--r-- | core/Updater.php | 115 |
1 files changed, 81 insertions, 34 deletions
diff --git a/core/Updater.php b/core/Updater.php index 8b272cde66..e10c6bf33c 100644 --- a/core/Updater.php +++ b/core/Updater.php @@ -7,6 +7,7 @@ * */ namespace Piwik; +use Piwik\Columns\Updater as ColumnUpdater; /** * Load and execute all relevant, incremental update scripts for Piwik core and plugins, and bump the component version numbers for completed updates. @@ -21,6 +22,7 @@ class Updater public $pathUpdateFilePlugins; private $componentsToCheck = array(); private $hasMajorDbUpdate = false; + private $updatedClasses = array(); /** * Constructor @@ -29,6 +31,8 @@ class Updater { $this->pathUpdateFileCore = PIWIK_INCLUDE_PATH . '/core/Updates/'; $this->pathUpdateFilePlugins = PIWIK_INCLUDE_PATH . '/plugins/%s/Updates/'; + + ColumnUpdater::setUpdater($this); } /** @@ -58,6 +62,30 @@ class Updater } /** + * Retrieve the current version of a recorded component + * @param string $name + * @return false|string + * @throws \Exception + */ + public static function getCurrentRecordedComponentVersion($name) + { + try { + $currentVersion = Option::get(self::getNameInOptionTable($name)); + } catch (\Exception $e) { + // mysql error 1146: table doesn't exist + if (Db::get()->isErrNo($e, '1146')) { + // case when the option table is not yet created (before 0.2.10) + $currentVersion = false; + } else { + // failed for some other reason + throw $e; + } + } + + return $currentVersion; + } + + /** * Returns the flag name to use in the option table to record current schema version * @param string $name * @return string @@ -111,6 +139,8 @@ class Updater public function getSqlQueriesToExecute() { $queries = array(); + $classNames = array(); + foreach ($this->componentsWithUpdateFile as $componentName => $componentUpdateInfo) { foreach ($componentUpdateInfo as $file => $fileVersion) { require_once $file; // prefixed by PIWIK_INCLUDE_PATH @@ -119,6 +149,13 @@ class Updater if (!class_exists($className, false)) { throw new \Exception("The class $className was not found in $file"); } + + if (in_array($className, $classNames)) { + continue; // prevent from getting updates from Piwik\Columns\Updater multiple times + } + + $classNames[] = $className; + $queriesForComponent = call_user_func(array($className, 'getSql')); foreach ($queriesForComponent as $query => $error) { $queries[] = $query . ';'; @@ -141,6 +178,11 @@ class Updater if ($componentName == 'core') { return '\\Piwik\\Updates\\' . $className; } + + if (ColumnUpdater::isDimensionComponent($componentName)) { + return '\\Piwik\\Columns\\Updater'; + } + return '\\Piwik\\Plugins\\' . $componentName . '\\' . $className; } @@ -154,14 +196,18 @@ class Updater public function update($componentName) { $warningMessages = array(); + foreach ($this->componentsWithUpdateFile[$componentName] as $file => $fileVersion) { try { require_once $file; // prefixed by PIWIK_INCLUDE_PATH $className = $this->getUpdateClassName($componentName, $fileVersion); - if (class_exists($className, false)) { + if (!in_array($className, $this->updatedClasses) && class_exists($className, false)) { // update() call_user_func(array($className, 'update')); + // makes sure to call Piwik\Columns\Updater only once as one call updates all dimensions at the same + // time for better performance + $this->updatedClasses[] = $className; } self::recordComponentSuccessfullyUpdated($componentName, $fileVersion); @@ -185,29 +231,35 @@ class Updater private function loadComponentsWithUpdateFile() { $componentsWithUpdateFile = array(); + $hasDimensionUpdate = null; + foreach ($this->componentsWithNewVersion as $name => $versions) { $currentVersion = $versions[self::INDEX_CURRENT_VERSION]; $newVersion = $versions[self::INDEX_NEW_VERSION]; if ($name == 'core') { $pathToUpdates = $this->pathUpdateFileCore . '*.php'; + } elseif (ColumnUpdater::isDimensionComponent($name)) { + $componentsWithUpdateFile[$name][PIWIK_INCLUDE_PATH . '/core/Columns/Updater.php'] = $newVersion; } else { $pathToUpdates = sprintf($this->pathUpdateFilePlugins, $name) . '*.php'; } - $files = _glob($pathToUpdates); - if ($files == false) { - $files = array(); - } + if (!empty($pathToUpdates)) { + $files = _glob($pathToUpdates); + if ($files == false) { + $files = array(); + } - foreach ($files as $file) { - $fileVersion = basename($file, '.php'); - if ( // if the update is from a newer version - version_compare($currentVersion, $fileVersion) == -1 - // but we don't execute updates from non existing future releases - && version_compare($fileVersion, $newVersion) <= 0 - ) { - $componentsWithUpdateFile[$name][$file] = $fileVersion; + foreach ($files as $file) { + $fileVersion = basename($file, '.php'); + if ( // if the update is from a newer version + version_compare($currentVersion, $fileVersion) == -1 + // but we don't execute updates from non existing future releases + && version_compare($fileVersion, $newVersion) <= 0 + ) { + $componentsWithUpdateFile[$name][$file] = $fileVersion; + } } } @@ -219,6 +271,7 @@ class Updater self::recordComponentSuccessfullyUpdated($name, $newVersion); } } + return $componentsWithUpdateFile; } @@ -239,30 +292,24 @@ class Updater $this->componentsToCheck = array_merge(array('core' => $coreVersions), $this->componentsToCheck); } + $recordedCoreVersion = self::getCurrentRecordedComponentVersion('core'); + if ($recordedCoreVersion === false) { + // This should not happen + $recordedCoreVersion = Version::VERSION; + self::recordComponentSuccessfullyUpdated('core', $recordedCoreVersion); + } + foreach ($this->componentsToCheck as $name => $version) { - try { - $currentVersion = Option::get(self::getNameInOptionTable($name)); - } catch (\Exception $e) { - // mysql error 1146: table doesn't exist - if (Db::get()->isErrNo($e, '1146')) { - // case when the option table is not yet created (before 0.2.10) - $currentVersion = false; - } else { - // failed for some other reason - throw $e; - } - } + $currentVersion = self::getCurrentRecordedComponentVersion($name); - if ($name === 'core' && $currentVersion === false) { - // This should not happen - $currentVersion = Version::VERSION; - self::recordComponentSuccessfullyUpdated($name, $currentVersion); + if (ColumnUpdater::isDimensionComponent($name)) { + $isComponentOutdated = $currentVersion !== $version; + } else { + // note: when versionCompare == 1, the version in the DB is newer, we choose to ignore + $isComponentOutdated = version_compare($currentVersion, $version) == -1; } - // note: when versionCompare == 1, the version in the DB is newer, we choose to ignore - $currentVersionIsOutdated = version_compare($currentVersion, $version) == -1; - $isComponentOutdated = $currentVersion === false || $currentVersionIsOutdated; - if ($isComponentOutdated) { + if ($isComponentOutdated || $currentVersion === false) { $componentsToUpdate[$name] = array( self::INDEX_CURRENT_VERSION => $currentVersion, self::INDEX_NEW_VERSION => $version @@ -344,4 +391,4 @@ class Updater */ class UpdaterErrorException extends \Exception { -}
\ No newline at end of file +} |