Early return during APIv4::get if table doesn't exist
authorColeman Watts <coleman@civicrm.org>
Wed, 12 Aug 2020 15:44:39 +0000 (11:44 -0400)
committerColeman Watts <coleman@civicrm.org>
Thu, 13 Aug 2020 00:50:58 +0000 (20:50 -0400)
If there are pending upgrades, checks if table exists before attempting to read from it.

CRM/Core/DAO.php
Civi/Api4/Generic/DAOGetAction.php
tests/phpunit/CRM/Core/DAOTest.php

index 7c17558d884585755ffdda0bb2576721bf3020aa..96da596f6b11c300f0d3c9d8554454c58f01dfa1 100644 (file)
@@ -1148,6 +1148,23 @@ class CRM_Core_DAO extends DB_DataObject {
     return $result;
   }
 
+  /**
+   * Checks if this DAO's table ought to exist.
+   *
+   * If there are pending DB updates, this function compares the CiviCRM version of the table to the current schema version.
+   *
+   * @return bool
+   * @throws CRM_Core_Exception
+   */
+  public static function tableHasBeenAdded() {
+    if (CRM_Utils_System::version() === CRM_Core_BAO_Domain::version()) {
+      return TRUE;
+    }
+    $daoExt = constant(static::class . '::EXT');
+    $daoVersion = constant(static::class . '::TABLE_ADDED') ?? '1.0';
+    return !($daoExt === 'civicrm' && version_compare(CRM_Core_BAO_Domain::version(), $daoVersion, '<'));
+  }
+
   /**
    * Check if there is a given table in the database.
    *
index 9ad1d54adc352ba4c9d2ccbdc7450ed0eb6c084c..cbdec8841e66199412eb7920dde34ffae560c4f6 100644 (file)
@@ -85,6 +85,12 @@ class DAOGetAction extends AbstractGetAction {
   protected $having = [];
 
   public function _run(Result $result) {
+    // Early return if table doesn't exist yet due to pending upgrade
+    $baoName = $this->getBaoName();
+    if (!$baoName::tableHasBeenAdded()) {
+      return;
+    }
+
     $this->setDefaultWhereClause();
     $this->expandSelectClauseWildcards();
     $this->getObjects($result);
index ed008287ed75b5cc777abf9e9c12862cf04aab08..0523aab7d51e1da7ac7f4938839f07451700579b 100644 (file)
@@ -542,4 +542,17 @@ class CRM_Core_DAOTest extends CiviUnitTestCase {
     $this->assertArrayNotHasKey('api_key', $permissionedContactFields);
   }
 
+  public function testTableHasBeenAdded() {
+    // Hack a different db version
+    CRM_Core_BAO_Domain::getDomain()->version = '5.28.0';
+
+    // Table was added in 5.29
+    $this->assertFalse(CRM_Contact_DAO_RelationshipCache::tableHasBeenAdded());
+
+    // Remove domain version override:
+    CRM_Core_BAO_Domain::version(TRUE);
+
+    $this->assertTrue(CRM_Contact_DAO_RelationshipCache::tableHasBeenAdded());
+  }
+
 }