CRM-18404 Rebuild triggers not including all tables
authoreileen <emcnaughton@wikimedia.org>
Wed, 13 Apr 2016 04:40:07 +0000 (16:40 +1200)
committerEileen <eileen@fuzion.co.nz>
Sat, 23 Apr 2016 03:51:15 +0000 (03:51 +0000)
This is an alternate fix to the one proposed here https://github.com/civicrm/civicrm-core/pull/8017 - the test part of itis leveraging tests in the revert-api PR so I have added it into the PR

CRM/Logging/Schema.php
tests/phpunit/api/v3/LoggingTest.php

index 821ecb88f815e6b9068f840b4682c99f8b8e64b0..436aa8df737d7ccc26c7ed7091fc7bd78f16d97d 100644 (file)
@@ -467,10 +467,9 @@ AND    (TABLE_NAME LIKE 'log_civicrm_%' $nonStandardTableNameString )
     foreach ($diffs as $table => $cols) {
       $this->fixSchemaDifferencesFor($table, $cols, FALSE);
     }
-
     if ($rebuildTrigger) {
       // invoke the meta trigger creation call
-      CRM_Core_DAO::triggerRebuild($table);
+      CRM_Core_DAO::triggerRebuild(NULL, TRUE);
     }
   }
 
@@ -534,23 +533,19 @@ AND    (TABLE_NAME LIKE 'log_civicrm_%' $nonStandardTableNameString )
    * @return array
    */
   private function columnsOf($table, $force = FALSE) {
-    static $columnsOf = array();
-
-    $from = (substr($table, 0, 4) == 'log_') ? "`{$this->db}`.$table" : $table;
-
-    if (!isset($columnsOf[$table]) || $force) {
-      $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
+    if ($force || !isset(\Civi::$statics[__CLASS__]['columnsOf'][$table])) {
+      $from = (substr($table, 0, 4) == 'log_') ? "`{$this->db}`.$table" : $table;
+      CRM_Core_TemporaryErrorScope::ignoreException();
       $dao = CRM_Core_DAO::executeQuery("SHOW COLUMNS FROM $from", CRM_Core_DAO::$_nullArray, TRUE, NULL, FALSE, FALSE);
       if (is_a($dao, 'DB_Error')) {
         return array();
       }
-      $columnsOf[$table] = array();
+      \Civi::$statics[__CLASS__]['columnsOf'][$table] = array();
       while ($dao->fetch()) {
-        $columnsOf[$table][] = $dao->Field;
+        \Civi::$statics[__CLASS__]['columnsOf'][$table][] = $dao->Field;
       }
     }
-
-    return $columnsOf[$table];
+    return \Civi::$statics[__CLASS__]['columnsOf'][$table];
   }
 
   /**
index e7ea73c0910084412cda4ec69ed8a8d2109695af..2f470bd8f376bc0a04e2afab4aff8a869e9c4601 100644 (file)
@@ -146,6 +146,32 @@ class api_v3_LoggingTest extends CiviUnitTestCase {
     $this->checkINNODBLogTableCreated();
   }
 
+  /**
+   * Check that if a field is added then the trigger is updated on refresh.
+   */
+  public function testRebuildTriggerAfterSchemaChange() {
+    $this->callAPISuccess('Setting', 'create', array('logging' => TRUE));
+    $tables = array('civicrm_acl', 'civicrm_website');
+    foreach ($tables as $table) {
+      CRM_Core_DAO::executeQuery("ALTER TABLE $table ADD column temp_col INT(10)");
+    }
+
+    $schema = new CRM_Logging_Schema();
+    $schema->fixSchemaDifferencesForAll(TRUE);
+
+    foreach ($tables as $table) {
+      $dao = CRM_Core_DAO::executeQuery("SHOW columns FROM log_{$table} WHERE Field = 'temp_col'");
+      $dao->fetch(TRUE);
+      $this->assertEquals(1, $dao->N, "Column temp_col not in $table");
+      $dao = CRM_Core_DAO::executeQuery("SHOW TRIGGERS LIKE '{$table}'");
+      while ($dao->fetch()) {
+        $this->assertContains('temp_col', $dao->Statement);
+      }
+    }
+    CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_acl DROP column temp_col");
+    CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_website DROP column temp_col");
+  }
+
   /**
    * Use a hook to declare an INNODB engine for the contact log table.
    *