Skip to content

Commit

Permalink
Extract getSearchSQL from getSearchQuery.
Browse files Browse the repository at this point in the history
Change one instance to call it directly. Next I'll deprecate it & change all instances hit by the tests
  • Loading branch information
eileenmcnaughton committed Feb 22, 2019
1 parent 741d80c commit 89d7bb7
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 94 deletions.
4 changes: 2 additions & 2 deletions CRM/Campaign/Selector/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,10 @@ public function buildPrevNextCache($sort) {
$cacheKey = "civicrm search {$this->_key}";
Civi::service('prevnext')->deleteItem(NULL, $cacheKey, 'civicrm_contact');

$sql = $this->_query->searchQuery(0, 0, $sort,
$sql = $this->_query->getSearchSQL(0, 0, $sort,
FALSE, FALSE,
FALSE, FALSE,
TRUE, $this->_campaignWhereClause,
$this->_campaignWhereClause,
NULL,
$this->_campaignFromClause
);
Expand Down
226 changes: 134 additions & 92 deletions CRM/Contact/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -4880,95 +4880,7 @@ public function searchQuery(
$additionalFromClause = NULL, $skipOrderAndLimit = FALSE
) {

if ($includeContactIds) {
$this->_includeContactIds = TRUE;
$this->_whereClause = $this->whereClause();
}

$onlyDeleted = in_array(array('deleted_contacts', '=', '1', '0', '0'), $this->_params);

// if we’re explicitly looking for a certain contact’s contribs, events, etc.
// and that contact happens to be deleted, set $onlyDeleted to true
foreach ($this->_params as $values) {
$name = CRM_Utils_Array::value(0, $values);
$op = CRM_Utils_Array::value(1, $values);
$value = CRM_Utils_Array::value(2, $values);
if ($name == 'contact_id' and $op == '=') {
if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'is_deleted')) {
$onlyDeleted = TRUE;
}
break;
}
}

// building the query string
$groupBy = $groupByCols = NULL;
if (!$count) {
if (isset($this->_groupByComponentClause)) {
$groupByCols = preg_replace('/^GROUP BY /', '', trim($this->_groupByComponentClause));
$groupByCols = explode(', ', $groupByCols);
}
elseif ($this->_useGroupBy) {
$groupByCols = array('contact_a.id');
}
}
if ($this->_mode & CRM_Contact_BAO_Query::MODE_ACTIVITY && (!$count)) {
$groupByCols = array('civicrm_activity.id');
}
if (!empty($groupByCols)) {
$groupBy = " GROUP BY " . implode(', ', $groupByCols);
}

$order = $orderBy = $limit = '';
if (!$count) {
list($order, $additionalFromClause) = $this->prepareOrderBy($sort, $sortByChar, $sortOrder, $additionalFromClause);

if ($rowCount > 0 && $offset >= 0) {
$offset = CRM_Utils_Type::escape($offset, 'Int');
$rowCount = CRM_Utils_Type::escape($rowCount, 'Int');
$limit = " LIMIT $offset, $rowCount ";
}
}
// Two cases where we are disabling FGB (FULL_GROUP_BY_MODE):
// 1. Expecting the search query to return all the first single letter characters of contacts ONLY, but when FGB is enabled
// MySQL expect the columns present in GROUP BY, must be present in SELECT clause and that results into error, needless to have other columns.
// 2. When GROUP BY columns are present then disable FGB otherwise it demands to add ORDER BY columns in GROUP BY and eventually in SELECT
// clause. This will impact the search query output.
$disableFullGroupByMode = ($sortByChar || !empty($groupBy) || $groupContacts);

if ($disableFullGroupByMode) {
CRM_Core_DAO::disableFullGroupByMode();
}

// CRM-15231
$this->_sort = $sort;

//CRM-15967
$this->includePseudoFieldsJoin($sort);

list($select, $from, $where, $having) = $this->query($count, $sortByChar, $groupContacts, $onlyDeleted);

if ($additionalWhereClause) {
$where = $where . ' AND ' . $additionalWhereClause;
}

//additional from clause should be w/ proper joins.
if ($additionalFromClause) {
$from .= "\n" . $additionalFromClause;
}

// if we are doing a transform, do it here
// use the $from, $where and $having to get the contact ID
if ($this->_displayRelationshipType) {
$this->filterRelatedContacts($from, $where, $having);
}

if ($skipOrderAndLimit) {
$query = "$select $from $where $having $groupBy";
}
else {
$query = "$select $from $where $having $groupBy $order $limit";
}
$query = $this->getSearchSQL($offset, $rowCount, $sort, $count, $includeContactIds, $sortByChar, $groupContacts, $additionalWhereClause, $sortOrder, $additionalFromClause, $skipOrderAndLimit);

if ($returnQuery) {
return $query;
Expand All @@ -4979,9 +4891,8 @@ public function searchQuery(

$dao = CRM_Core_DAO::executeQuery($query);

if ($disableFullGroupByMode) {
CRM_Core_DAO::reenableFullGroupByMode();
}
// We can always call this - it will only re-enable if it was originally enabled.
CRM_Core_DAO::reenableFullGroupByMode();

if ($groupContacts) {
$ids = array();
Expand Down Expand Up @@ -6658,4 +6569,135 @@ protected function addBasicCancelStatsToSummary(&$summary, $where, $from) {
}
}

/**
* /**
* Create the sql query for an contact search.
*
* @param int $offset
* The offset for the query.
* @param int $rowCount
* The number of rows to return.
* @param string|CRM_Utils_Sort $sort
* The order by string.
* @param bool $count
* Is this a count only query ?.
* @param bool $includeContactIds
* Should we include contact ids?.
* @param bool $sortByChar
* If true returns the distinct array of first characters for search results.
* @param bool $groupContacts
* If true, return only the contact ids.
* @param string $additionalWhereClause
* If the caller wants to further restrict the search (used for components).
* @param null $sortOrder
* @param string $additionalFromClause
* Should be clause with proper joins, effective to reduce where clause load.
*
* @param bool $skipOrderAndLimit
* @return string
*/
public function getSearchSQL(
$offset = 0, $rowCount = 0, $sort = NULL,
$count = FALSE, $includeContactIds = FALSE,
$sortByChar = FALSE, $groupContacts = FALSE,
$additionalWhereClause = NULL, $sortOrder = NULL,
$additionalFromClause = NULL, $skipOrderAndLimit = FALSE) {
if ($includeContactIds) {
$this->_includeContactIds = TRUE;
$this->_whereClause = $this->whereClause();
}

$onlyDeleted = in_array([
'deleted_contacts',
'=',
'1',
'0',
'0'
], $this->_params);

// if we’re explicitly looking for a certain contact’s contribs, events, etc.
// and that contact happens to be deleted, set $onlyDeleted to true
foreach ($this->_params as $values) {
$name = CRM_Utils_Array::value(0, $values);
$op = CRM_Utils_Array::value(1, $values);
$value = CRM_Utils_Array::value(2, $values);
if ($name == 'contact_id' and $op == '=') {
if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'is_deleted')) {
$onlyDeleted = TRUE;
}
break;
}
}

// building the query string
$groupBy = $groupByCols = NULL;
if (!$count) {
if (isset($this->_groupByComponentClause)) {
$groupByCols = preg_replace('/^GROUP BY /', '', trim($this->_groupByComponentClause));
$groupByCols = explode(', ', $groupByCols);
}
elseif ($this->_useGroupBy) {
$groupByCols = ['contact_a.id'];
}
}
if ($this->_mode & CRM_Contact_BAO_Query::MODE_ACTIVITY && (!$count)) {
$groupByCols = ['civicrm_activity.id'];
}
if (!empty($groupByCols)) {
$groupBy = " GROUP BY " . implode(', ', $groupByCols);
}

$order = $orderBy = $limit = '';
if (!$count) {
list($order, $additionalFromClause) = $this->prepareOrderBy($sort, $sortByChar, $sortOrder, $additionalFromClause);

if ($rowCount > 0 && $offset >= 0) {
$offset = CRM_Utils_Type::escape($offset, 'Int');
$rowCount = CRM_Utils_Type::escape($rowCount, 'Int');
$limit = " LIMIT $offset, $rowCount ";
}
}
// Two cases where we are disabling FGB (FULL_GROUP_BY_MODE):
// 1. Expecting the search query to return all the first single letter characters of contacts ONLY, but when FGB is enabled
// MySQL expect the columns present in GROUP BY, must be present in SELECT clause and that results into error, needless to have other columns.
// 2. When GROUP BY columns are present then disable FGB otherwise it demands to add ORDER BY columns in GROUP BY and eventually in SELECT
// clause. This will impact the search query output.
$disableFullGroupByMode = ($sortByChar || !empty($groupBy) || $groupContacts);

if ($disableFullGroupByMode) {
CRM_Core_DAO::disableFullGroupByMode();
}

// CRM-15231
$this->_sort = $sort;

//CRM-15967
$this->includePseudoFieldsJoin($sort);

list($select, $from, $where, $having) = $this->query($count, $sortByChar, $groupContacts, $onlyDeleted);

if ($additionalWhereClause) {
$where = $where . ' AND ' . $additionalWhereClause;
}

//additional from clause should be w/ proper joins.
if ($additionalFromClause) {
$from .= "\n" . $additionalFromClause;
}

// if we are doing a transform, do it here
// use the $from, $where and $having to get the contact ID
if ($this->_displayRelationshipType) {
$this->filterRelatedContacts($from, $where, $having);
}

if ($skipOrderAndLimit) {
$query = "$select $from $where $having $groupBy";
}
else {
$query = "$select $from $where $having $groupBy $order $limit";
}
return $query;
}

}

0 comments on commit 89d7bb7

Please sign in to comment.