From 66cd923006730be17a68368f127acbf9eaeb62b0 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Mon, 20 Aug 2012 14:56:35 -0400
Subject: [PATCH] Implemented automatic database table structure changes in
 upgrade process.

---
 .../VuFind/Controller/Plugin/DbUpgrade.php    | 55 ++++++++++++++-----
 .../VuFind/Controller/UpgradeController.php   |  2 +-
 2 files changed, 41 insertions(+), 16 deletions(-)

diff --git a/module/VuFind/src/VuFind/Controller/Plugin/DbUpgrade.php b/module/VuFind/src/VuFind/Controller/Plugin/DbUpgrade.php
index 67d95bfb8fe..2d4b9d0bf10 100644
--- a/module/VuFind/src/VuFind/Controller/Plugin/DbUpgrade.php
+++ b/module/VuFind/src/VuFind/Controller/Plugin/DbUpgrade.php
@@ -108,9 +108,7 @@ class DbUpgrade extends AbstractPlugin
      */
     public function query($sql)
     {
-        /* TODO
         $this->getAdapter()->query($sql, DbAdapter::QUERY_MODE_EXECUTE);
-         */
     }
 
     /**
@@ -154,7 +152,7 @@ class DbUpgrade extends AbstractPlugin
      */
     protected function getTableColumns($table)
     {
-        $info = $this->getTableInfo();
+        $info = $this->getTableInfo(true);
         $columns = isset($info[$table]) ? $info[$table]->getColumns() : array();
         $retVal = array();
         foreach ($columns as $current) {
@@ -239,6 +237,43 @@ class DbUpgrade extends AbstractPlugin
         return $missing;
     }
 
+    /**
+     * Given a table column object, return true if the object's type matches the
+     * specified $type parameter.  Return false if there is a mismatch that will
+     * require table structure updates.
+     *
+     * @param \Zend\Db\Metadata\Object\ColumnObject $column       Object to check
+     * @param string                                $expectedType Type to compare
+     *
+     * @return bool
+     */
+    protected function typeMatches($column, $expectedType)
+    {
+        // Get base type:
+        $type = $column->getDataType();
+
+        // If it's not a blob or a text (which don't have explicit sizes in our SQL),
+        // we should see what the character length is, if any:
+        if ($type != 'blob' && $type != 'text') {
+            $charLen = $column->getCharacterMaximumLength();
+            if ($charLen) {
+                $type .= '(' . $charLen . ')';
+            }
+        }
+
+        // If it's an integer, the expected type will have a parenthetical value;
+        // this is a display width which we can't retrieve using the column metadata
+        // object.  Since display width is not important to VuFind, we should ignore
+        // this factor when comparing things.
+        if ($type == 'int' || $type == 'tinyint' || $type == 'smallint'
+            || $type == 'mediumint' || $type == 'bigint'
+        ) {
+            list($expectedType) = explode('(', $expectedType);
+        }
+
+        return $type == $expectedType;
+    }
+
     /**
      * Get a list of changed columns in the database tables (associative array,
      * key = table name, value = array of column name => new data type).
@@ -248,7 +283,6 @@ class DbUpgrade extends AbstractPlugin
      */
     public function getModifiedColumns()
     {
-        /* TODO
         $missing = array();
         foreach ($this->dbCommands as $table => $sql) {
             // Parse column names out of the CREATE TABLE SQL, which will always be
@@ -274,16 +308,8 @@ class DbUpgrade extends AbstractPlugin
             // Now check for mismatched types:
             $actualColumns = $this->getTableColumns($table);
             foreach ($expectedColumns as $i => $column) {
-                $type = $actualColumns[$column]->getDataType();
-                $charLen = $actualColumns[$column]->getCharacterMaximumLength();
-                if ($charLen) {
-                    $type .= '(' . $charLen . ')';
-                }
-                $precision = $actualColumns[$column]->getNumericPrecision();
-                if ($precision) {
-                    $type .= '(' . $precision . ')';
-                }
-                if ($type != $expectedTypes[$i]) {
+                $currentColumn = $actualColumns[$column];
+                if (!$this->typeMatches($currentColumn, $expectedTypes[$i])) {
                     if (!isset($missing[$table])) {
                         $missing[$table] = array();
                     }
@@ -292,7 +318,6 @@ class DbUpgrade extends AbstractPlugin
             }
         }
         return $missing;
-         */
     }
 
     /**
diff --git a/module/VuFind/src/VuFind/Controller/UpgradeController.php b/module/VuFind/src/VuFind/Controller/UpgradeController.php
index 986179925ca..381047f7f4f 100644
--- a/module/VuFind/src/VuFind/Controller/UpgradeController.php
+++ b/module/VuFind/src/VuFind/Controller/UpgradeController.php
@@ -186,7 +186,6 @@ class UpgradeController extends AbstractBase
                 ->setAdapter(DbGlobalAdapter::getStaticAdapter())
                 ->loadSql(APPLICATION_PATH . '/module/VuFind/sql/mysql.sql');
 
-            /* TODO
             // Check for missing tables.  Note that we need to finish dealing with
             // missing tables before we proceed to the missing columns check, or else
             // the missing tables will cause fatal errors during the column test.
@@ -247,6 +246,7 @@ class UpgradeController extends AbstractBase
             unset($this->session->dbRootUser);
             unset($this->session->dbRootPass);
 
+            /* TODO
             // Check for legacy "anonymous tag" bug:
             $anonymousTags = VuFind_Model_Db_Tags::getAnonymousCount();
             if ($anonymousTags > 0 && !isset($this->cookie->skipAnonymousTags)) {
-- 
GitLab