CRM-18212 - CRM_Core_DAO - Move rebuild/drop/create triggers to another class
authorTim Otten <totten@civicrm.org>
Tue, 19 Apr 2016 02:27:45 +0000 (19:27 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 19 Apr 2016 03:06:21 +0000 (20:06 -0700)
CRM/Core/DAO.php
Civi/Core/Container.php
Civi/Core/SqlTriggers.php [new file with mode: 0644]

index c124c0957dbe632fd6cf6b35e1c1326dca92b2ef..1b01d7455faa506ece38ca4633e74fa9d2b03668 100644 (file)
@@ -1952,25 +1952,12 @@ SELECT contact_id
    * @param string $tableName
    *   the specific table requiring a rebuild; or NULL to rebuild all tables.
    * @param bool $force
+   * @deprecated
    *
    * @see CRM-9716
    */
   public static function triggerRebuild($tableName = NULL, $force = FALSE) {
-    $info = array();
-
-    $logging = new CRM_Logging_Schema();
-    $logging->triggerInfo($info, $tableName, $force);
-
-    CRM_Core_I18n_Schema::triggerInfo($info, $tableName);
-    CRM_Contact_BAO_Contact::triggerInfo($info, $tableName);
-
-    CRM_Utils_Hook::triggerInfo($info, $tableName);
-
-    // drop all existing triggers on all tables
-    $logging->dropTriggers($tableName);
-
-    // now create the set of new triggers
-    self::createTriggers($info, $tableName);
+    Civi::service('sql_triggers')->rebuild($tableName, $force);
   }
 
   /**
@@ -1995,15 +1982,10 @@ SELECT contact_id
    *
    * @param string $tableName
    *   the specific table requiring a rebuild; or NULL to rebuild all tables.
+   * @deprecated
    */
   public static function dropTriggers($tableName = NULL) {
-    $info = array();
-
-    $logging = new CRM_Logging_Schema();
-    $logging->triggerInfo($info, $tableName);
-
-    // drop all existing triggers on all tables
-    $logging->dropTriggers($tableName);
+    Civi::service('sql_triggers')->dropTriggers($tableName);
   }
 
   /**
@@ -2011,110 +1993,10 @@ SELECT contact_id
    *   per hook_civicrm_triggerInfo.
    * @param string $onlyTableName
    *   the specific table requiring a rebuild; or NULL to rebuild all tables.
+   * @deprecated
    */
   public static function createTriggers(&$info, $onlyTableName = NULL) {
-    // Validate info array, should probably raise errors?
-    if (is_array($info) == FALSE) {
-      return;
-    }
-
-    $triggers = array();
-
-    // now enumerate the tables and the events and collect the same set in a different format
-    foreach ($info as $value) {
-
-      // clean the incoming data, skip malformed entries
-      // TODO: malformed entries should raise errors or get logged.
-      if (isset($value['table']) == FALSE ||
-        isset($value['event']) == FALSE ||
-        isset($value['when']) == FALSE ||
-        isset($value['sql']) == FALSE
-      ) {
-        continue;
-      }
-
-      if (is_string($value['table']) == TRUE) {
-        $tables = array($value['table']);
-      }
-      else {
-        $tables = $value['table'];
-      }
-
-      if (is_string($value['event']) == TRUE) {
-        $events = array(strtolower($value['event']));
-      }
-      else {
-        $events = array_map('strtolower', $value['event']);
-      }
-
-      $whenName = strtolower($value['when']);
-
-      foreach ($tables as $tableName) {
-        if (!isset($triggers[$tableName])) {
-          $triggers[$tableName] = array();
-        }
-
-        foreach ($events as $eventName) {
-          $template_params = array('{tableName}', '{eventName}');
-          $template_values = array($tableName, $eventName);
-
-          $sql = str_replace($template_params,
-            $template_values,
-            $value['sql']
-          );
-          $variables = str_replace($template_params,
-            $template_values,
-            CRM_Utils_Array::value('variables', $value)
-          );
-
-          if (!isset($triggers[$tableName][$eventName])) {
-            $triggers[$tableName][$eventName] = array();
-          }
-
-          if (!isset($triggers[$tableName][$eventName][$whenName])) {
-            // We're leaving out cursors, conditions, and handlers for now
-            // they are kind of dangerous in this context anyway
-            // better off putting them in stored procedures
-            $triggers[$tableName][$eventName][$whenName] = array(
-              'variables' => array(),
-              'sql' => array(),
-            );
-          }
-
-          if ($variables) {
-            $triggers[$tableName][$eventName][$whenName]['variables'][] = $variables;
-          }
-
-          $triggers[$tableName][$eventName][$whenName]['sql'][] = $sql;
-        }
-      }
-    }
-
-    // now spit out the sql
-    foreach ($triggers as $tableName => $tables) {
-      if ($onlyTableName != NULL && $onlyTableName != $tableName) {
-        continue;
-      }
-      foreach ($tables as $eventName => $events) {
-        foreach ($events as $whenName => $parts) {
-          $varString = implode("\n", $parts['variables']);
-          $sqlString = implode("\n", $parts['sql']);
-          $validName = CRM_Core_DAO::shortenSQLName($tableName, 48, TRUE);
-          $triggerName = "{$validName}_{$whenName}_{$eventName}";
-          $triggerSQL = "CREATE TRIGGER $triggerName $whenName $eventName ON $tableName FOR EACH ROW BEGIN $varString $sqlString END";
-
-          CRM_Core_DAO::executeQuery("DROP TRIGGER IF EXISTS $triggerName");
-          CRM_Core_DAO::executeQuery(
-            $triggerSQL,
-            array(),
-            TRUE,
-            NULL,
-            FALSE,
-            FALSE
-          );
-        }
-      }
-    }
+    Civi::service('sql_triggers')->createTriggers($info, $onlyTableName);
   }
 
   /**
index ce9d9479560bdfe048b8ada3906f5f28fb54e2e5..cad5ff23edb2842b7c913bbff7aac247229bbb7e 100644 (file)
@@ -167,6 +167,11 @@ class Container {
       ))->setFactoryClass('CRM_Utils_Cache')->setFactoryMethod('create');
     }
 
+    $container->setDefinition('sql_triggers', new Definition(
+      'Civi\Core\SqlTriggers',
+      array()
+    ));
+
     $container->setDefinition('pear_mail', new Definition('Mail'))
       ->setFactoryClass('CRM_Utils_Mail')->setFactoryMethod('createMailer');
 
diff --git a/Civi/Core/SqlTriggers.php b/Civi/Core/SqlTriggers.php
new file mode 100644 (file)
index 0000000..b794127
--- /dev/null
@@ -0,0 +1,193 @@
+<?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        |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Core;
+
+/**
+ * Class SqlTriggers
+ * @package Civi\Core
+ *
+ * This class manages creation and destruction of SQL triggers.
+ */
+class SqlTriggers {
+
+  /**
+   * Build a list of triggers via hook and add them to (err, reconcile them
+   * with) the database.
+   *
+   * @param string $tableName
+   *   the specific table requiring a rebuild; or NULL to rebuild all tables.
+   * @param bool $force
+   *
+   * @see CRM-9716
+   */
+  public function rebuild($tableName = NULL, $force = FALSE) {
+    $info = array();
+
+    $logging = new \CRM_Logging_Schema();
+    $logging->triggerInfo($info, $tableName, $force);
+
+    \CRM_Core_I18n_Schema::triggerInfo($info, $tableName);
+    \CRM_Contact_BAO_Contact::triggerInfo($info, $tableName);
+
+    \CRM_Utils_Hook::triggerInfo($info, $tableName);
+
+    // drop all existing triggers on all tables
+    $logging->dropTriggers($tableName);
+
+    // now create the set of new triggers
+    $this->createTriggers($info, $tableName);
+  }
+
+  /**
+   * @param array $info
+   *   per hook_civicrm_triggerInfo.
+   * @param string $onlyTableName
+   *   the specific table requiring a rebuild; or NULL to rebuild all tables.
+   */
+  public function createTriggers(&$info, $onlyTableName = NULL) {
+    // Validate info array, should probably raise errors?
+    if (is_array($info) == FALSE) {
+      return;
+    }
+
+    $triggers = array();
+
+    // now enumerate the tables and the events and collect the same set in a different format
+    foreach ($info as $value) {
+
+      // clean the incoming data, skip malformed entries
+      // TODO: malformed entries should raise errors or get logged.
+      if (isset($value['table']) == FALSE ||
+        isset($value['event']) == FALSE ||
+        isset($value['when']) == FALSE ||
+        isset($value['sql']) == FALSE
+      ) {
+        continue;
+      }
+
+      if (is_string($value['table']) == TRUE) {
+        $tables = array($value['table']);
+      }
+      else {
+        $tables = $value['table'];
+      }
+
+      if (is_string($value['event']) == TRUE) {
+        $events = array(strtolower($value['event']));
+      }
+      else {
+        $events = array_map('strtolower', $value['event']);
+      }
+
+      $whenName = strtolower($value['when']);
+
+      foreach ($tables as $tableName) {
+        if (!isset($triggers[$tableName])) {
+          $triggers[$tableName] = array();
+        }
+
+        foreach ($events as $eventName) {
+          $template_params = array('{tableName}', '{eventName}');
+          $template_values = array($tableName, $eventName);
+
+          $sql = str_replace($template_params,
+            $template_values,
+            $value['sql']
+          );
+          $variables = str_replace($template_params,
+            $template_values,
+            \CRM_Utils_Array::value('variables', $value)
+          );
+
+          if (!isset($triggers[$tableName][$eventName])) {
+            $triggers[$tableName][$eventName] = array();
+          }
+
+          if (!isset($triggers[$tableName][$eventName][$whenName])) {
+            // We're leaving out cursors, conditions, and handlers for now
+            // they are kind of dangerous in this context anyway
+            // better off putting them in stored procedures
+            $triggers[$tableName][$eventName][$whenName] = array(
+              'variables' => array(),
+              'sql' => array(),
+            );
+          }
+
+          if ($variables) {
+            $triggers[$tableName][$eventName][$whenName]['variables'][] = $variables;
+          }
+
+          $triggers[$tableName][$eventName][$whenName]['sql'][] = $sql;
+        }
+      }
+    }
+
+    // now spit out the sql
+    foreach ($triggers as $tableName => $tables) {
+      if ($onlyTableName != NULL && $onlyTableName != $tableName) {
+        continue;
+      }
+      foreach ($tables as $eventName => $events) {
+        foreach ($events as $whenName => $parts) {
+          $varString = implode("\n", $parts['variables']);
+          $sqlString = implode("\n", $parts['sql']);
+          $validName = \CRM_Core_DAO::shortenSQLName($tableName, 48, TRUE);
+          $triggerName = "{$validName}_{$whenName}_{$eventName}";
+          $triggerSQL = "CREATE TRIGGER $triggerName $whenName $eventName ON $tableName FOR EACH ROW BEGIN $varString $sqlString END";
+
+          \CRM_Core_DAO::executeQuery("DROP TRIGGER IF EXISTS $triggerName");
+          \CRM_Core_DAO::executeQuery(
+            $triggerSQL,
+            array(),
+            TRUE,
+            NULL,
+            FALSE,
+            FALSE
+          );
+        }
+      }
+    }
+  }
+
+  /**
+   * Wrapper function to drop triggers.
+   *
+   * @param string $tableName
+   *   the specific table requiring a rebuild; or NULL to rebuild all tables.
+   */
+  public function dropTriggers($tableName = NULL) {
+    $info = array();
+
+    $logging = new \CRM_Logging_Schema();
+    $logging->triggerInfo($info, $tableName);
+
+    // drop all existing triggers on all tables
+    $logging->dropTriggers($tableName);
+  }
+
+}