Differential D18484 Diff 44403 src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
Show All 21 Lines | abstract class PhabricatorCursorPagedPolicyAwareQuery | ||||
private $orderVector; | private $orderVector; | ||||
private $groupVector; | private $groupVector; | ||||
private $builtinOrder; | private $builtinOrder; | ||||
private $edgeLogicConstraints = array(); | private $edgeLogicConstraints = array(); | ||||
private $edgeLogicConstraintsAreValid = false; | private $edgeLogicConstraintsAreValid = false; | ||||
private $spacePHIDs; | private $spacePHIDs; | ||||
private $spaceIsArchived; | private $spaceIsArchived; | ||||
private $ngrams = array(); | private $ngrams = array(); | ||||
private $ferretEngine; | |||||
private $ferretConstraints; | |||||
protected function getPageCursors(array $page) { | protected function getPageCursors(array $page) { | ||||
return array( | return array( | ||||
$this->getResultCursor(head($page)), | $this->getResultCursor(head($page)), | ||||
$this->getResultCursor(last($page)), | $this->getResultCursor(last($page)), | ||||
); | ); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | /* -( Building Query Clauses )--------------------------------------------- */ | ||||
/** | /** | ||||
* @task clauses | * @task clauses | ||||
*/ | */ | ||||
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { | protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { | ||||
$joins = array(); | $joins = array(); | ||||
$joins[] = $this->buildEdgeLogicJoinClause($conn); | $joins[] = $this->buildEdgeLogicJoinClause($conn); | ||||
$joins[] = $this->buildApplicationSearchJoinClause($conn); | $joins[] = $this->buildApplicationSearchJoinClause($conn); | ||||
$joins[] = $this->buildNgramsJoinClause($conn); | $joins[] = $this->buildNgramsJoinClause($conn); | ||||
$joins[] = $this->buildFerretJoinClause($conn); | |||||
return $joins; | return $joins; | ||||
} | } | ||||
/** | /** | ||||
* @task clauses | * @task clauses | ||||
*/ | */ | ||||
protected function buildWhereClause(AphrontDatabaseConnection $conn) { | protected function buildWhereClause(AphrontDatabaseConnection $conn) { | ||||
$where = $this->buildWhereClauseParts($conn); | $where = $this->buildWhereClauseParts($conn); | ||||
return $this->formatWhereClause($where); | return $this->formatWhereClause($where); | ||||
} | } | ||||
/** | /** | ||||
* @task clauses | * @task clauses | ||||
*/ | */ | ||||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { | protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { | ||||
$where = array(); | $where = array(); | ||||
$where[] = $this->buildPagingClause($conn); | $where[] = $this->buildPagingClause($conn); | ||||
$where[] = $this->buildEdgeLogicWhereClause($conn); | $where[] = $this->buildEdgeLogicWhereClause($conn); | ||||
$where[] = $this->buildSpacesWhereClause($conn); | $where[] = $this->buildSpacesWhereClause($conn); | ||||
$where[] = $this->buildNgramsWhereClause($conn); | $where[] = $this->buildNgramsWhereClause($conn); | ||||
$where[] = $this->buildFerretWhereClause($conn); | |||||
return $where; | return $where; | ||||
} | } | ||||
/** | /** | ||||
* @task clauses | * @task clauses | ||||
*/ | */ | ||||
protected function buildHavingClause(AphrontDatabaseConnection $conn) { | protected function buildHavingClause(AphrontDatabaseConnection $conn) { | ||||
▲ Show 20 Lines • Show All 1,065 Lines • ▼ Show 20 Lines | /* -( Integration with CustomField )--------------------------------------- */ | ||||
* @task customfield | * @task customfield | ||||
*/ | */ | ||||
protected function isCustomFieldOrderKey($key) { | protected function isCustomFieldOrderKey($key) { | ||||
$prefix = 'custom:'; | $prefix = 'custom:'; | ||||
return !strncmp($key, $prefix, strlen($prefix)); | return !strncmp($key, $prefix, strlen($prefix)); | ||||
} | } | ||||
/* -( Ferret )------------------------------------------------------------- */ | |||||
public function withFerretConstraint( | |||||
PhabricatorFerretEngine $engine, | |||||
$raw_query) { | |||||
if ($this->ferretEngine) { | |||||
throw new Exception( | |||||
pht( | |||||
'Query may not have multiple fulltext constraints.')); | |||||
} | |||||
if (!strlen($raw_query)) { | |||||
return $this; | |||||
} | |||||
$this->ferretEngine = $engine; | |||||
$this->ferretConstraints = preg_split('/\s+/', $raw_query); | |||||
return $this; | |||||
} | |||||
protected function buildFerretJoinClause(AphrontDatabaseConnection $conn) { | |||||
if (!$this->ferretEngine) { | |||||
return array(); | |||||
} | |||||
$engine = $this->ferretEngine; | |||||
$ngram_engine = new PhabricatorNgramEngine(); | |||||
$ngram_table = $engine->newNgramsObject(); | |||||
$ngram_table_name = $ngram_table->getTableName(); | |||||
$flat = array(); | |||||
foreach ($this->ferretConstraints as $term) { | |||||
$value = $term; | |||||
$length = count(phutil_utf8v($term)); | |||||
if ($length >= 3) { | |||||
$ngrams = $ngram_engine->getNgramsFromString($value, 'query'); | |||||
$prefix = false; | |||||
} else if ($length == 2) { | |||||
$ngrams = $ngram_engine->getNgramsFromString($value, 'prefix'); | |||||
$prefix = false; | |||||
} else { | |||||
$ngrams = array(' '.$value); | |||||
$prefix = true; | |||||
} | |||||
foreach ($ngrams as $ngram) { | |||||
$flat[] = array( | |||||
'table' => $ngram_table_name, | |||||
'ngram' => $ngram, | |||||
'prefix' => $prefix, | |||||
); | |||||
} | |||||
} | |||||
// MySQL only allows us to join a maximum of 61 tables per query. Each | |||||
// ngram is going to cost us a join toward that limit, so if the user | |||||
// specified a very long query string, just pick 16 of the ngrams | |||||
// at random. | |||||
if (count($flat) > 16) { | |||||
shuffle($flat); | |||||
$flat = array_slice($flat, 0, 16); | |||||
} | |||||
$alias = $this->getPrimaryTableAlias(); | |||||
if ($alias) { | |||||
$phid_column = qsprintf($conn, '%T.%T', $alias, 'phid'); | |||||
} else { | |||||
$phid_column = qsprintf($conn, '%T', 'phid'); | |||||
} | |||||
$document_table = $engine->newDocumentObject(); | |||||
$field_table = $engine->newFieldObject(); | |||||
$joins = array(); | |||||
$joins[] = qsprintf( | |||||
$conn, | |||||
'JOIN %T ftdoc ON ftdoc.objectPHID = %Q', | |||||
$document_table->getTableName(), | |||||
$phid_column); | |||||
$idx = 1; | |||||
foreach ($flat as $spec) { | |||||
$table = $spec['table']; | |||||
$ngram = $spec['ngram']; | |||||
$prefix = $spec['prefix']; | |||||
$alias = 'ft'.$idx++; | |||||
if ($prefix) { | |||||
$joins[] = qsprintf( | |||||
$conn, | |||||
'JOIN %T %T ON %T.documentID = ftdoc.id AND %T.ngram LIKE %>', | |||||
$table, | |||||
$alias, | |||||
$alias, | |||||
$alias, | |||||
$ngram); | |||||
} else { | |||||
$joins[] = qsprintf( | |||||
$conn, | |||||
'JOIN %T %T ON %T.documentID = ftdoc.id AND %T.ngram = %s', | |||||
$table, | |||||
$alias, | |||||
$alias, | |||||
$alias, | |||||
$ngram); | |||||
} | |||||
} | |||||
$joins[] = qsprintf( | |||||
$conn, | |||||
'JOIN %T ftfield ON ftdoc.id = ftfield.documentID', | |||||
$field_table->getTableName()); | |||||
return $joins; | |||||
} | |||||
protected function buildFerretWhereClause(AphrontDatabaseConnection $conn) { | |||||
if (!$this->ferretEngine) { | |||||
return array(); | |||||
} | |||||
$where = array(); | |||||
foreach ($this->ferretConstraints as $constraint) { | |||||
$where[] = qsprintf( | |||||
$conn, | |||||
'(ftfield.rawCorpus LIKE %~ OR ftfield.normalCorpus LIKE %~)', | |||||
$constraint, | |||||
$constraint); | |||||
} | |||||
return $where; | |||||
} | |||||
/* -( Ngrams )------------------------------------------------------------- */ | /* -( Ngrams )------------------------------------------------------------- */ | ||||
protected function withNgramsConstraint( | protected function withNgramsConstraint( | ||||
PhabricatorSearchNgrams $index, | PhabricatorSearchNgrams $index, | ||||
$value) { | $value) { | ||||
if (strlen($value)) { | if (strlen($value)) { | ||||
▲ Show 20 Lines • Show All 744 Lines • Show Last 20 Lines |