? .hosting.module.swp
? ports
? migrate/.hosting_migrate.module.swp
? package/.hosting_package.install.swp
? package/.hosting_package.instance.inc.swp
? task/.hosting_task.install.swp
Index: migrate/hosting_migrate.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hosting/migrate/hosting_migrate.module,v
retrieving revision 1.20
diff -u -r1.20 hosting_migrate.module
--- migrate/hosting_migrate.module	2 Sep 2009 10:47:08 -0000	1.20
+++ migrate/hosting_migrate.module	22 Sep 2009 03:13:16 -0000
@@ -20,6 +20,19 @@
   );
 }
 
+function hosting_migrate_menu() {
+  // TODO: add some security here
+  $items['hosting/migrate/compare'] = array(
+    'title' => 'Compare packages',
+    'page callback' => 'hosting_migrate_comparison',
+
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK
+  );
+
+
+  return $items;
+}
 
 
 
@@ -33,30 +46,15 @@
 }
 
 function hosting_migrate_theme($existing, $type, $theme, $path) {
-  return array('hosting_task_migrate_form' => array('arguments' => array('form' => NULL)));
+  return array(
+  'hosting_migrate_comparison' => array(
+      'arguments' => array('packages')
+  ));
 }
 
 function hosting_task_migrate_form($node) {
-  $site_instances = hosting_package_instances_load(
-    array('rid' => $node->nid, 'i.status' => 1));
-
-  $site_platform = node_load($node->platform);
-  $cols = array();
 
   $packages = array();
-  $form['radios']['#tree'] = false;
-  $form['radios'][$node->platform]['parameters']['#tree'] = TRUE;
-  $form['radios'][$node->platform]['parameters']['target_platform'] = array(
-    '#type' => 'radio',
-    '#title' => t('Current'),
-    '#default_value' => $node->platform,
-    '#disabled' => TRUE,
-    "#return_value" => $node->platform,
-  );
-  foreach ($site_instances as $instance) {
-    $packages[$node->platform][$instance->package_id] = $instance;
-  }
-
 
   $profile_platform_instances = hosting_package_instances_load(
     array('r.type' => 'platform', 'n.nid' => $node->profile));
@@ -67,29 +65,46 @@
       '#type' => 'hidden',
       '#value' => t('no_targets')); 
   }
+  $site_platform = node_load($node->platform);
 
+  $form[$node->platform]['target_platform'] = array(
+    '#type' => 'radio',
+    '#title' => $site_platform->title,
+    "#return_value" => $node->platform,
+    "#default_value" => $node->platform,
+    '#description' => t("Current platform"),
+    '#parents' => array('parameters', 'target_platform'),
+  );
   foreach ($profile_platform_instances as $profile_instance) {
     if ($profile_instance->rid != $node->platform) {
+      $status = hosting_package_comparison($node->nid, $profile_instance->iid);
+
+      $description = t("Upgrades: !upgrades, Warnings: !missing, Errors: !errors | <a href='!url'>Compare platforms</a>",
+        array(
+          '!upgrades' => $status['upgrade'],
+          '!missing' => $status['missing'],
+          '!errors' => $status['error'],
+          '!url' => url('hosting/migrate/compare/' . $node->nid . '/' . $profile_instance->iid))
+        );
       $platform = node_load($profile_instance->rid);
       if ($platform->web_server == $site_platform->web_server) {
-        $form['radios'][$platform->nid]['parameters']['#tree'] = TRUE;
-        $form['radios'][$platform->nid]['parameters']['target_platform'] = array(
+
+        $form[$platform->nid]['target_platform'] = array(
           '#type' => 'radio',
           '#title' => $platform->title,
+          '#parents' => array('parameters', 'target_platform'),
           "#return_value" => $platform->nid,
+          '#description' => $description,
         );
-
-        $platform_instances = hosting_package_instances_load(
-          array('rid' => $profile_instance->iid));
-        foreach ($platform_instances as $instance) {
-          $packages[$platform->nid][$instance->package_id] = $instance;
-        }
       }
+      if ($status['error']) {
+        $form[$platform->nid]['target_platform']['#disabled'] = TRUE;
+      }
+
     }
   }
+
   $form['#node'] = $node;
-  $form['#packages'] = $packages;
-  $form['#theme'] = 'hosting_task_migrate_form';
   return $form;
   $table = array();
 
@@ -109,60 +124,67 @@
   return $form;
 }
 
-function theme_hosting_task_migrate_form(&$form) {
-  $node = $form['#node'];
-  $packages = $form['#packages'];
-  $headers = array();
-  $rows = array();
+function hosting_migrate_comparison($current, $target) {
 
-  $headers[] = t("Platform");
-  foreach ($packages[$node->platform] as $package_instance) {
-    $headers[] = array('class' => 'hosting-package-name', 'data' => '<acronym title=' . $package_instance->package_type . '>' . $package_instance->title . '</acronym>');
-  }
-  foreach ($packages as $platform => $package_instances) {
-    $row = array();
-    foreach ($packages[$node->platform] as $key => $platform_instance) {
-      if ($instance = $package_instances[$key]) {
-        $comparison = hosting_package_instance_version_compare($platform_instance, $instance);
-        $display = $instance->version;
-        if ($instance->schema_version) {
-          $display .= " (" . $instance->schema_version . ")";
-        }
-        if ($comparison > 0) {
-          $row[] = array('class' => 'hosting-package-upgrade', 'data' => $display);
-        }
-        elseif ($comparison == 0) {
-          $row[] = array('class' => 'hosting-package-same', 'data' => $display);
-        }
-        else {
-          $row[] = array('class' => 'hosting-package-downgrade', 'data' => $display);
-          $error = TRUE;
-        }
-      }
-      else {
-        $row[] = array('class' => 'hosting-package-missing', 'data' => t("Missing"));
-        $warning = TRUE;
-      }
+  _hosting_package_temporary_table("current", $current);
+  _hosting_package_temporary_table("target", $target);
+
+  $packages = array();
+
+  $result = db_query("SELECT c.nid, c.short_name, 
+    c.version as current_version, t.version as target_version,
+    c.version_code as current_version_code, t.version_code as target_version_code,
+    c.schema_version as current_schema, t.schema_version as target_schema FROM current c LEFT JOIN target t ON c.nid=t.nid ORDER BY short_name"); 
+
+  while ($obj = db_fetch_object($result)) {
+    if (is_null($obj->target_version_code)) {
+      $obj->status = 'missing';
     }
-    $class = 'hosting-package-upgrade';
-    if ($platform == $node->platform) {
-      $class = 'hosting-package-same';
+    elseif (  ($obj->current_version_code > $obj->target_version_code) 
+      || ($obj->current_schema > $obj->target_schema)) {
+      $obj->status = 'downgrade';
     }
-    elseif ($error) {
-      $class = 'hosting-package-downgrade';
-      $form['radios'][$platform]['parameters']['target_platform']['#attributes']['disabled'] = 'disabled';
+    elseif ($obj->current_version_code < $obj->target_version_code) {
+      $obj->status = 'upgrade';
     }
-    elseif ($warning) {
-      $class = 'hosting-package-missing';
+    else {  
+      $obj->status = 'same';
     }
-    $platform_col = array('class' => $class, 'data' =>  drupal_render($form['radios'][$platform]['parameters']['target_platform']));
-    array_unshift($row, $platform_col);
-    $rows[] = $row;
+    $packages[$obj->nid] = $obj;
+  }
+  
+  db_query("DROP TEMPORARY TABLE target");
+  db_query("DROP TEMPORARY TABLE current");
+
+  return theme("hosting_migrate_comparison", $packages);
+}
+
+function _hosting_migrate_version_display($version, $schema = null, $status = null) {
+  
+  $status = (!is_null($status)) ? $status : 'same';
+  $display = $version;
+  if ($schema) {
+    $display .= " (" . $schema . ")";
   }
 
-  $output .= "<div id='hosting-package-comparison'>" . theme('table', $headers, $rows) . "</div>";
 
-  $output .= drupal_render($form);
-  return $output;
+  if ($status == 'missing') {
+    $display = t('Missing');
+  }
+  return array('class' => 'hosting-package-' . $status, 'data' => $display);
 }
 
+function theme_hosting_migrate_comparison($packages) {
+  $rows = array();
+
+  $headers = array(t("Package"), t("Current"), t("Target"));
+  foreach ($packages as $key => $instance) {
+    $row = array();
+    $row[] = $instance->short_name;
+
+    $row[] = _hosting_migrate_version_display($instance->current_version, $instance->current_schema);
+    $row[] = _hosting_migrate_version_display($instance->target_version, $instance->target_schema, $instance->status);
+    $rows[] = $row;
+  }
+  return "<div id='hosting-package-comparison'>" . theme('table', $headers, $rows) . "</div>";
+}
Index: package/hosting_package.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hosting/package/hosting_package.install,v
retrieving revision 1.11
diff -u -r1.11 hosting_package.install
--- package/hosting_package.install	28 May 2009 00:27:23 -0000	1.11
+++ package/hosting_package.install	22 Sep 2009 03:13:17 -0000
@@ -73,6 +73,12 @@
         'not null' => TRUE,
         'default' => '',
       ),
+      'version_code' => array(
+        'type' => 'int',
+        'size' => 'big',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
       'status' => array(
         'type' => 'int',
         'not null' => TRUE,
@@ -230,6 +236,7 @@
 function hosting_package_update_7() {
   $ret = array();
 
+
   db_drop_primary_key($ret, 'hosting_package_instance');
   db_field_set_no_default($ret, 'hosting_package_instance', 'iid');
   db_change_field($ret, 'hosting_package_instance', 'iid', 'iid',
@@ -238,3 +245,20 @@
 
   return $ret;
 }
+
+function hosting_package_update_8() {
+  include_once(drupal_get_path('module', 'hosting_package') . '/hosting_package.instance.inc');
+  $ret = array();
+  db_add_field($ret, 'hosting_package_instance', 'version_code', array(
+      'type' => 'int',
+      'size' => 'big',
+      'not null' => TRUE,
+      'default' => 0,
+    ));
+  $result = db_query("SELECT iid, version FROM {hosting_package_instance}");
+  while ($obj = db_fetch_object($result)) {
+    $code = hosting_package_instance_version_code($obj->version);
+    db_query("UPDATE {hosting_package_instance} SET version_code = %f WHERE iid = %d", $code, $obj->iid);
+  }
+  return $ret;
+}
Index: package/hosting_package.instance.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hosting/package/hosting_package.instance.inc,v
retrieving revision 1.5
diff -u -r1.5 hosting_package.instance.inc
--- package/hosting_package.instance.inc	28 May 2009 00:27:23 -0000	1.5
+++ package/hosting_package.instance.inc	22 Sep 2009 03:13:17 -0000
@@ -42,6 +42,7 @@
       $instance->languages = $package['info']['languages'];
       $instance->filename = $package['filename'];
       $instance->version = ($package['version']) ? $package['version'] : 'Unknown';
+      $instance->version_code = hosting_package_instance_version_code($package['version']);
       $instance->schema_version = $package['schema_version'];
       if (array_key_exists('status', $package)) {
         $instance->status = $package['status'];
@@ -67,10 +68,10 @@
 function hosting_package_instance_update(&$instance) {
   db_query("UPDATE {hosting_package_instance} SET
     rid = %d, package_id = %d, filename = '%s',
-    schema_version = %d, version = '%s', status = %d
+    schema_version = %d, version = '%s', version_code = %f, status = %d
     WHERE iid = %d", 
     $instance->rid, $instance->package_id, $instance->filename, 
-    $instance->schema_version, $instance->version, $instance->status,
+    $instance->schema_version, $instance->version, $instance->version_code, $instance->status,
     $instance->iid);
 
   _hosting_package_instance_languages($instance);
@@ -79,10 +80,10 @@
 function hosting_package_instance_create(&$instance) {
    db_query("INSERT INTO {hosting_package_instance} (
       rid, package_id, filename,
-      schema_version, version, status)
-      VALUES (%d, %d, '%s', %d, '%s', %d)", 
+      schema_version, version, version_code, status)
+      VALUES (%d, %d, '%s', %d, %f, '%s', %d)", 
       $instance->rid, $instance->package_id, $instance->filename, 
-      $instance->schema_version, $instance->version, $instance->status);
+      $instance->schema_version, $instance->version, $instance->version_code, $instance->status);
    $instance->iid = db_last_insert_id('hosting_package_instance', 'iid');
    _hosting_package_instance_languages($instance);
 }
@@ -115,7 +116,7 @@
   $instances = array();
   $result = db_query("SELECT 
       n.title, r.type, p.package_type, p.nid,
-      i.iid, i.version, i.schema_version,
+      i.iid, i.version, i.version_code, i.schema_version,
       i.status, p.description, p.short_name, i.rid,
       i.package_id
       FROM {hosting_package_instance} i 
@@ -156,44 +157,86 @@
   db_query("DELETE FROM {hosting_package_instance} WHERE iid = %d", $instance->iid);
 }
 
-function hosting_package_instance_version_compare($from, $to) {
-  if ($from->version == $to->version) {
+
+/**
+ * Turn package version string into a number
+ *
+ * This function returns a float value for the number that represents the
+ * version string.
+ */
+function hosting_package_instance_version_code($version) {
+
+  $defaults = array(
+    'platform_major' => 0,
+    'platform_minor' => 0,
+    'package_major' => 0,
+    'package_minor' => 0,
+    'package_version_type' => 'release',
+    'package_patch_level' => 0,
+  );
+
+  $release_types = array(
+    '' => 0,
+    'dev' => 0,
+    'unstable' => 1,
+    'alpha' => 2,
+    'beta' => 3,
+    'rc' => 4,
+    'release' => 5
+  );
+
+  $regex = array(
+    'core' => '/^(?<platform_major>\d?)\.(?<platform_minor>[x\d]*)?(-(?<package_version_type>dev|unstable|alpha|beta|rc)?(?<package_patch_level>\d)*)?$/',
+    'contrib' => "/(?<platform_major>\d?)\.(?<platform_minor>[x\d]*)?(-(?<package_major>\d*)?\.(?<package_minor>[x\d]*)?(-(?<package_version_type>alpha|unstable|beta|rc|dev)?(?<package_patch_level>\d)*)?)?/");
+
+  $matches = array();
+  if (preg_match($regex['core'], $version, $matches)) {
+    $matches = array_merge($defaults, $matches);
+  }
+  elseif (preg_match($regex['contrib'], $version, $matches)) {
+    $matches = array_merge($defaults, $matches);
+  }
+  else {
     return 0;
   }
+  // we use the float type because php generally has a maximum integer value to small to handle this value
+  $result =  (float) sprintf("%d%02d%02d%02d%02d%02d", 
+    $matches['platform_major'], $matches['platform_minor'], $matches['package_major'], 
+    $matches['package_minor'], $release_types[$matches['package_version_type']], 
+    $matches['package_patch_level']);
+
+  return $result;
+}
+
+function hosting_package_comparison($current, $target) {
 
-#  if (isset($from->schema_version)) {
-#    if ($to->schema_version > $from->schema_version) {
-#      return 1;
-#    }
-#  }
-
-  if (in_array($from->version, array('Unknown', 'HEAD'))) {
-    if (!in_array($to->version, array('Unknown', 'HEAD'))) {
-      return 1;
-    }
-  }
-  _hosting_version_info_extract($from);
-  _hosting_version_info_extract($to);
-  $compare = version_compare($to->drupal_version, $from->drupal_version);
-  if ($compare == 0) {
-    $compare = version_compare($to->project_version, $from->project_version);
-  }
-  return $compare;
-}
-
-function _hosting_version_info_extract(&$instance) {
-  $parts = explode('-', $instance->version);
-  switch (sizeof($parts)) {
-    case '3' :
-      $instance->project_version = str_replace(".x", ".0", $parts[1]) . "." . $parts[2];
-      $instance->drupal_version = str_replace(".x", ".0", $parts[0]);
-      break;
-    case '2' :
-      $instance->project_version = str_replace(".x", ".0", $parts[1]);
-      $instance->drupal_version = str_replace(".x", ".0", $parts[0]);
-      break;
-    case '1' :
-      $instance->drupal_version = str_replace(".x", ".0", $parts[0]);
-      break;
+  _hosting_package_temporary_table("current", $current);
+  _hosting_package_temporary_table("target", $target);
+  
+  $missing = 0;
+  $error = 0;
+  $upgrade = 0;
+  $result = db_query("SELECT c.nid, t.version_code FROM current c LEFT JOIN target t ON c.nid=t.nid WHERE c.version_code > t.version_code OR c.schema_version > t.schema_version");
+  while ($obj = db_fetch_object($result)) {
+    if (is_null($obj->version_code)) {
+      $missing = $missing + 1;
+    }
+    else {
+      $error = $error + 1;
+    }
   }
+  $result = db_query("SELECT COUNT(c.nid) as upgrades FROM  current c LEFT JOIN target t ON c.nid=t.nid WHERE c.version_code < t.version_code");
+  while ($obj = db_fetch_object($result)) {
+    $upgrade = $obj->upgrades;
+  }
+  
+  db_query("DROP TEMPORARY TABLE target");
+  db_query("DROP TEMPORARY TABLE current");
+
+  return array("upgrade" => $upgrade, "missing" => $missing, "error" => $error);
+}
+
+
+function _hosting_package_temporary_table($name, $ref) {
+  db_query("CREATE TEMPORARY TABLE %s AS SELECT nid, short_name, version_code, schema_version, version from hosting_package p left join hosting_package_instance i on p.nid = i.package_id where rid= %d", $name, $ref);
 }
