public function executeSearch(PhabricatorSavedQuery $query) { $where = array(); $join = array(); $order = 'ORDER BY documentCreated DESC'; $dao_doc = new PhabricatorSearchDocument(); $dao_field = new PhabricatorSearchDocumentField(); $t_doc = $dao_doc->getTableName(); $t_field = $dao_field->getTableName(); $conn_r = $dao_doc->establishConnection('r'); $q = $query->getParameter('query'); if (strlen($q)) { $join[] = qsprintf($conn_r, '%T field ON field.phid = document.phid', $t_field); $where[] = qsprintf($conn_r, 'MATCH(corpus) AGAINST (%s IN BOOLEAN MODE)', $q); // When searching for a string, promote user listings above other // listings. $order = qsprintf($conn_r, 'ORDER BY IF(documentType = %s, 0, 1) ASC, MAX(MATCH(corpus) AGAINST (%s)) DESC', 'USER', $q); $field = $query->getParameter('field'); if ($field) { $where[] = qsprintf($conn_r, 'field.field = %s', $field); } } $exclude = $query->getParameter('exclude'); if ($exclude) { $where[] = qsprintf($conn_r, 'document.phid != %s', $exclude); } $types = $query->getParameter('types'); if ($types) { if (strlen($q)) { $where[] = qsprintf($conn_r, 'field.phidType IN (%Ls)', $types); } $where[] = qsprintf($conn_r, 'document.documentType IN (%Ls)', $types); } $join[] = $this->joinRelationship($conn_r, $query, 'authorPHIDs', PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR); $statuses = $query->getParameter('statuses', array()); $statuses = array_fuse($statuses); $open_rel = PhabricatorSearchRelationship::RELATIONSHIP_OPEN; $closed_rel = PhabricatorSearchRelationship::RELATIONSHIP_CLOSED; $include_open = !empty($statuses[$open_rel]); $include_closed = !empty($statuses[$closed_rel]); if ($include_open && !$include_closed) { $join[] = $this->joinRelationship($conn_r, $query, 'statuses', $open_rel, true); } else { if ($include_closed && !$include_open) { $join[] = $this->joinRelationship($conn_r, $query, 'statuses', $closed_rel, true); } } if ($query->getParameter('withAnyOwner')) { $join[] = $this->joinRelationship($conn_r, $query, 'withAnyOwner', PhabricatorSearchRelationship::RELATIONSHIP_OWNER, true); } else { if ($query->getParameter('withUnowned')) { $join[] = $this->joinRelationship($conn_r, $query, 'withUnowned', PhabricatorSearchRelationship::RELATIONSHIP_UNOWNED, true); } else { $join[] = $this->joinRelationship($conn_r, $query, 'ownerPHIDs', PhabricatorSearchRelationship::RELATIONSHIP_OWNER); } } $join[] = $this->joinRelationship($conn_r, $query, 'subscriberPHIDs', PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER); $join[] = $this->joinRelationship($conn_r, $query, 'projectPHIDs', PhabricatorSearchRelationship::RELATIONSHIP_PROJECT); $join[] = $this->joinRelationship($conn_r, $query, 'repository', PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY); $join = array_filter($join); foreach ($join as $key => $clause) { $join[$key] = ' JOIN ' . $clause; } $join = implode(' ', $join); if ($where) { $where = 'WHERE ' . implode(' AND ', $where); } else { $where = ''; } $offset = (int) $query->getParameter('offset', 0); $limit = (int) $query->getParameter('limit', 25); $hits = queryfx_all($conn_r, 'SELECT document.phid FROM %T document %Q %Q GROUP BY document.phid %Q LIMIT %d, %d', $t_doc, $join, $where, $order, $offset, $limit); return ipull($hits, 'phid'); }
public function executeSearch(PhabricatorSearchQuery $query) { $where = array(); $join = array(); $order = 'ORDER BY documentCreated DESC'; $dao_doc = new PhabricatorSearchDocument(); $dao_field = new PhabricatorSearchDocumentField(); $t_doc = $dao_doc->getTableName(); $t_field = $dao_field->getTableName(); $conn_r = $dao_doc->establishConnection('r'); $q = $query->getQuery(); if (strlen($q)) { $join[] = qsprintf($conn_r, "{$t_field} field ON field.phid = document.phid"); $where[] = qsprintf($conn_r, 'MATCH(corpus) AGAINST (%s IN BOOLEAN MODE)', $q); // When searching for a string, promote user listings above other // listings. $order = qsprintf($conn_r, 'ORDER BY IF(documentType = %s, 0, 1) ASC, MAX(MATCH(corpus) AGAINST (%s)) DESC', 'USER', $q); $field = $query->getParameter('field'); if ($field) { $where[] = qsprintf($conn_r, 'field.field = %s', $field); } } $exclude = $query->getParameter('exclude'); if ($exclude) { $where[] = qsprintf($conn_r, 'document.phid != %s', $exclude); } if ($query->getParameter('type')) { if (strlen($q)) { // TODO: verify that this column actually does something useful in query // plans once we have nontrivial amounts of data. $where[] = qsprintf($conn_r, 'field.phidType = %s', $query->getParameter('type')); } $where[] = qsprintf($conn_r, 'document.documentType = %s', $query->getParameter('type')); } $join[] = $this->joinRelationship($conn_r, $query, 'author', PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR); $join[] = $this->joinRelationship($conn_r, $query, 'open', PhabricatorSearchRelationship::RELATIONSHIP_OPEN); $join[] = $this->joinRelationship($conn_r, $query, 'owner', PhabricatorSearchRelationship::RELATIONSHIP_OWNER); $join[] = $this->joinRelationship($conn_r, $query, 'project', PhabricatorSearchRelationship::RELATIONSHIP_PROJECT); $join[] = $this->joinRelationship($conn_r, $query, 'repository', PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY); $join = array_filter($join); foreach ($join as $key => $clause) { $join[$key] = ' JOIN ' . $clause; } $join = implode(' ', $join); if ($where) { $where = 'WHERE ' . implode(' AND ', $where); } else { $where = ''; } $offset = (int) $query->getParameter('offset', 0); $limit = (int) $query->getParameter('limit', 25); $hits = queryfx_all($conn_r, 'SELECT document.phid FROM %T document %Q %Q GROUP BY document.phid %Q LIMIT %d, %d', $t_doc, $join, $where, $order, $offset, $limit); return ipull($hits, 'phid'); }