This is an alternate methodology using __destruct on the DAO object.
Note that I have found some places bypass this - ie.
```
$rule = new CRM_ACL_BAO_ACL();
$rule->query($query);
```
But I think that is a pretty clumsy construct & we should swap to
CRM_Core_DAO::executeQuery();
CRM_Utils_Hook::post('delete', $contactType, $contact->id, $contact);
}
- // also reset the DB_DO global array so we can reuse the memory
- // http://issues.civicrm.org/jira/browse/CRM-4387
- CRM_Core_DAO::freeResult();
-
return TRUE;
}
break;
}
- // clean up memory from dao's
- CRM_Core_DAO::freeResult();
-
// see if we've hit our timeout yet
/* if ( $the_thing_with_the_stuff ) {
do_something( );
}
$updateDAO = CRM_Core_DAO::cascadeUpdate($daoName, $obj->id, $entityID, $skipData);
- CRM_Core_DAO::freeResult();
}
else {
CRM_Core_Error::fatal("DAO Mapper missing for $entityTable.");
*/
class CRM_Core_DAO extends DB_DataObject {
+ /**
+ * How many times has this instance been cloned.
+ *
+ * @var int
+ */
+ protected $resultCopies = 0;
+
/**
* @var null
* @deprecated
$this->__table = $this->getTableName();
}
+ public function __clone() {
+ if (!empty($this->_DB_resultid)) {
+ $this->resultCopies++;
+ }
+ }
+
+ /**
+ * Class destructor.
+ */
+ public function __destruct() {
+ if ($this->resultCopies === 0) {
+ $this->free();
+ }
+ $this->resultCopies--;
+ }
+
/**
* Empty definition for virtual function.
*/
$otherTree = CRM_Core_BAO_CustomGroup::getTree($main['contact_type'], NULL, $otherId, -1,
CRM_Utils_Array::value('contact_sub_type', $other), NULL, TRUE, NULL, TRUE, $checkPermissions
);
- CRM_Core_DAO::freeResult();
foreach ($otherTree as $gid => $group) {
$foundField = FALSE;
// pair may have been flipped, so make sure we delete using both orders
CRM_Core_BAO_PrevNextCache::deletePair($mainId, $otherId, $cacheKeyString, TRUE);
}
-
- CRM_Core_DAO::freeResult();
}
}
}
}
+ /**
+ * Test the DAO cloning method does not hit issues with freeing the result.
+ */
+ public function testCloneDAO() {
+ $dao = CRM_Core_DAO::executeQuery('SELECT * FROM civicrm_domain');
+ $i = 0;
+ while ($dao->fetch()) {
+ $i++;
+ $cloned = clone($dao);
+ unset($cloned);
+ }
+ $this->assertEquals(2, $i);
+ }
+
}
$this->callAPIAndDocument('entity_tag', 'get', $paramsEntity, __FUNCTION__, __FILE__);
}
+ /**
+ * Test memory usage does not escalate crazily.
+ */
+ public function testMemoryLeak() {
+ $start = memory_get_usage();
+ for ($i = 0; $i < 100; $i++) {
+ $this->callAPISuccess('EntityTag', 'get', []);
+ $memUsage = memory_get_usage();
+ }
+ $max = $start + 2000000;
+ $this->assertTrue($memUsage < $max, "mem usage ( $memUsage ) should be less than $max (start was $start) ");
+ }
+
/**
* Test tag can be added to a household.
*/