fix dangerous delete cascade
authordemeritcowboy <demeritcowboy@hotmail.com>
Thu, 27 Jul 2023 02:54:37 +0000 (22:54 -0400)
committerdemeritcowboy <demeritcowboy@hotmail.com>
Thu, 27 Jul 2023 02:54:37 +0000 (22:54 -0400)
CRM/Activity/DAO/Activity.php
CRM/Upgrade/Incremental/php/FiveSixtyFour.php
CRM/Upgrade/Incremental/sql/5.64.beta1.mysql.tpl [new file with mode: 0644]
xml/schema/Activity/Activity.xml

index bf375175615145d6d9698d24224006fff2861fa1..544e93db8eb4c36beaf20138c34856dfecb45174 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Generated from xml/schema/CRM/Activity/Activity.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:e1adbd9104050ebb0d274cf885a2de67)
+ * (GenCodeChecksum:5e64c1c4489e9c640f15d3a4877f7331)
  */
 
 /**
index 177270d03d14ed1f07dbe1d5eda12b35c4b38c4e..6c7492f65f470b27224d048c0b3c1531e4edbe02 100644 (file)
  */
 class CRM_Upgrade_Incremental_php_FiveSixtyFour extends CRM_Upgrade_Incremental_Base {
 
+  /**
+   * How many activities before the queries used here are slow. Guessing.
+   */
+  const ACTIVITY_THRESHOLD = 1000000;
+
+  public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
+    if ($rev === '5.64.beta1') {
+      // The ON DELETE constraint drop+recreate can be slow, so tell people what to do at their convenience if db is large.
+      if (CRM_Core_DAO::singleValueQuery('SELECT MAX(id) FROM civicrm_activity') >= self::ACTIVITY_THRESHOLD) {
+        $preUpgradeMessage .= '<p>' . ts('<strong>ACTION REQUIRED</strong>: You will need to apply a <strong>manual update</strong> because your civicrm_activity table is large and the update will run slowly. Please read about <a %1>how to apply this update manually</a>.', [1 => 'target="_blank" href="https://civicrm.org/redirect/activities-parentid-cascade"']) . '</p>';
+      }
+    }
+  }
+
   /**
    * Upgrade step; adds tasks including 'runSql'.
    *
@@ -36,6 +50,19 @@ class CRM_Upgrade_Incremental_php_FiveSixtyFour extends CRM_Upgrade_Incremental_
     $this->addTask('Fix double json encoding of accepted_credit_cards field in payment processor table', 'fixDoubleEscapingPaymentProcessorCreditCards');
   }
 
+  /**
+   * Upgrade step; adds tasks including 'runSql'.
+   *
+   * @param string $rev
+   *   The version number matching this function name
+   */
+  public function upgrade_5_64_beta1($rev): void {
+    $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
+    if (CRM_Core_DAO::singleValueQuery('SELECT MAX(id) FROM civicrm_activity') < self::ACTIVITY_THRESHOLD) {
+      $this->addTask('Fix dangerous delete cascade', 'fixDeleteCascade');
+    }
+  }
+
   public static function updateLogging($ctx): bool {
     if (\Civi::settings()->get('logging')) {
       $dsn = defined('CIVICRM_LOGGING_DSN') ? CRM_Utils_SQL::autoSwitchDSN(CIVICRM_LOGGING_DSN) : CRM_Utils_SQL::autoSwitchDSN(CIVICRM_DSN);
@@ -78,4 +105,13 @@ CHANGE `cancel_URL` `cancel_url` varchar(255) DEFAULT NULL COMMENT 'Redirect to
     return TRUE;
   }
 
+  /**
+   * Fix DELETE CASCADE that can lead to loss of data.
+   */
+  public static function fixDeleteCascade($ctx): bool {
+    CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_activity', 'FK_civicrm_activity_parent_id');
+    CRM_Core_DAO::executeQuery('ALTER TABLE `civicrm_activity` ADD CONSTRAINT `FK_civicrm_activity_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `civicrm_activity` (`id`) ON DELETE SET NULL');
+    return TRUE;
+  }
+
 }
diff --git a/CRM/Upgrade/Incremental/sql/5.64.beta1.mysql.tpl b/CRM/Upgrade/Incremental/sql/5.64.beta1.mysql.tpl
new file mode 100644 (file)
index 0000000..543a06e
--- /dev/null
@@ -0,0 +1 @@
+{* file to handle db changes in 5.64.beta1 during upgrade *}
index aff1261ef95ded171e108117312a3431e3d1540e..bc55111df0fc6dfcf47e90b36846c7a918112eb5 100644 (file)
     <table>civicrm_activity</table>
     <key>id</key>
     <add>1.1</add>
-    <onDelete>CASCADE</onDelete>
+    <onDelete>SET NULL</onDelete>
   </foreignKey>
   <field>
     <name>is_test</name>