diff --git a/boot.php b/boot.php index 3efd065f3e..5973156ecd 100644 --- a/boot.php +++ b/boot.php @@ -28,9 +28,9 @@ use Friendica\Core\L10n; use Friendica\Core\PConfig; use Friendica\Core\Protocol; use Friendica\Core\System; +use Friendica\Core\Update; use Friendica\Core\Worker; use Friendica\Database\DBA; -use Friendica\Database\DBStructure; use Friendica\Model\Contact; use Friendica\Model\Conversation; use Friendica\Util\DateTimeFormat; @@ -454,7 +454,7 @@ function check_db($via_worker) if ($build < DB_UPDATE_VERSION) { // When we cannot execute the database update via the worker, we will do it directly if (!Worker::add(PRIORITY_CRITICAL, 'DBUpdate') && $via_worker) { - update_db(); + Update::run(); } } } diff --git a/src/Core/Console/DatabaseStructure.php b/src/Core/Console/DatabaseStructure.php index 4b607c1e6a..7b4c4c6cf1 100644 --- a/src/Core/Console/DatabaseStructure.php +++ b/src/Core/Console/DatabaseStructure.php @@ -3,6 +3,7 @@ namespace Friendica\Core\Console; use Friendica\Core; +use Friendica\Core\Update; use Friendica\Database\DBA; use Friendica\Database\DBStructure; use RuntimeException; @@ -80,7 +81,7 @@ HELP; // run the pre_update_nnnn functions in update.php for ($x = $stored; $x < $current; $x ++) { - $r = run_update_function($x, 'pre_update'); + $r = Update::runUpdateFunction($x, 'pre_update'); if (!$r) { break; } @@ -90,7 +91,7 @@ HELP; // run the update_nnnn functions in update.php for ($x = $stored; $x < $current; $x ++) { - $r = run_update_function($x, 'update'); + $r = Update::runUpdateFunction($x, 'update'); if (!$r) { break; } diff --git a/src/Core/Update.php b/src/Core/Update.php new file mode 100644 index 0000000000..350c2572e2 --- /dev/null +++ b/src/Core/Update.php @@ -0,0 +1,123 @@ + DB_UPDATE_VERSION)) { + $build = DB_UPDATE_VERSION - 1; + Config::set('system', 'build', $build); + } + + if ($build != DB_UPDATE_VERSION) { + require_once 'update.php'; + + $stored = intval($build); + $current = intval(DB_UPDATE_VERSION); + if ($stored < $current) { + Config::load('database'); + + // Compare the current structure with the defined structure + $t = Config::get('database', 'dbupdate_' . DB_UPDATE_VERSION); + if (!is_null($t)) { + return; + } + + // run the pre_update_nnnn functions in update.php + for ($x = $stored + 1; $x <= $current; $x++) { + $r = self::runUpdateFunction($x, 'pre_update'); + if (!$r) { + break; + } + } + + Config::set('database', 'dbupdate_' . DB_UPDATE_VERSION, time()); + + // update the structure in one call + $retval = DBStructure::update(false, true); + if ($retval) { + DBStructure::updateFail( + DB_UPDATE_VERSION, + $retval + ); + return; + } else { + Config::set('database', 'dbupdate_' . DB_UPDATE_VERSION, 'success'); + } + + // run the update_nnnn functions in update.php + for ($x = $stored + 1; $x <= $current; $x++) { + $r = self::runUpdateFunction($x, 'update'); + if (!$r) { + break; + } + } + } + } + } + + /** + * Executes a specific update function + * + * @param int $x the DB version number of the function + * @param string $prefix the prefix of the function (update, pre_update) + * + * @return bool true, if the update function worked + */ + public static function runUpdateFunction($x, $prefix) + { + $funcname = $prefix . '_' . $x; + + if (function_exists($funcname)) { + // There could be a lot of processes running or about to run. + // We want exactly one process to run the update command. + // So store the fact that we're taking responsibility + // after first checking to see if somebody else already has. + // If the update fails or times-out completely you may need to + // delete the config entry to try again. + + $t = Config::get('database', $funcname); + if (!is_null($t)) { + return false; + } + Config::set('database', $funcname, time()); + + // call the specific update + $retval = $funcname(); + + if ($retval) { + //send the administrator an e-mail + DBStructure::updateFail( + $x, + L10n::t('Update %s failed. See error logs.', $x) + ); + return false; + } else { + Config::set('database', $funcname, 'success'); + + if ($prefix == 'update') { + Config::set('system', 'build', $x); + } + + return true; + } + } else { + Config::set('database', $funcname, 'success'); + + if ($prefix == 'update') { + Config::set('system', 'build', $x); + } + + return true; + } + } +} \ No newline at end of file diff --git a/src/Worker/DBUpdate.php b/src/Worker/DBUpdate.php index ed8e409e98..fcf07c0b65 100644 --- a/src/Worker/DBUpdate.php +++ b/src/Worker/DBUpdate.php @@ -6,17 +6,16 @@ namespace Friendica\Worker; use Friendica\Core\Config; +use Friendica\Core\Update; class DBUpdate { public static function execute() { - $a = \Friendica\BaseObject::getApp(); - // We are deleting the latest dbupdate entry. // This is done to avoid endless loops because the update was interupted. Config::delete('database', 'dbupdate_'.DB_UPDATE_VERSION); - update_db($a); + Update::run(); } }