1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-04-12 04:18:37 +02:00

Make buildPagingClauseFromMultipleColumns() safer

Summary: Ref T7803. Reduce the amount of code we're trusting to build SQL queries.

Test Plan:
  - Paged through results in Maniphest, Differential and Diffusion.
  - Some of the NULLable groups in Maniphest are a bit funky but this was preexisting.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7803

Differential Revision: https://secure.phabricator.com/D12353
This commit is contained in:
epriestley 2015-04-11 17:39:05 -07:00
parent a43473c4b6
commit 604d1409f1
4 changed files with 68 additions and 31 deletions

View file

@ -896,14 +896,16 @@ final class DifferentialRevisionQuery
return $default; return $default;
case self::ORDER_MODIFIED: case self::ORDER_MODIFIED:
$columns[] = array( $columns[] = array(
'name' => 'r.dateModified', 'table' => 'r',
'column' => 'dateModified',
'value' => $cursor->getDateModified(), 'value' => $cursor->getDateModified(),
'type' => 'int', 'type' => 'int',
); );
break; break;
case self::ORDER_PATH_MODIFIED: case self::ORDER_PATH_MODIFIED:
$columns[] = array( $columns[] = array(
'name' => 'p.epoch', 'table' => 'p',
'column' => 'epoch',
'value' => $cursor->getDateCreated(), 'value' => $cursor->getDateCreated(),
'type' => 'int', 'type' => 'int',
); );
@ -911,7 +913,8 @@ final class DifferentialRevisionQuery
} }
$columns[] = array( $columns[] = array(
'name' => 'r.id', 'table' => 'r',
'column' => 'id',
'value' => $cursor->getID(), 'value' => $cursor->getID(),
'type' => 'int', 'type' => 'int',
); );

View file

@ -1005,16 +1005,18 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
break; break;
case self::GROUP_PRIORITY: case self::GROUP_PRIORITY:
$columns[] = array( $columns[] = array(
'name' => 'task.priority', 'table' => 'task',
'column' => 'priority',
'value' => (int)$group_id, 'value' => (int)$group_id,
'type' => 'int', 'type' => 'int',
); );
break; break;
case self::GROUP_OWNER: case self::GROUP_OWNER:
$columns[] = array( $columns[] = array(
'name' => '(task.ownerOrdering IS NULL)', 'table' => 'task',
'value' => (int)(strlen($group_id) ? 0 : 1), 'column' => 'ownerOrdering',
'type' => 'int', 'value' => strlen($group_id),
'type' => 'null',
); );
if ($group_id) { if ($group_id) {
$paging_users = id(new PhabricatorPeopleQuery()) $paging_users = id(new PhabricatorPeopleQuery())
@ -1025,7 +1027,8 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
return null; return null;
} }
$columns[] = array( $columns[] = array(
'name' => 'task.ownerOrdering', 'table' => 'task',
'column' => 'ownerOrdering',
'value' => head($paging_users)->getUsername(), 'value' => head($paging_users)->getUsername(),
'type' => 'string', 'type' => 'string',
'reverse' => true, 'reverse' => true,
@ -1034,16 +1037,18 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
break; break;
case self::GROUP_STATUS: case self::GROUP_STATUS:
$columns[] = array( $columns[] = array(
'name' => 'task.status', 'table' => 'task',
'column' => 'status',
'value' => $group_id, 'value' => $group_id,
'type' => 'string', 'type' => 'string',
); );
break; break;
case self::GROUP_PROJECT: case self::GROUP_PROJECT:
$columns[] = array( $columns[] = array(
'name' => '(projectGroupName.indexedObjectName IS NULL)', 'table' => 'projectGroupName',
'value' => (int)(strlen($group_id) ? 0 : 1), 'column' => 'indexedObjectName',
'type' => 'int', 'value' => strlen($group_id),
'type' => 'null',
); );
if ($group_id) { if ($group_id) {
$paging_projects = id(new PhabricatorProjectQuery()) $paging_projects = id(new PhabricatorProjectQuery())
@ -1054,7 +1059,8 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
return null; return null;
} }
$columns[] = array( $columns[] = array(
'name' => 'projectGroupName.indexedObjectName', 'table' => 'projectGroupName',
'column' => 'indexedObjectName',
'value' => head($paging_projects)->getName(), 'value' => head($paging_projects)->getName(),
'type' => 'string', 'type' => 'string',
'reverse' => true, 'reverse' => true,
@ -1073,18 +1079,21 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
case self::ORDER_PRIORITY: case self::ORDER_PRIORITY:
if ($this->groupBy != self::GROUP_PRIORITY) { if ($this->groupBy != self::GROUP_PRIORITY) {
$columns[] = array( $columns[] = array(
'name' => 'task.priority', 'table' => 'task',
'column' => 'priority',
'value' => (int)$cursor->getPriority(), 'value' => (int)$cursor->getPriority(),
'type' => 'int', 'type' => 'int',
); );
} }
$columns[] = array( $columns[] = array(
'name' => 'task.subpriority', 'table' => 'task',
'column' => 'subpriority',
'value' => $cursor->getSubpriority(), 'value' => $cursor->getSubpriority(),
'type' => 'float', 'type' => 'float',
); );
$columns[] = array( $columns[] = array(
'name' => 'task.dateModified', 'table' => 'task',
'column' => 'dateModified',
'value' => (int)$cursor->getDateModified(), 'value' => (int)$cursor->getDateModified(),
'type' => 'int', 'type' => 'int',
); );
@ -1094,14 +1103,16 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
break; break;
case self::ORDER_MODIFIED: case self::ORDER_MODIFIED:
$columns[] = array( $columns[] = array(
'name' => 'task.dateModified', 'table' => 'task',
'column' => 'dateModified',
'value' => (int)$cursor->getDateModified(), 'value' => (int)$cursor->getDateModified(),
'type' => 'int', 'type' => 'int',
); );
break; break;
case self::ORDER_TITLE: case self::ORDER_TITLE:
$columns[] = array( $columns[] = array(
'name' => 'task.title', 'table' => 'task',
'column' => 'title',
'value' => $cursor->getTitle(), 'value' => $cursor->getTitle(),
'type' => 'string', 'type' => 'string',
); );
@ -1112,7 +1123,8 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
} }
$columns[] = array( $columns[] = array(
'name' => 'task.id', 'table' => 'task',
'column' => 'id',
'value' => $cursor->getID(), 'value' => $cursor->getID(),
'type' => 'int', 'type' => 'int',
); );

View file

@ -383,7 +383,8 @@ final class PhabricatorRepositoryQuery
} }
$id_column = array( $id_column = array(
'name' => 'r.id', 'table' => 'r',
'column' => 'id',
'type' => 'int', 'type' => 'int',
'value' => $cursor->getID(), 'value' => $cursor->getID(),
); );
@ -396,7 +397,8 @@ final class PhabricatorRepositoryQuery
return null; return null;
} }
$columns[] = array( $columns[] = array(
'name' => 's.epoch', 'table' => 's',
'column' => 'epoch',
'type' => 'int', 'type' => 'int',
'value' => $commit->getEpoch(), 'value' => $commit->getEpoch(),
); );
@ -404,7 +406,8 @@ final class PhabricatorRepositoryQuery
break; break;
case self::ORDER_CALLSIGN: case self::ORDER_CALLSIGN:
$columns[] = array( $columns[] = array(
'name' => 'r.callsign', 'table' => 'r',
'column' => 'callsign',
'type' => 'string', 'type' => 'string',
'value' => $cursor->getCallsign(), 'value' => $cursor->getCallsign(),
'reverse' => true, 'reverse' => true,
@ -412,7 +415,8 @@ final class PhabricatorRepositoryQuery
break; break;
case self::ORDER_NAME: case self::ORDER_NAME:
$columns[] = array( $columns[] = array(
'name' => 'r.name', 'table' => 'r',
'column' => 'name',
'type' => 'string', 'type' => 'string',
'value' => $cursor->getName(), 'value' => $cursor->getName(),
'reverse' => true, 'reverse' => true,
@ -421,7 +425,8 @@ final class PhabricatorRepositoryQuery
break; break;
case self::ORDER_SIZE: case self::ORDER_SIZE:
$columns[] = array( $columns[] = array(
'name' => 's.size', 'table' => 's',
'column' => 'size',
'type' => 'int', 'type' => 'int',
'value' => $cursor->getCommitCount(), 'value' => $cursor->getCommitCount(),
); );

View file

@ -181,13 +181,15 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
* $conn_r, * $conn_r,
* array( * array(
* array( * array(
* 'name' => 'title', * 'table' => 't',
* 'column' => 'title',
* 'type' => 'string', * 'type' => 'string',
* 'value' => $cursor->getTitle(), * 'value' => $cursor->getTitle(),
* 'reverse' => true, * 'reverse' => true,
* ), * ),
* array( * array(
* 'name' => 'id', * 'table' => 't',
* 'column' => 'id',
* 'type' => 'int', * 'type' => 'int',
* 'value' => $cursor->getID(), * 'value' => $cursor->getID(),
* ), * ),
@ -212,7 +214,8 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
PhutilTypeSpec::checkMap( PhutilTypeSpec::checkMap(
$column, $column,
array( array(
'name' => 'string', 'table' => 'optional string',
'column' => 'string',
'value' => 'wild', 'value' => 'wild',
'type' => 'string', 'type' => 'string',
'reverse' => 'optional bool', 'reverse' => 'optional bool',
@ -231,10 +234,11 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$accumulated = array(); $accumulated = array();
$last_key = last_key($columns); $last_key = last_key($columns);
foreach ($columns as $key => $column) { foreach ($columns as $key => $column) {
$name = $column['name'];
$type = $column['type']; $type = $column['type'];
switch ($type) { switch ($type) {
case 'null':
$value = qsprintf($conn, '%d', ($column['value'] ? 0 : 1));
break;
case 'int': case 'int':
$value = qsprintf($conn, '%d', $column['value']); $value = qsprintf($conn, '%d', $column['value']);
break; break;
@ -252,10 +256,23 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$reverse = ($is_query_reversed xor $is_column_reversed); $reverse = ($is_query_reversed xor $is_column_reversed);
$clause = $accumulated; $clause = $accumulated;
$table_name = idx($column, 'table');
$column_name = $column['column'];
if ($table_name !== null) {
$field = qsprintf($conn, '%T.%T', $table_name, $column_name);
} else {
$field = qsprintf($conn, '%T', $column_name);
}
if ($type == 'null') {
$field = qsprintf($conn, '(%Q IS NULL)', $field);
}
$clause[] = qsprintf( $clause[] = qsprintf(
$conn, $conn,
'%Q %Q %Q', '%Q %Q %Q',
$name, $field,
$reverse ? '>' : '<', $reverse ? '>' : '<',
$value); $value);
$clauses[] = '('.implode(') AND (', $clause).')'; $clauses[] = '('.implode(') AND (', $clause).')';
@ -263,7 +280,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$accumulated[] = qsprintf( $accumulated[] = qsprintf(
$conn, $conn,
'%Q = %Q', '%Q = %Q',
$name, $field,
$value); $value);
} }