From ecb008791f0ff61ae1f6d5447af9eabc1bb8ec41 Mon Sep 17 00:00:00 2001
From: Tom Swiggers <tom.swiggers@inuits.be>
Date: Tue, 8 Mar 2011 13:44:52 +0100
Subject: [PATCH 1/3] Issue #1085000 by tomswiggers: extra parameters for updatedb

---
 commands/core/core.drush.inc      |   31 +++++++++++++++++++++++++++++--
 commands/core/drupal/update_6.inc |   18 ++++++++++++++++--
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/commands/core/core.drush.inc b/commands/core/core.drush.inc
index 6f61797..1bbc3b5 100644
--- a/commands/core/core.drush.inc
+++ b/commands/core/core.drush.inc
@@ -61,6 +61,10 @@ function core_drush_command() {
     'description' => 'Apply any database updates required (as with running update.php).',
     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_SITE,
     'aliases' => array('updb'),
+    'options' => array(
+      'module' => 'Module name',
+      'number' => 'Schema version number'
+    )
   );
   $items['core-status'] = array(
     'description' => 'Provides a birds-eye view of the current Drupal installation, if any.',
@@ -275,14 +279,37 @@ function core_drush_engine_drupal() {
  * Command handler. Execute update.php code from drush.
  */
 function drush_core_updatedb() {
+  $update_main = TRUE;
+  $args = func_get_args();
+
   if (drush_get_context('DRUSH_SIMULATE')) {
     drush_log(dt('updatedb command does not support --simulate option.'), 'ok');
     return TRUE;
   }
 
   drush_include_engine('drupal', 'update', drush_drupal_major_version());
-  if (update_main() === FALSE) {
-    return FALSE;
+
+  if (is_array($args) && !empty($args) && count($args) >= 2) {
+
+    if (drush_drupal_major_version() != 6) {
+      drush_log(dt('Not supported for other version than 6'), 'error');
+      return FALSE;
+    }
+
+    drush_log(dt('Perform update @number for module @module.', array('@module' => $args[0], '@number' => $args[1])), 'ok');
+
+    $context = array('results' => array($args[0] => array('#abort' => FALSE)));
+
+    update_main_prepare();
+    _update_do_one($args[0], $args[1], $context);
+    $update_main = FALSE;
+  }
+
+  if ($update_main) {
+
+    if (update_main() === FALSE) {
+      return FALSE;
+    }
   }
 
   if (drush_drupal_major_version() <= 6) {
diff --git a/commands/core/drupal/update_6.inc b/commands/core/drupal/update_6.inc
index f3bcc50..42937b3 100644
--- a/commands/core/drupal/update_6.inc
+++ b/commands/core/drupal/update_6.inc
@@ -478,12 +478,14 @@ function _update_do_one($module, $number, &$context) {
   }
 
   $function = $module .'_update_'. $number;
-  drush_log("Executing $function", 'success');
 
   if (function_exists($function)) {
+    drush_log("Executing $function", 'success');
     $ret = $function($context['sandbox']);
     $context['results'][$module] = $ret;
     _drush_log_update_sql($ret);
+  } else {
+    drush_log("Function $function doesn't exists.", 'error');
   }
 
   if (isset($ret['#finished'])) {
@@ -491,7 +493,7 @@ function _update_do_one($module, $number, &$context) {
     unset($ret['#finished']);
   }
 
-  if ($context['finished'] == 1 && empty($context['results'][$module]['#abort'])) {
+  if ($context['finished'] == 1 && empty($context['results'][$module]['#abort']) && $number > _get_installed_schema_version($module)) {
     drupal_set_installed_schema_version($module, $number);
   }
 
@@ -502,3 +504,15 @@ function _update_batch_command($id) {
   drush_batch_command($id);
 }
 
+/**
+ * Get the installed schema version for a given module
+ */
+function _get_installed_schema_version($name) {
+  $record = db_fetch_object(db_query("SELECT schema_version FROM {system} WHERE name = '%s'", $name));
+
+  if ($record->schema_version) {
+    return $record->schema_version;
+  } else {
+    return -1;
+  }
+}
-- 
1.7.1


From 146e1880158b336ae15747f8ec9aeb6d38fe1137 Mon Sep 17 00:00:00 2001
From: Tom Swiggers <tom.swiggers@inuits.be>
Date: Fri, 11 Mar 2011 14:38:01 +0100
Subject: [PATCH 2/3] Issue #1085000 by tomswiggers: extra parameters for updatedb, more functionality

---
 commands/core/core.drush.inc      |   29 ++++++++++--
 commands/core/drupal/update_6.inc |   90 ++++++++++++++++++++++---------------
 2 files changed, 78 insertions(+), 41 deletions(-)

diff --git a/commands/core/core.drush.inc b/commands/core/core.drush.inc
index 1bbc3b5..7abe5d4 100644
--- a/commands/core/core.drush.inc
+++ b/commands/core/core.drush.inc
@@ -61,7 +61,7 @@ function core_drush_command() {
     'description' => 'Apply any database updates required (as with running update.php).',
     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_SITE,
     'aliases' => array('updb'),
-    'options' => array(
+    'arguments' => array(
       'module' => 'Module name',
       'number' => 'Schema version number'
     )
@@ -281,6 +281,7 @@ function core_drush_engine_drupal() {
 function drush_core_updatedb() {
   $update_main = TRUE;
   $args = func_get_args();
+  $conditions = NULL;
 
   if (drush_get_context('DRUSH_SIMULATE')) {
     drush_log(dt('updatedb command does not support --simulate option.'), 'ok');
@@ -289,13 +290,13 @@ function drush_core_updatedb() {
 
   drush_include_engine('drupal', 'update', drush_drupal_major_version());
 
-  if (is_array($args) && !empty($args) && count($args) >= 2) {
+  if (is_array($args) && !empty($args)) {
 
     if (drush_drupal_major_version() != 6) {
       drush_log(dt('Not supported for other version than 6'), 'error');
       return FALSE;
     }
-
+/*
     drush_log(dt('Perform update @number for module @module.', array('@module' => $args[0], '@number' => $args[1])), 'ok');
 
     $context = array('results' => array($args[0] => array('#abort' => FALSE)));
@@ -303,11 +304,19 @@ function drush_core_updatedb() {
     update_main_prepare();
     _update_do_one($args[0], $args[1], $context);
     $update_main = FALSE;
+*/
+
+    $conditions = new stdClass();
+    $conditions->module = $args[0];
+
+    if (count($args) >= 2) {
+      $conditions->update_nbr = $args[1];
+    }
   }
 
   if ($update_main) {
 
-    if (update_main() === FALSE) {
+    if (update_main($conditions) === FALSE) {
       return FALSE;
     }
   }
@@ -326,6 +335,18 @@ function drush_core_updatedb() {
 }
 
 /**
+ * Check if the $update_nbr can be performed 
+ */
+function _update_check_perform_update($update_nbr, $schema_version, $conditions = NULL) {
+  
+  if (!is_null($conditions) && $conditions->update_nbr) {
+    return $conditions->update_nbr == $update_nbr;
+  } else {
+    return $update_nbr > $schema_version;
+  }
+}
+
+/**
  * Implementation of hook_drush_help().
  *
  * This function is called whenever a drush user calls
diff --git a/commands/core/drupal/update_6.inc b/commands/core/drupal/update_6.inc
index 42937b3..b0f9942 100644
--- a/commands/core/drupal/update_6.inc
+++ b/commands/core/drupal/update_6.inc
@@ -367,54 +367,59 @@ function update_main_prepare() {
   // Disable anything in the {system} table that is not compatible with the current version of Drupal core.
   _drush_log_update_sql(update_fix_compatibility());
 }
-
-function update_main() {
+/**
+ * @param stdClass $conditions 
+ */
+function update_main($conditions = NULL) {
   update_main_prepare();
 
   $start = array();
   $has_updates = FALSE;
   $modules = drupal_get_installed_schema_version(NULL, FALSE, TRUE);
   foreach ($modules as $module => $schema_version) {
-    $updates = drupal_get_schema_versions($module);
-    // Skip incompatible module updates completely, otherwise test schema versions.
-    if (!update_check_incompatibility($module) && $updates !== FALSE && $schema_version >= 0) {
-      // module_invoke returns NULL for nonexisting hooks, so if no updates
-      // are removed, it will == 0.
-      $last_removed = module_invoke($module, 'update_last_removed');
-      if ($schema_version < $last_removed) {
-        drush_set_error('PROVISION_DRUPAL_UPDATE_FAILED', dt( $module .' module can not be updated. Its schema version is '. $schema_version .'. Updates up to and including '. $last_removed .' have been removed in this release. In order to update '. $module .' module, you will first <a href="http://drupal.org/upgrade">need to upgrade</a> to the last version in which these updates were available.'));
-        continue;
-      }
 
-      $updates = drupal_map_assoc($updates);
-      foreach (array_keys($updates) as $update) {
-        if ($update > $schema_version) {
-          $start[$module] = $update;
-          break;
+    //check if module is in the conditions object, if so check if module is the same
+    if ((!is_null($conditions) && ($module == $conditions->module)) || is_null($conditions)) {
+      $updates = drupal_get_schema_versions($module);
+      // Skip incompatible module updates completely, otherwise test schema versions.
+      if (!update_check_incompatibility($module) && $updates !== FALSE && $schema_version >= 0) {
+        // module_invoke returns NULL for nonexisting hooks, so if no updates
+        // are removed, it will == 0.
+        $last_removed = module_invoke($module, 'update_last_removed');
+        if ($schema_version < $last_removed) {
+          drush_set_error('PROVISION_DRUPAL_UPDATE_FAILED', dt( $module .' module can not be updated. Its schema version is '. $schema_version .'. Updates up to and including '. $last_removed .' have been removed in this release. In order to update '. $module .' module, you will first <a href="http://drupal.org/upgrade">need to upgrade</a> to the last version in which these updates were available.'));
+          continue;
         }
-      }
 
-      // Record any pending updates. Used for confirmation prompt.
-      foreach (array_keys($updates) as $update) {
-        if ($update > $schema_version) {
-          if (class_exists('ReflectionFunction')) {
-            // The description for an update comes from its Doxygen.
-            $func = new ReflectionFunction($module. '_update_'. $update);
-            $description = str_replace(array("\n", '*', '/'), '', $func->getDocComment());
-          }
-          if (empty($description)) {
-            $description = dt('description not available');
+        $updates = drupal_map_assoc($updates);
+        foreach (array_keys($updates) as $update) {
+          if (_update_check_perform_update($update, $schema_version, $conditions)) {
+            $start[$module] = $update;
+            break;
           }
+        }
 
-          $pending[$module][] = array("$update - ". trim($description));
-          $has_updates = TRUE;
+        // Record any pending updates. Used for confirmation prompt.
+        foreach (array_keys($updates) as $update) {
+          if (_update_check_perform_update($update, $schema_version, $conditions)) {
+            if (class_exists('ReflectionFunction')) {
+              // The description for an update comes from its Doxygen.
+              $func = new ReflectionFunction($module. '_update_'. $update);
+              $description = str_replace(array("\n", '*', '/'), '', $func->getDocComment());
+            }
+            if (empty($description)) {
+              $description = dt('description not available');
+            }
+
+            $pending[$module][] = array("$update - ". trim($description));
+            $has_updates = TRUE;
+          }
         }
-      }
 
+      }
     }
   }
 
-
   // Print a list of pending updates for this module and get confirmation.
   if ($has_updates) {
     drush_print(dt('The following updates are pending:'));
@@ -432,14 +437,23 @@ function update_main() {
     // Proceed with running all pending updates.
     $operations = array();
     foreach ($start as $module => $version) {
-      drupal_set_installed_schema_version($module, $version - 1);
+      /**
+       * TODO why is this needed?
+       * If you use this command in this situation it will lead to unwished behavior
+       * module with updates (6001, 6002, 6003, 6004)
+       * the version is at 6004
+       * if you run drush updatedb [module] [6002]
+       * the version will be set to 6002 and with the next run of update 6003 and 6004 will be executed again
+       */
+      //drupal_set_installed_schema_version($module, $version - 1);
       $updates = drupal_get_schema_versions($module);
+      $schema_version = _get_installed_schema_version($module);
       $max_version = max($updates);
       if ($version <= $max_version) {
         drush_log(dt('Updating module @module from schema version @start to schema version @max', array('@module' => $module, '@start' => $version - 1, '@max' => $max_version)));
         foreach ($updates as $update) {
-          if ($update >= $version) {
-            $operations[] = array('_update_do_one', array($module, $update));
+          if (_update_check_perform_update($update, $schema_version, $conditions)) {
+            $operations[] = array('_update_do_one', array($module, $update, $schema_version));
           }
         }
       }
@@ -454,6 +468,7 @@ function update_main() {
       'error_message' => 'An unrecoverable error has occurred. You can find the error message below. It is advised to copy it to the clipboard for reference.',
       'finished' => 'update_finished',
     );
+
     batch_set($batch);
     $batch =& batch_get();
     $batch['progressive'] = FALSE;
@@ -470,7 +485,7 @@ function update_main() {
  * This does not mess with sessions and the like, as it will be used
  * from the command line
  */
-function _update_do_one($module, $number, &$context) {
+function _update_do_one($module, $number, $version, &$context) {
   // If updates for this module have been aborted
   // in a previous step, go no further.
   if (!empty($context['results'][$module]['#abort'])) {
@@ -493,7 +508,7 @@ function _update_do_one($module, $number, &$context) {
     unset($ret['#finished']);
   }
 
-  if ($context['finished'] == 1 && empty($context['results'][$module]['#abort']) && $number > _get_installed_schema_version($module)) {
+  if ($context['finished'] == 1 && empty($context['results'][$module]['#abort']) && $number > $version) {
     drupal_set_installed_schema_version($module, $number);
   }
 
@@ -516,3 +531,4 @@ function _get_installed_schema_version($name) {
     return -1;
   }
 }
+
-- 
1.7.1


From f0e0c66febce64231637027e1bb9752717363419 Mon Sep 17 00:00:00 2001
From: Tom Swiggers <tom.swiggers@inuits.be>
Date: Fri, 11 Mar 2011 15:09:43 +0100
Subject: [PATCH 3/3] Issue #1085000 by tomswiggers: extra parameters for updatedb, add examples

---
 commands/core/core.drush.inc |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/commands/core/core.drush.inc b/commands/core/core.drush.inc
index 7abe5d4..ca33b18 100644
--- a/commands/core/core.drush.inc
+++ b/commands/core/core.drush.inc
@@ -64,6 +64,11 @@ function core_drush_command() {
     'arguments' => array(
       'module' => 'Module name',
       'number' => 'Schema version number'
+    ),
+    'examples' => array(
+      'drush updatedb' => 'Run all pending updates.',
+      'drush updatedb mymodule' => 'Run all pending updates for mymodule',
+      'drush updatedb mymodule 6007' => 'Run update 6007 for mymodule',
     )
   );
   $items['core-status'] = array(
-- 
1.7.1

