CRM-18772 Backport check to see if column already exists
authorSeamus Lee <seamuslee001@gmail.com>
Sun, 5 Jun 2016 23:36:07 +0000 (09:36 +1000)
committerSeamus Lee <seamuslee001@gmail.com>
Mon, 6 Jun 2016 02:30:41 +0000 (12:30 +1000)
CRM/Core/BAO/SchemaHandler.php
tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php [new file with mode: 0644]

index 0abdd694c601764baa4f1c879a08c906c992a615..c99273d904ea47796577dbd62db0ad19d8a91f8b 100644 (file)
@@ -526,4 +526,42 @@ MODIFY      {$columnName} varchar( $length )
     }
   }
 
+  /**
+   * Check if the table has an index matching the name.
+   *
+   * @param string $tableName
+   * @param array $indexName
+   *
+   * @return \CRM_Core_DAO|object
+   */
+  public static function checkIfIndexExists($tableName, $indexName) {
+    $result = CRM_Core_DAO::executeQuery(
+      "SHOW INDEX FROM $tableName WHERE key_name = %1 AND seq_in_index = 1",
+      array(1 => array($indexName, 'String'))
+    );
+    if ($result->fetch()) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * Check if the table has a specified column
+   *
+   * @param string $tableName
+   * @param string $columnName
+   *
+   * @return \CRM_Core_DAO|object
+   */
+  public static function checkIfFieldExists($tableName, $columnName) {
+    $result = CRM_Core_DAO::executeQuery(
+      "SHOW COLUMNS FROM $tableName LIKE ' %1 '",
+      array(1 => array($columnName, 'mysqlColumnNameOrAlias'))
+    );
+    if ($result->fetch()) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
 }
diff --git a/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php b/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php
new file mode 100644 (file)
index 0000000..57f1d76
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2016                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * Class CRM_Core_BAO_SchemaHandlerTest.
+ *
+ * These tests create and drop indexes on the civicrm_uf_join table. The indexes
+ * being added and dropped we assume will never exist.
+ * @group headless
+ */
+class CRM_Core_BAO_SchemaHandlerTest extends CiviUnitTestCase {
+
+  /**
+   * Test creating an index.
+   *
+   * We want to be sure it creates an index and exits gracefully if the index
+   * already exists.
+   */
+  public function testCreateIndex() {
+    $tables = array('civicrm_uf_join' => array('weight'));
+    CRM_Core_BAO_SchemaHandler::createIndexes($tables);
+    CRM_Core_BAO_SchemaHandler::createIndexes($tables);
+    $dao = CRM_Core_DAO::executeQuery("SHOW INDEX FROM civicrm_uf_join");
+    $count = 0;
+
+    while ($dao->fetch()) {
+      if ($dao->Column_name == 'weight') {
+        $count++;
+        CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_uf_join DROP INDEX " . $dao->Key_name);
+      }
+    }
+    $this->assertEquals(1, $count);
+  }
+
+  /**
+   * Test creating an index.
+   *
+   * We want to be sure it creates an index and exits gracefully if the index
+   * already exists.
+   */
+  public function testCombinedIndex() {
+    $tables = array('civicrm_uf_join' => array('weight'));
+    CRM_Core_BAO_SchemaHandler::createIndexes($tables);
+
+    $tables = array('civicrm_uf_join' => array(array('weight', 'module')));
+    CRM_Core_BAO_SchemaHandler::createIndexes($tables);
+    $dao = CRM_Core_DAO::executeQuery("SHOW INDEX FROM civicrm_uf_join");
+    $weightCount = 0;
+    $combinedCount = 0;
+    $indexes = array();
+
+    while ($dao->fetch()) {
+      if ($dao->Column_name == 'weight') {
+        $weightCount++;
+        $indexes[$dao->Key_name] = $dao->Key_name;
+      }
+      if ($dao->Column_name == 'module') {
+        $combinedCount++;
+        $this->assertArrayHasKey($dao->Key_name, $indexes);
+      }
+
+    }
+    foreach (array_keys($indexes) as $index) {
+      CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_uf_join DROP INDEX " . $index);
+    }
+    $this->assertEquals(2, $weightCount);
+  }
+
+  /**
+   * Test the drop index if exists function for a non-existent index.
+   */
+  public function testCHeckIndexNotExists() {
+    $this->assertFalse(CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_contact', 'magic_button'));
+  }
+
+  /**
+   * Test the drop index if exists function for a non-existent index.
+   */
+  public function testCHeckIndexExists() {
+    $this->assertTrue(CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_contact', 'index_hash'));
+  }
+
+  /**
+   * Test the drop index if exists function for a non-existent index.
+   */
+  public function testDropIndexNoneExists() {
+    CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_contact', 'magic_button');
+  }
+
+  /**
+   * Test the drop index if exists function.
+   */
+  public function testDropIndexExists() {
+    CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_contact', 'index_hash');
+    $this->assertFalse(CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_contact', 'index_hash'));
+
+    // Recreate it to clean up after the test.
+    CRM_Core_BAO_SchemaHandler::createIndexes(array('civicrm_contact' => array('hash')));
+  }
+
+  /**
+   * @return array
+   */
+  public function columnTests() {
+    $columns = array();
+    $columns[] = array('civicrm_contribution', 'total_amount');
+    $columns[] = array('civicrm_contact', 'from_name');
+    $columns[] = array('civicrm_contact', 'xxxx');
+    return $columns;
+  }
+
+  /**
+   * @param $tableName
+   * @param $columnName
+   *
+   * @dataProvider columnTests
+   */
+  public function testCheckIfColumnExists($tableName, $columnName) {
+    if ($columnName == 'xxxx') {
+      $this->assertFalse(CRM_Core_BAO_SchemaHandler::checkIfFieldExists($tableName, $columnName));
+    }
+    else {
+      $this->assertTrue(CRM_Core_BAO_SchemaHandler::checkIfFieldExists($tableName, $columnName));
+    }
+  }
+
+}