Skip to content

Commit

Permalink
Merge pull request #12664 from totten/master-prevnext-ifclean
Browse files Browse the repository at this point in the history
(dev/core#217) PrevNext - Remove references to entity_table and entity_id2 from service. Add test.
  • Loading branch information
eileenmcnaughton authored Aug 17, 2018
2 parents 7e22e03 + 073ba4f commit 984e763
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 41 deletions.
2 changes: 1 addition & 1 deletion CRM/Campaign/Selector/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public function buildPrevNextCache($sort) {
);
list($select, $from) = explode(' FROM ', $sql);
$selectSQL = "
SELECT 'civicrm_contact', contact_a.id, contact_a.id, '$cacheKey', contact_a.display_name
SELECT '$cacheKey', contact_a.id, contact_a.display_name
FROM {$from}
";

Expand Down
2 changes: 1 addition & 1 deletion CRM/Contact/Selector.php
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,7 @@ public function fillupPrevNextCache($sort, $cacheKey, $start = 0, $end = self::C
// the other alternative of running the FULL query will just be incredibly inefficient
// and slow things down way too much on large data sets / complex queries

$selectSQL = "SELECT DISTINCT 'civicrm_contact', contact_a.id, contact_a.id, '$cacheKey', contact_a.sort_name";
$selectSQL = "SELECT DISTINCT '$cacheKey', contact_a.id, contact_a.sort_name";

$sql = str_replace(array("SELECT contact_a.id as contact_id", "SELECT contact_a.id as id"), $selectSQL, $sql);
try {
Expand Down
4 changes: 2 additions & 2 deletions CRM/Core/DAO/PrevNextCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
* Generated from xml/schema/CRM/Core/PrevNextCache.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:cfce4435348e53ba9941ce5ed223c05b)
* (GenCodeChecksum:5e4976ab94ea074a01a14e9eb0dde913)
*/

/**
Expand Down Expand Up @@ -127,7 +127,7 @@ public static function &fields() {
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Prev Next Entity ID 2'),
'description' => 'FK to entity table specified in entity_table column.',
'required' => TRUE,
'required' => FALSE,
'table_name' => 'civicrm_prevnext_cache',
'entity' => 'PrevNextCache',
'bao' => 'CRM_Core_BAO_PrevNextCache',
Expand Down
16 changes: 9 additions & 7 deletions CRM/Core/PrevNextCache/Interface.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ interface CRM_Core_PrevNextCache_Interface {
* @param string $cacheKey
* @param string $sql
* A SQL query. The query *MUST* be a SELECT statement which yields
* the following columns (in order): entity_table, entity_id1, entity_id2, cacheKey, data
* the following columns (in order): cacheKey, entity_id1, data
* @return bool
*/
public function fillWithSql($cacheKey, $sql);
Expand All @@ -50,9 +50,7 @@ public function fillWithSql($cacheKey, $sql);
* @param string $cacheKey
* @param array $rows
* A list of cache records. Each record should have keys:
* - entity_table
* - entity_id1
* - entity_id2
* - data
* @return bool
*/
Expand Down Expand Up @@ -89,20 +87,24 @@ public function getSelection($cacheKey, $action = 'get');
*
* @param string $cacheKey
* @param int $id1
* @param int $id2
*
* @return array
* List of neighbors.
* [
* 'foundEntry' => 1,
* 'prev' => ['id1' => 123, 'data'=>'foo'],
* 'next' => ['id1' => 456, 'data'=>'foo'],
* ]
*/
public function getPositions($cacheKey, $id1, $id2);
public function getPositions($cacheKey, $id1);

/**
* Delete an item from the prevnext cache table based on the entity.
*
* @param int $id
* @param string $cacheKey
* @param string $entityTable
*/
public function deleteItem($id = NULL, $cacheKey = NULL, $entityTable = 'civicrm_contact');
public function deleteItem($id = NULL, $cacheKey = NULL);

/**
* Get count of matching rows.
Expand Down
78 changes: 49 additions & 29 deletions CRM/Core/PrevNextCache/Sql.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ class CRM_Core_PrevNextCache_Sql implements CRM_Core_PrevNextCache_Interface {
*
* @param string $sql
* A SQL query. The query *MUST* be a SELECT statement which yields
* the following columns (in order): entity_table, entity_id1, entity_id2, cacheKey, data
* the following columns (in order): cacheKey, entity_id1, data
* @return bool
* @throws CRM_Core_Exception
*/
public function fillWithSql($cacheKey, $sql) {
$insertSQL = "
INSERT INTO civicrm_prevnext_cache ( entity_table, entity_id1, entity_id2, cacheKey, data )
INSERT INTO civicrm_prevnext_cache (cacheKey, entity_id1, data)
";
$result = CRM_Core_DAO::executeQuery($insertSQL . $sql, [], FALSE, NULL, FALSE, TRUE, TRUE);
if (is_a($result, 'DB_Error')) {
Expand All @@ -59,9 +59,7 @@ public function fillWithArray($cacheKey, $rows) {

$insert = CRM_Utils_SQL_Insert::into('civicrm_prevnext_cache')
->columns([
'entity_table',
'entity_id1',
'entity_id2',
'cacheKey',
'data'
]);
Expand All @@ -85,14 +83,11 @@ public function fillWithArray($cacheKey, $rows) {
* To unselect all contact IDs, use NULL.
*/
public function markSelection($cacheKey, $action, $cIds = NULL) {
$entity_table = 'civicrm_contact';

if (!$cacheKey) {
return;
}
$params = array();

$entity_whereClause = " AND entity_table = '{$entity_table}'";
if ($cIds && $cacheKey && $action) {
if (is_array($cIds)) {
$cIdFilter = "(" . implode(',', $cIds) . ")";
Expand All @@ -110,12 +105,12 @@ public function markSelection($cacheKey, $action, $cIds = NULL) {
}
if ($action == 'select') {
$whereClause .= "AND is_selected = 0";
$sql = "UPDATE civicrm_prevnext_cache SET is_selected = 1 {$whereClause} {$entity_whereClause}";
$sql = "UPDATE civicrm_prevnext_cache SET is_selected = 1 {$whereClause}";
$params[1] = array($cacheKey, 'String');
}
elseif ($action == 'unselect') {
$whereClause .= "AND is_selected = 1";
$sql = "UPDATE civicrm_prevnext_cache SET is_selected = 0 {$whereClause} {$entity_whereClause}";
$sql = "UPDATE civicrm_prevnext_cache SET is_selected = 0 {$whereClause}";
$params[1] = array($cacheKey, 'String');
}
// default action is reseting
Expand All @@ -125,7 +120,6 @@ public function markSelection($cacheKey, $action, $cIds = NULL) {
UPDATE civicrm_prevnext_cache
SET is_selected = 0
WHERE cacheKey = %1 AND is_selected = 1
{$entity_whereClause}
";
$params[1] = array($cacheKey, 'String');
}
Expand All @@ -145,31 +139,25 @@ public function markSelection($cacheKey, $action, $cIds = NULL) {
* @return array|NULL
*/
public function getSelection($cacheKey, $action = 'get') {
$entity_table = 'civicrm_contact';

if (!$cacheKey) {
return NULL;
}
$params = array();

$entity_whereClause = " AND entity_table = '{$entity_table}'";
if ($cacheKey && ($action == 'get' || $action == 'getall')) {
$actionGet = ($action == "get") ? " AND is_selected = 1 " : "";
$sql = "
SELECT entity_id1, entity_id2 FROM civicrm_prevnext_cache
SELECT entity_id1 FROM civicrm_prevnext_cache
WHERE cacheKey = %1
$actionGet
$entity_whereClause
ORDER BY id
";
$params[1] = array($cacheKey, 'String');

$contactIds = array($cacheKey => array());
$cIdDao = CRM_Core_DAO::executeQuery($sql, $params);
while ($cIdDao->fetch()) {
if ($cIdDao->entity_id1 == $cIdDao->entity_id2) {
$contactIds[$cacheKey][$cIdDao->entity_id1] = 1;
}
$contactIds[$cacheKey][$cIdDao->entity_id1] = 1;
}
return $contactIds;
}
Expand All @@ -180,27 +168,57 @@ public function getSelection($cacheKey, $action = 'get') {
*
* @param string $cacheKey
* @param int $id1
* @param int $id2
*
* NOTE: I don't really get why there are two ID columns, but we'll
* keep passing them through as a matter of safe-refactoring.
*
* @return array
*/
public function getPositions($cacheKey, $id1, $id2) {
return CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, $id1, $id2);
public function getPositions($cacheKey, $id1) {
$mergeId = CRM_Core_DAO::singleValueQuery(
"SELECT id FROM civicrm_prevnext_cache WHERE cacheKey = %2 AND entity_id1 = %1",
[
1 => [$id1, 'Integer'],
2 => [$cacheKey, 'String'],
]
);

$pos = ['foundEntry' => 0];
if ($mergeId) {
$pos['foundEntry'] = 1;

$sql = "SELECT pn.id, pn.entity_id1, pn.entity_id2, pn.data FROM civicrm_prevnext_cache pn ";
$wherePrev = " WHERE pn.id < %1 AND pn.cacheKey = %2 ORDER BY ID DESC LIMIT 1";
$whereNext = " WHERE pn.id > %1 AND pn.cacheKey = %2 ORDER BY ID ASC LIMIT 1";
$p = [
1 => [$mergeId, 'Integer'],
2 => [$cacheKey, 'String'],
];

$dao = CRM_Core_DAO::executeQuery($sql . $wherePrev, $p);
if ($dao->fetch()) {
$pos['prev']['id1'] = $dao->entity_id1;
$pos['prev']['mergeId'] = $dao->id;
$pos['prev']['data'] = $dao->data;
}

$dao = CRM_Core_DAO::executeQuery($sql . $whereNext, $p);
if ($dao->fetch()) {
$pos['next']['id1'] = $dao->entity_id1;
$pos['next']['mergeId'] = $dao->id;
$pos['next']['data'] = $dao->data;
}
}
return $pos;

}

/**
* Delete an item from the prevnext cache table based on the entity.
*
* @param int $id
* @param string $cacheKey
* @param string $entityTable
*/
public function deleteItem($id = NULL, $cacheKey = NULL, $entityTable = 'civicrm_contact') {
$sql = "DELETE FROM civicrm_prevnext_cache WHERE entity_table = %1";
$params = array(1 => array($entityTable, 'String'));
public function deleteItem($id = NULL, $cacheKey = NULL) {
$sql = "DELETE FROM civicrm_prevnext_cache WHERE (1)";
$params = array();

if (is_numeric($id)) {
$sql .= " AND ( entity_id1 = %2 OR entity_id2 = %2 )";
Expand All @@ -221,7 +239,9 @@ public function deleteItem($id = NULL, $cacheKey = NULL, $entityTable = 'civicrm
* @return int
*/
public function getCount($cacheKey) {
return CRM_Core_BAO_PrevNextCache::getCount($cacheKey, NULL, "entity_table = 'civicrm_contact'");
$query = "SELECT COUNT(*) FROM civicrm_prevnext_cache pn WHERE pn.cacheKey = %1";
$params = [1 => [$cacheKey, 'String']];
return (int) CRM_Core_DAO::singleValueQuery($query, $params, TRUE, FALSE);
}

}
3 changes: 3 additions & 0 deletions CRM/Upgrade/Incremental/sql/5.6.alpha1.mysql.tpl
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
{* file to handle db changes in 5.6.alpha1 during upgrade *}

ALTER TABLE civicrm_prevnext_cache
CHANGE `entity_id2` `entity_id2` int unsigned NULL COMMENT 'FK to entity table specified in entity_table column.';
Loading

0 comments on commit 984e763

Please sign in to comment.