Page MenuHomestyx hydra

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/src/applications/almanac/query/AlmanacBindingQuery.php b/src/applications/almanac/query/AlmanacBindingQuery.php
index dd4336db8c..0b6d7cda3a 100644
--- a/src/applications/almanac/query/AlmanacBindingQuery.php
+++ b/src/applications/almanac/query/AlmanacBindingQuery.php
@@ -1,139 +1,139 @@
<?php
final class AlmanacBindingQuery
extends AlmanacQuery {
private $ids;
private $phids;
private $servicePHIDs;
private $devicePHIDs;
private $interfacePHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withServicePHIDs(array $phids) {
$this->servicePHIDs = $phids;
return $this;
}
public function withDevicePHIDs(array $phids) {
$this->devicePHIDs = $phids;
return $this;
}
public function withInterfacePHIDs(array $phids) {
$this->interfacePHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new AlmanacBinding();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $bindings) {
$service_phids = mpull($bindings, 'getServicePHID');
$device_phids = mpull($bindings, 'getDevicePHID');
$interface_phids = mpull($bindings, 'getInterfacePHID');
$services = id(new AlmanacServiceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($service_phids)
->execute();
$services = mpull($services, null, 'getPHID');
$devices = id(new AlmanacDeviceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($device_phids)
->execute();
$devices = mpull($devices, null, 'getPHID');
$interfaces = id(new AlmanacInterfaceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($interface_phids)
->execute();
$interfaces = mpull($interfaces, null, 'getPHID');
foreach ($bindings as $key => $binding) {
$service = idx($services, $binding->getServicePHID());
$device = idx($devices, $binding->getDevicePHID());
$interface = idx($interfaces, $binding->getInterfacePHID());
if (!$service || !$device || !$interface) {
$this->didRejectResult($binding);
unset($bindings[$key]);
continue;
}
$binding->attachService($service);
$binding->attachDevice($device);
$binding->attachInterface($interface);
}
return $bindings;
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->servicePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'servicePHID IN (%Ls)',
$this->servicePHIDs);
}
if ($this->devicePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'devicePHID IN (%Ls)',
$this->devicePHIDs);
}
if ($this->interfacePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'interfacePHID IN (%Ls)',
$this->interfacePHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/almanac/query/AlmanacDeviceQuery.php b/src/applications/almanac/query/AlmanacDeviceQuery.php
index bd1797088f..287af6c647 100644
--- a/src/applications/almanac/query/AlmanacDeviceQuery.php
+++ b/src/applications/almanac/query/AlmanacDeviceQuery.php
@@ -1,103 +1,103 @@
<?php
final class AlmanacDeviceQuery
extends AlmanacQuery {
private $ids;
private $phids;
private $names;
private $namePrefix;
private $nameSuffix;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function withNamePrefix($prefix) {
$this->namePrefix = $prefix;
return $this;
}
public function withNameSuffix($suffix) {
$this->nameSuffix = $suffix;
return $this;
}
protected function loadPage() {
$table = new AlmanacDevice();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->names !== null) {
$hashes = array();
foreach ($this->names as $name) {
$hashes[] = PhabricatorHash::digestForIndex($name);
}
$where[] = qsprintf(
$conn_r,
'nameIndex IN (%Ls)',
$hashes);
}
if ($this->namePrefix !== null) {
$where[] = qsprintf(
$conn_r,
'name LIKE %>',
$this->namePrefix);
}
if ($this->nameSuffix !== null) {
$where[] = qsprintf(
$conn_r,
'name LIKE %<',
$this->nameSuffix);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
}
diff --git a/src/applications/almanac/query/AlmanacInterfaceQuery.php b/src/applications/almanac/query/AlmanacInterfaceQuery.php
index 7e2a867d29..e119203da5 100644
--- a/src/applications/almanac/query/AlmanacInterfaceQuery.php
+++ b/src/applications/almanac/query/AlmanacInterfaceQuery.php
@@ -1,139 +1,139 @@
<?php
final class AlmanacInterfaceQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $networkPHIDs;
private $devicePHIDs;
private $addresses;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withNetworkPHIDs(array $phids) {
$this->networkPHIDs = $phids;
return $this;
}
public function withDevicePHIDs(array $phids) {
$this->devicePHIDs = $phids;
return $this;
}
public function withAddresses(array $addresses) {
$this->addresses = $addresses;
return $this;
}
protected function loadPage() {
$table = new AlmanacInterface();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $interfaces) {
$network_phids = mpull($interfaces, 'getNetworkPHID');
$device_phids = mpull($interfaces, 'getDevicePHID');
$networks = id(new AlmanacNetworkQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($network_phids)
->execute();
$networks = mpull($networks, null, 'getPHID');
$devices = id(new AlmanacDeviceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($device_phids)
->execute();
$devices = mpull($devices, null, 'getPHID');
foreach ($interfaces as $key => $interface) {
$network = idx($networks, $interface->getNetworkPHID());
$device = idx($devices, $interface->getDevicePHID());
if (!$network || !$device) {
$this->didRejectResult($interface);
unset($interfaces[$key]);
continue;
}
$interface->attachNetwork($network);
$interface->attachDevice($device);
}
return $interfaces;
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->networkPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'networkPHID IN (%Ls)',
$this->networkPHIDs);
}
if ($this->devicePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'devicePHID IN (%Ls)',
$this->devicePHIDs);
}
if ($this->addresses !== null) {
$parts = array();
foreach ($this->addresses as $address) {
$parts[] = qsprintf(
$conn_r,
'(networkPHID = %s AND address = %s AND port = %d)',
$address->getNetworkPHID(),
$address->getAddress(),
$address->getPort());
}
$where[] = implode(' OR ', $parts);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
}
diff --git a/src/applications/almanac/query/AlmanacNetworkQuery.php b/src/applications/almanac/query/AlmanacNetworkQuery.php
index 1eb43fa828..d33def72ea 100644
--- a/src/applications/almanac/query/AlmanacNetworkQuery.php
+++ b/src/applications/almanac/query/AlmanacNetworkQuery.php
@@ -1,60 +1,60 @@
<?php
final class AlmanacNetworkQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new AlmanacNetwork();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
}
diff --git a/src/applications/almanac/query/AlmanacPropertyQuery.php b/src/applications/almanac/query/AlmanacPropertyQuery.php
index 470ea62618..886c26a7be 100644
--- a/src/applications/almanac/query/AlmanacPropertyQuery.php
+++ b/src/applications/almanac/query/AlmanacPropertyQuery.php
@@ -1,111 +1,111 @@
<?php
final class AlmanacPropertyQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $objectPHIDs;
private $names;
private $disablePolicyFilteringAndAttachment;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function setDisablePolicyFilteringAndAttachment($disable) {
$this->disablePolicyFilteringAndAttachment = $disable;
return $this;
}
protected function shouldDisablePolicyFiltering() {
return $this->disablePolicyFilteringAndAttachment;
}
protected function loadPage() {
$table = new AlmanacProperty();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $properties) {
if (!$this->disablePolicyFilteringAndAttachment) {
$object_phids = mpull($properties, 'getObjectPHID');
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($object_phids)
->execute();
$objects = mpull($objects, null, 'getPHID');
foreach ($properties as $key => $property) {
$object = idx($objects, $property->getObjectPHID());
if (!$object) {
unset($properties[$key]);
continue;
}
$property->attachObject($object);
}
}
return $properties;
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->names !== null) {
$hashes = array();
foreach ($this->names as $name) {
$hashes[] = PhabricatorHash::digestForIndex($name);
}
$where[] = qsprintf(
$conn_r,
'fieldIndex IN (%Ls)',
$hashes);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
}
diff --git a/src/applications/almanac/query/AlmanacServiceQuery.php b/src/applications/almanac/query/AlmanacServiceQuery.php
index d9aca2650e..d961b2e4ab 100644
--- a/src/applications/almanac/query/AlmanacServiceQuery.php
+++ b/src/applications/almanac/query/AlmanacServiceQuery.php
@@ -1,224 +1,224 @@
<?php
final class AlmanacServiceQuery
extends AlmanacQuery {
private $ids;
private $phids;
private $names;
private $serviceClasses;
private $devicePHIDs;
private $locked;
private $namePrefix;
private $nameSuffix;
private $needBindings;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function withServiceClasses(array $classes) {
$this->serviceClasses = $classes;
return $this;
}
public function withDevicePHIDs(array $phids) {
$this->devicePHIDs = $phids;
return $this;
}
public function withLocked($locked) {
$this->locked = $locked;
return $this;
}
public function withNamePrefix($prefix) {
$this->namePrefix = $prefix;
return $this;
}
public function withNameSuffix($suffix) {
$this->nameSuffix = $suffix;
return $this;
}
public function needBindings($need_bindings) {
$this->needBindings = $need_bindings;
return $this;
}
protected function loadPage() {
$table = new AlmanacService();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT service.* FROM %T service %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildJoinClause($conn_r) {
$joins = array();
if ($this->devicePHIDs !== null) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T binding ON service.phid = binding.servicePHID',
id(new AlmanacBinding())->getTableName());
}
return implode(' ', $joins);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'service.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'service.phid IN (%Ls)',
$this->phids);
}
if ($this->names !== null) {
$hashes = array();
foreach ($this->names as $name) {
$hashes[] = PhabricatorHash::digestForIndex($name);
}
$where[] = qsprintf(
$conn_r,
'service.nameIndex IN (%Ls)',
$hashes);
}
if ($this->serviceClasses !== null) {
$where[] = qsprintf(
$conn_r,
'service.serviceClass IN (%Ls)',
$this->serviceClasses);
}
if ($this->devicePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'binding.devicePHID IN (%Ls)',
$this->devicePHIDs);
}
if ($this->locked !== null) {
$where[] = qsprintf(
$conn_r,
'service.isLocked = %d',
(int)$this->locked);
}
if ($this->namePrefix !== null) {
$where[] = qsprintf(
$conn_r,
'service.name LIKE %>',
$this->namePrefix);
}
if ($this->nameSuffix !== null) {
$where[] = qsprintf(
$conn_r,
'service.name LIKE %<',
$this->nameSuffix);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $services) {
$service_types = AlmanacServiceType::getAllServiceTypes();
foreach ($services as $key => $service) {
$service_class = $service->getServiceClass();
$service_type = idx($service_types, $service_class);
if (!$service_type) {
$this->didRejectResult($service);
unset($services[$key]);
continue;
}
$service->attachServiceType($service_type);
}
return $services;
}
protected function didFilterPage(array $services) {
if ($this->needBindings) {
$service_phids = mpull($services, 'getPHID');
$bindings = id(new AlmanacBindingQuery())
->setViewer($this->getViewer())
->withServicePHIDs($service_phids)
->execute();
$bindings = mgroup($bindings, 'getServicePHID');
foreach ($services as $service) {
$service_bindings = idx($bindings, $service->getPHID(), array());
$service->attachBindings($service_bindings);
}
}
return parent::didFilterPage($services);
}
public function getOrderableColumns() {
return parent::getOrderableColumns() + array(
'name' => array(
'table' => 'service',
'column' => 'name',
'type' => 'string',
'unique' => true,
'reverse' => true,
),
);
}
protected function getValueMap($cursor, array $keys) {
$service = $this->loadCursorObject($cursor);
return array(
'id' => $service->getID(),
'name' => $service->getServiceName(),
);
}
public function getBuiltinOrders() {
return array(
'name' => array(
'vector' => array('name'),
'name' => pht('Service Name'),
),
) + parent::getBuiltinOrders();
}
}
diff --git a/src/applications/calendar/query/PhabricatorCalendarEventQuery.php b/src/applications/calendar/query/PhabricatorCalendarEventQuery.php
index f6feea5041..cdfeb0ca43 100644
--- a/src/applications/calendar/query/PhabricatorCalendarEventQuery.php
+++ b/src/applications/calendar/query/PhabricatorCalendarEventQuery.php
@@ -1,111 +1,111 @@
<?php
final class PhabricatorCalendarEventQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $rangeBegin;
private $rangeEnd;
private $invitedPHIDs;
private $creatorPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withDateRange($begin, $end) {
$this->rangeBegin = $begin;
$this->rangeEnd = $end;
return $this;
}
public function withInvitedPHIDs(array $phids) {
$this->invitedPHIDs = $phids;
return $this;
}
public function withCreatorPHIDs(array $phids) {
$this->creatorPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorCalendarEvent();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->rangeBegin) {
$where[] = qsprintf(
$conn_r,
'dateTo >= %d',
$this->rangeBegin);
}
if ($this->rangeEnd) {
$where[] = qsprintf(
$conn_r,
'dateFrom <= %d',
$this->rangeEnd);
}
// TODO: Currently, the creator is always the only invitee, but you can
// query them separately since this won't always be true.
if ($this->invitedPHIDs) {
$where[] = qsprintf(
$conn_r,
'userPHID IN (%Ls)',
$this->invitedPHIDs);
}
if ($this->creatorPHIDs) {
$where[] = qsprintf(
$conn_r,
'userPHID IN (%Ls)',
$this->creatorPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorCalendarApplication';
}
}
diff --git a/src/applications/chatlog/query/PhabricatorChatLogChannelQuery.php b/src/applications/chatlog/query/PhabricatorChatLogChannelQuery.php
index 4dcc4a16a9..2aded5c11b 100644
--- a/src/applications/chatlog/query/PhabricatorChatLogChannelQuery.php
+++ b/src/applications/chatlog/query/PhabricatorChatLogChannelQuery.php
@@ -1,63 +1,63 @@
<?php
final class PhabricatorChatLogChannelQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $channels;
private $channelIDs;
public function withChannelNames(array $channels) {
$this->channels = $channels;
return $this;
}
public function withIDs(array $channel_ids) {
$this->channelIDs = $channel_ids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorChatLogChannel();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T c %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$logs = $table->loadAllFromArray($data);
return $logs;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->channelIDs) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->channelIDs);
}
if ($this->channels) {
$where[] = qsprintf(
$conn_r,
'channelName IN (%Ls)',
$this->channels);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorChatLogApplication';
}
}
diff --git a/src/applications/chatlog/query/PhabricatorChatLogQuery.php b/src/applications/chatlog/query/PhabricatorChatLogQuery.php
index cb7fe53128..d174fdac90 100644
--- a/src/applications/chatlog/query/PhabricatorChatLogQuery.php
+++ b/src/applications/chatlog/query/PhabricatorChatLogQuery.php
@@ -1,84 +1,84 @@
<?php
final class PhabricatorChatLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $channelIDs;
private $maximumEpoch;
public function withChannelIDs(array $channel_ids) {
$this->channelIDs = $channel_ids;
return $this;
}
public function withMaximumEpoch($epoch) {
$this->maximumEpoch = $epoch;
return $this;
}
protected function loadPage() {
$table = new PhabricatorChatLogEvent();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T e %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$logs = $table->loadAllFromArray($data);
return $logs;
}
protected function willFilterPage(array $events) {
$channel_ids = mpull($events, 'getChannelID', 'getChannelID');
$channels = id(new PhabricatorChatLogChannelQuery())
->setViewer($this->getViewer())
->withIDs($channel_ids)
->execute();
$channels = mpull($channels, null, 'getID');
foreach ($events as $key => $event) {
$channel = idx($channels, $event->getChannelID());
if (!$channel) {
unset($events[$key]);
continue;
}
$event->attachChannel($channel);
}
return $events;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->maximumEpoch) {
$where[] = qsprintf(
$conn_r,
'epoch <= %d',
$this->maximumEpoch);
}
if ($this->channelIDs) {
$where[] = qsprintf(
$conn_r,
'channelID IN (%Ld)',
$this->channelIDs);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorChatLogApplication';
}
}
diff --git a/src/applications/conduit/query/PhabricatorConduitLogQuery.php b/src/applications/conduit/query/PhabricatorConduitLogQuery.php
index 56934caf45..4d66cccae5 100644
--- a/src/applications/conduit/query/PhabricatorConduitLogQuery.php
+++ b/src/applications/conduit/query/PhabricatorConduitLogQuery.php
@@ -1,46 +1,46 @@
<?php
final class PhabricatorConduitLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $methods;
public function withMethods(array $methods) {
$this->methods = $methods;
return $this;
}
protected function loadPage() {
$table = new PhabricatorConduitMethodCallLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->methods) {
$where[] = qsprintf(
$conn_r,
'method IN (%Ls)',
$this->methods);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorConduitApplication';
}
}
diff --git a/src/applications/conduit/query/PhabricatorConduitTokenQuery.php b/src/applications/conduit/query/PhabricatorConduitTokenQuery.php
index 563e437a4a..870043cac8 100644
--- a/src/applications/conduit/query/PhabricatorConduitTokenQuery.php
+++ b/src/applications/conduit/query/PhabricatorConduitTokenQuery.php
@@ -1,128 +1,128 @@
<?php
final class PhabricatorConduitTokenQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $objectPHIDs;
private $expired;
private $tokens;
private $tokenTypes;
public function withExpired($expired) {
$this->expired = $expired;
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
public function withTokens(array $tokens) {
$this->tokens = $tokens;
return $this;
}
public function withTokenTypes(array $types) {
$this->tokenTypes = $types;
return $this;
}
protected function loadPage() {
$table = new PhabricatorConduitToken();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->tokens !== null) {
$where[] = qsprintf(
$conn_r,
'token IN (%Ls)',
$this->tokens);
}
if ($this->tokenTypes !== null) {
$where[] = qsprintf(
$conn_r,
'tokenType IN (%Ls)',
$this->tokenTypes);
}
if ($this->expired !== null) {
if ($this->expired) {
$where[] = qsprintf(
$conn_r,
'expires <= %d',
PhabricatorTime::getNow());
} else {
$where[] = qsprintf(
$conn_r,
'expires IS NULL OR expires > %d',
PhabricatorTime::getNow());
}
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $tokens) {
$object_phids = mpull($tokens, 'getObjectPHID');
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($object_phids)
->execute();
$objects = mpull($objects, null, 'getPHID');
foreach ($tokens as $key => $token) {
$object = idx($objects, $token->getObjectPHID(), null);
if (!$object) {
$this->didRejectResult($token);
unset($tokens[$key]);
continue;
}
$token->attachObject($object);
}
return $tokens;
}
public function getQueryApplicationClass() {
return 'PhabricatorConduitApplication';
}
}
diff --git a/src/applications/config/query/PhabricatorConfigEntryQuery.php b/src/applications/config/query/PhabricatorConfigEntryQuery.php
index 01982ca7d0..56bf15a267 100644
--- a/src/applications/config/query/PhabricatorConfigEntryQuery.php
+++ b/src/applications/config/query/PhabricatorConfigEntryQuery.php
@@ -1,60 +1,60 @@
<?php
final class PhabricatorConfigEntryQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids;
private $ids;
public function withIDs($ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs($phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorConfigEntry();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorConfigApplication';
}
}
diff --git a/src/applications/conpherence/query/ConpherenceFulltextQuery.php b/src/applications/conpherence/query/ConpherenceFulltextQuery.php
index 780c4914cf..244791076c 100644
--- a/src/applications/conpherence/query/ConpherenceFulltextQuery.php
+++ b/src/applications/conpherence/query/ConpherenceFulltextQuery.php
@@ -1,68 +1,68 @@
<?php
final class ConpherenceFulltextQuery
extends PhabricatorOffsetPagedQuery {
private $threadPHIDs;
private $fulltext;
public function withThreadPHIDs(array $phids) {
$this->threadPHIDs = $phids;
return $this;
}
public function withFulltext($fulltext) {
$this->fulltext = $fulltext;
return $this;
}
public function execute() {
$table = new ConpherenceIndex();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT threadPHID, transactionPHID, previousTransactionPHID
FROM %T i %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderByClause($conn_r),
$this->buildLimitClause($conn_r));
return $rows;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->threadPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'i.threadPHID IN (%Ls)',
$this->threadPHIDs);
}
if (strlen($this->fulltext)) {
$where[] = qsprintf(
$conn_r,
'MATCH(i.corpus) AGAINST (%s IN BOOLEAN MODE)',
$this->fulltext);
}
return $this->formatWhereClause($where);
}
private function buildOrderByClause(AphrontDatabaseConnection $conn_r) {
if (strlen($this->fulltext)) {
return qsprintf(
$conn_r,
'ORDER BY MATCH(i.corpus) AGAINST (%s IN BOOLEAN MODE) DESC',
$this->fulltext);
} else {
return qsprintf(
$conn_r,
'ORDER BY id DESC');
}
}
}
diff --git a/src/applications/conpherence/query/ConpherenceParticipantCountQuery.php b/src/applications/conpherence/query/ConpherenceParticipantCountQuery.php
index 1d0cb81f8c..7a4f170c3a 100644
--- a/src/applications/conpherence/query/ConpherenceParticipantCountQuery.php
+++ b/src/applications/conpherence/query/ConpherenceParticipantCountQuery.php
@@ -1,73 +1,73 @@
<?php
/**
* Query class that answers the question:
*
* - Q: How many unread conpherences am I participating in?
* - A:
* id(new ConpherenceParticipantCountQuery())
* ->withParticipantPHIDs(array($my_phid))
* ->withParticipationStatus(ConpherenceParticipationStatus::BEHIND)
* ->execute();
*/
final class ConpherenceParticipantCountQuery
extends PhabricatorOffsetPagedQuery {
private $participantPHIDs;
private $participationStatus;
public function withParticipantPHIDs(array $phids) {
$this->participantPHIDs = $phids;
return $this;
}
public function withParticipationStatus($participation_status) {
$this->participationStatus = $participation_status;
return $this;
}
public function execute() {
$table = new ConpherenceParticipant();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT COUNT(*) as count, participantPHID '.
'FROM %T participant %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildGroupByClause($conn_r),
$this->buildLimitClause($conn_r));
return ipull($rows, 'count', 'participantPHID');
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->participantPHIDs) {
$where[] = qsprintf(
$conn_r,
'participantPHID IN (%Ls)',
$this->participantPHIDs);
}
if ($this->participationStatus !== null) {
$where[] = qsprintf(
$conn_r,
'participationStatus = %d',
$this->participationStatus);
}
return $this->formatWhereClause($where);
}
private function buildGroupByClause(AphrontDatabaseConnection $conn_r) {
$group_by = qsprintf(
$conn_r,
'GROUP BY participantPHID');
return $group_by;
}
}
diff --git a/src/applications/conpherence/query/ConpherenceParticipantQuery.php b/src/applications/conpherence/query/ConpherenceParticipantQuery.php
index f9c31deed6..bb879be4e4 100644
--- a/src/applications/conpherence/query/ConpherenceParticipantQuery.php
+++ b/src/applications/conpherence/query/ConpherenceParticipantQuery.php
@@ -1,128 +1,128 @@
<?php
/**
* Query class that answers these questions:
*
* - Q: What are the conpherences to show when I land on /conpherence/ ?
* - A:
*
* id(new ConpherenceParticipantQuery())
* ->withParticipantPHIDs(array($my_phid))
* ->execute();
*
* - Q: What are the next set of conpherences as I scroll up (more recent) or
* down (less recent) this list of conpherences?
* - A:
*
* id(new ConpherenceParticipantQuery())
* ->withParticipantPHIDs(array($my_phid))
* ->withParticipantCursor($top_participant)
* ->setOrder(ConpherenceParticipantQuery::ORDER_NEWER)
* ->execute();
*
* -or-
*
* id(new ConpherenceParticipantQuery())
* ->withParticipantPHIDs(array($my_phid))
* ->withParticipantCursor($bottom_participant)
* ->setOrder(ConpherenceParticipantQuery::ORDER_OLDER)
* ->execute();
*
* For counts of read, un-read, or all conpherences by participant, see
* @{class:ConpherenceParticipantCountQuery}.
*/
final class ConpherenceParticipantQuery extends PhabricatorOffsetPagedQuery {
const LIMIT = 100;
const ORDER_NEWER = 'newer';
const ORDER_OLDER = 'older';
private $participantPHIDs;
private $participantCursor;
private $order = self::ORDER_OLDER;
public function withParticipantPHIDs(array $phids) {
$this->participantPHIDs = $phids;
return $this;
}
public function withParticipantCursor(ConpherenceParticipant $participant) {
$this->participantCursor = $participant;
return $this;
}
public function setOrder($order) {
$this->order = $order;
return $this;
}
public function execute() {
$table = new ConpherenceParticipant();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T participant %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$participants = $table->loadAllFromArray($data);
$participants = mpull($participants, null, 'getConpherencePHID');
if ($this->order == self::ORDER_NEWER) {
$participants = array_reverse($participants);
}
return $participants;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->participantPHIDs) {
$where[] = qsprintf(
$conn_r,
'participantPHID IN (%Ls)',
$this->participantPHIDs);
}
if ($this->participantCursor) {
$date_touched = $this->participantCursor->getDateTouched();
$id = $this->participantCursor->getID();
if ($this->order == self::ORDER_OLDER) {
$compare_date = '<';
$compare_id = '<=';
} else {
$compare_date = '>';
$compare_id = '>=';
}
$where[] = qsprintf(
$conn_r,
'(dateTouched %Q %d OR (dateTouched = %d AND id %Q %d))',
$compare_date,
$date_touched,
$date_touched,
$compare_id,
$id);
}
return $this->formatWhereClause($where);
}
private function buildOrderClause(AphrontDatabaseConnection $conn_r) {
$order_word = ($this->order == self::ORDER_OLDER) ? 'DESC' : 'ASC';
// if these are different direction we won't get as efficient a query
// see http://dev.mysql.com/doc/refman/5.5/en/order-by-optimization.html
$order = qsprintf(
$conn_r,
'ORDER BY dateTouched %Q, id %Q',
$order_word,
$order_word);
return $order;
}
}
diff --git a/src/applications/conpherence/query/ConpherenceThreadQuery.php b/src/applications/conpherence/query/ConpherenceThreadQuery.php
index b5607c1061..c191a763b4 100644
--- a/src/applications/conpherence/query/ConpherenceThreadQuery.php
+++ b/src/applications/conpherence/query/ConpherenceThreadQuery.php
@@ -1,383 +1,383 @@
<?php
final class ConpherenceThreadQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
const TRANSACTION_LIMIT = 100;
private $phids;
private $ids;
private $participantPHIDs;
private $isRoom;
private $needParticipants;
private $needWidgetData;
private $needTransactions;
private $needParticipantCache;
private $needFilePHIDs;
private $afterTransactionID;
private $beforeTransactionID;
private $transactionLimit;
public function needFilePHIDs($need_file_phids) {
$this->needFilePHIDs = $need_file_phids;
return $this;
}
public function needParticipantCache($participant_cache) {
$this->needParticipantCache = $participant_cache;
return $this;
}
public function needParticipants($need) {
$this->needParticipants = $need;
return $this;
}
public function needWidgetData($need_widget_data) {
$this->needWidgetData = $need_widget_data;
return $this;
}
public function needTransactions($need_transactions) {
$this->needTransactions = $need_transactions;
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withParticipantPHIDs(array $phids) {
$this->participantPHIDs = $phids;
return $this;
}
public function withIsRoom($bool) {
$this->isRoom = $bool;
return $this;
}
public function setAfterTransactionID($id) {
$this->afterTransactionID = $id;
return $this;
}
public function setBeforeTransactionID($id) {
$this->beforeTransactionID = $id;
return $this;
}
public function setTransactionLimit($transaction_limit) {
$this->transactionLimit = $transaction_limit;
return $this;
}
public function getTransactionLimit() {
return $this->transactionLimit;
}
protected function loadPage() {
$table = new ConpherenceThread();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT conpherence_thread.* FROM %T conpherence_thread %Q %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$conpherences = $table->loadAllFromArray($data);
if ($conpherences) {
$conpherences = mpull($conpherences, null, 'getPHID');
$this->loadParticipantsAndInitHandles($conpherences);
if ($this->needParticipantCache) {
$this->loadCoreHandles($conpherences, 'getRecentParticipantPHIDs');
}
if ($this->needWidgetData || $this->needParticipants) {
$this->loadCoreHandles($conpherences, 'getParticipantPHIDs');
}
if ($this->needTransactions) {
$this->loadTransactionsAndHandles($conpherences);
}
if ($this->needFilePHIDs || $this->needWidgetData) {
$this->loadFilePHIDs($conpherences);
}
if ($this->needWidgetData) {
$this->loadWidgetData($conpherences);
}
}
return $conpherences;
}
private function buildGroupClause($conn_r) {
if ($this->participantPHIDs !== null) {
return 'GROUP BY conpherence_thread.id';
} else {
return $this->buildApplicationSearchGroupClause($conn_r);
}
}
private function buildJoinClause($conn_r) {
$joins = array();
if ($this->participantPHIDs !== null) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T p ON p.conpherencePHID = conpherence_thread.phid',
id(new ConpherenceParticipant())->getTableName());
}
$viewer = $this->getViewer();
if ($this->shouldJoinForViewer($viewer)) {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T v ON v.conpherencePHID = conpherence_thread.phid '.
'AND v.participantPHID = %s',
id(new ConpherenceParticipant())->getTableName(),
$viewer->getPHID());
}
$joins[] = $this->buildApplicationSearchJoinClause($conn_r);
return implode(' ', $joins);
}
private function shouldJoinForViewer(PhabricatorUser $viewer) {
if ($viewer->isLoggedIn() &&
$this->ids === null &&
$this->phids === null) {
return true;
}
return false;
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'conpherence_thread.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'conpherence_thread.phid IN (%Ls)',
$this->phids);
}
if ($this->participantPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'p.participantPHID IN (%Ls)',
$this->participantPHIDs);
}
if ($this->isRoom !== null) {
$where[] = qsprintf(
$conn_r,
'conpherence_thread.isRoom = %d',
(int)$this->isRoom);
}
$viewer = $this->getViewer();
if ($this->shouldJoinForViewer($viewer)) {
$where[] = qsprintf(
$conn_r,
'conpherence_thread.isRoom = 1 OR v.participantPHID IS NOT NULL');
} else if ($this->phids === null && $this->ids === null) {
$where[] = qsprintf(
$conn_r,
'conpherence_thread.isRoom = 1');
}
return $this->formatWhereClause($where);
}
private function loadParticipantsAndInitHandles(array $conpherences) {
$participants = id(new ConpherenceParticipant())
->loadAllWhere('conpherencePHID IN (%Ls)', array_keys($conpherences));
$map = mgroup($participants, 'getConpherencePHID');
foreach ($conpherences as $current_conpherence) {
$conpherence_phid = $current_conpherence->getPHID();
$conpherence_participants = idx(
$map,
$conpherence_phid,
array());
$conpherence_participants = mpull(
$conpherence_participants,
null,
'getParticipantPHID');
$current_conpherence->attachParticipants($conpherence_participants);
$current_conpherence->attachHandles(array());
}
return $this;
}
private function loadCoreHandles(
array $conpherences,
$method) {
$handle_phids = array();
foreach ($conpherences as $conpherence) {
$handle_phids[$conpherence->getPHID()] =
$conpherence->$method();
}
$flat_phids = array_mergev($handle_phids);
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs($flat_phids)
->execute();
foreach ($handle_phids as $conpherence_phid => $phids) {
$conpherence = $conpherences[$conpherence_phid];
$conpherence->attachHandles(
$conpherence->getHandles() + array_select_keys($handles, $phids));
}
return $this;
}
private function loadTransactionsAndHandles(array $conpherences) {
$query = id(new ConpherenceTransactionQuery())
->setViewer($this->getViewer())
->withObjectPHIDs(array_keys($conpherences))
->needHandles(true);
// We have to flip these for the underyling query class. The semantics of
// paging are tricky business.
if ($this->afterTransactionID) {
$query->setBeforeID($this->afterTransactionID);
} else if ($this->beforeTransactionID) {
$query->setAfterID($this->beforeTransactionID);
}
if ($this->getTransactionLimit()) {
// fetch an extra for "show older" scenarios
$query->setLimit($this->getTransactionLimit() + 1);
}
$transactions = $query->execute();
$transactions = mgroup($transactions, 'getObjectPHID');
foreach ($conpherences as $phid => $conpherence) {
$current_transactions = idx($transactions, $phid, array());
$handles = array();
foreach ($current_transactions as $transaction) {
$handles += $transaction->getHandles();
}
$conpherence->attachHandles($conpherence->getHandles() + $handles);
$conpherence->attachTransactions($current_transactions);
}
return $this;
}
private function loadFilePHIDs(array $conpherences) {
$edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST;
$file_edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array_keys($conpherences))
->withEdgeTypes(array($edge_type))
->execute();
foreach ($file_edges as $conpherence_phid => $data) {
$conpherence = $conpherences[$conpherence_phid];
$conpherence->attachFilePHIDs(array_keys($data[$edge_type]));
}
return $this;
}
private function loadWidgetData(array $conpherences) {
$participant_phids = array();
$file_phids = array();
foreach ($conpherences as $conpherence) {
$participant_phids[] = array_keys($conpherence->getParticipants());
$file_phids[] = $conpherence->getFilePHIDs();
}
$participant_phids = array_mergev($participant_phids);
$file_phids = array_mergev($file_phids);
$epochs = CalendarTimeUtil::getCalendarEventEpochs(
$this->getViewer());
$start_epoch = $epochs['start_epoch'];
$end_epoch = $epochs['end_epoch'];
$statuses = id(new PhabricatorCalendarEventQuery())
->setViewer($this->getViewer())
->withInvitedPHIDs($participant_phids)
->withDateRange($start_epoch, $end_epoch)
->execute();
$statuses = mgroup($statuses, 'getUserPHID');
// attached files
$files = array();
$file_author_phids = array();
$authors = array();
if ($file_phids) {
$files = id(new PhabricatorFileQuery())
->setViewer($this->getViewer())
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
$file_author_phids = mpull($files, 'getAuthorPHID', 'getPHID');
$authors = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs($file_author_phids)
->execute();
$authors = mpull($authors, null, 'getPHID');
}
foreach ($conpherences as $phid => $conpherence) {
$participant_phids = array_keys($conpherence->getParticipants());
$statuses = array_select_keys($statuses, $participant_phids);
$statuses = array_mergev($statuses);
$statuses = msort($statuses, 'getDateFrom');
$conpherence_files = array();
$files_authors = array();
foreach ($conpherence->getFilePHIDs() as $curr_phid) {
$curr_file = idx($files, $curr_phid);
if (!$curr_file) {
// this file was deleted or user doesn't have permission to see it
// this is generally weird
continue;
}
$conpherence_files[$curr_phid] = $curr_file;
// some files don't have authors so be careful
$current_author = null;
$current_author_phid = idx($file_author_phids, $curr_phid);
if ($current_author_phid) {
$current_author = $authors[$current_author_phid];
}
$files_authors[$curr_phid] = $current_author;
}
$widget_data = array(
'statuses' => $statuses,
'files' => $conpherence_files,
'files_authors' => $files_authors,
);
$conpherence->attachWidgetData($widget_data);
}
return $this;
}
public function getQueryApplicationClass() {
return 'PhabricatorConpherenceApplication';
}
}
diff --git a/src/applications/countdown/query/PhabricatorCountdownQuery.php b/src/applications/countdown/query/PhabricatorCountdownQuery.php
index 5d04dfde6a..c5f206a4e2 100644
--- a/src/applications/countdown/query/PhabricatorCountdownQuery.php
+++ b/src/applications/countdown/query/PhabricatorCountdownQuery.php
@@ -1,88 +1,88 @@
<?php
final class PhabricatorCountdownQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $upcoming;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withUpcoming($upcoming) {
$this->upcoming = true;
return $this;
}
protected function loadPage() {
$table = new PhabricatorCountdown();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$countdowns = $table->loadAllFromArray($data);
return $countdowns;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID in (%Ls)',
$this->authorPHIDs);
}
if ($this->upcoming) {
$where[] = qsprintf(
$conn_r,
'epoch >= %d',
time());
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorCountdownApplication';
}
}
diff --git a/src/applications/daemon/query/PhabricatorDaemonLogQuery.php b/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
index 545c412f86..5822194d06 100644
--- a/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
+++ b/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
@@ -1,194 +1,194 @@
<?php
final class PhabricatorDaemonLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
const STATUS_ALL = 'status-all';
const STATUS_ALIVE = 'status-alive';
const STATUS_RUNNING = 'status-running';
private $ids;
private $notIDs;
private $status = self::STATUS_ALL;
private $daemonClasses;
private $allowStatusWrites;
private $daemonIDs;
public static function getTimeUntilUnknown() {
return 3 * PhutilDaemonHandle::getHeartbeatEventFrequency();
}
public static function getTimeUntilDead() {
return 30 * PhutilDaemonHandle::getHeartbeatEventFrequency();
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withoutIDs(array $ids) {
$this->notIDs = $ids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withDaemonClasses(array $classes) {
$this->daemonClasses = $classes;
return $this;
}
public function setAllowStatusWrites($allow) {
$this->allowStatusWrites = $allow;
return $this;
}
public function withDaemonIDs(array $daemon_ids) {
$this->daemonIDs = $daemon_ids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorDaemonLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $daemons) {
$unknown_delay = PhabricatorDaemonLogQuery::getTimeUntilUnknown();
$dead_delay = PhabricatorDaemonLogQuery::getTimeUntilDead();
$status_running = PhabricatorDaemonLog::STATUS_RUNNING;
$status_unknown = PhabricatorDaemonLog::STATUS_UNKNOWN;
$status_wait = PhabricatorDaemonLog::STATUS_WAIT;
$status_exiting = PhabricatorDaemonLog::STATUS_EXITING;
$status_exited = PhabricatorDaemonLog::STATUS_EXITED;
$status_dead = PhabricatorDaemonLog::STATUS_DEAD;
$filter = array_fuse($this->getStatusConstants());
foreach ($daemons as $key => $daemon) {
$status = $daemon->getStatus();
$seen = $daemon->getDateModified();
$is_running = ($status == $status_running) ||
($status == $status_wait) ||
($status == $status_exiting);
// If we haven't seen the daemon recently, downgrade its status to
// unknown.
$unknown_time = ($seen + $unknown_delay);
if ($is_running && ($unknown_time < time())) {
$status = $status_unknown;
}
// If the daemon hasn't been seen in quite a while, assume it is dead.
$dead_time = ($seen + $dead_delay);
if (($status == $status_unknown) && ($dead_time < time())) {
$status = $status_dead;
}
// If we changed the daemon's status, adjust it.
if ($status != $daemon->getStatus()) {
$daemon->setStatus($status);
// ...and write it, if we're in a context where that's reasonable.
if ($this->allowStatusWrites) {
$guard = AphrontWriteGuard::beginScopedUnguardedWrites();
$daemon->save();
unset($guard);
}
}
// If the daemon no longer matches the filter, get rid of it.
if ($filter) {
if (empty($filter[$daemon->getStatus()])) {
unset($daemons[$key]);
}
}
}
return $daemons;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->notIDs !== null) {
$where[] = qsprintf(
$conn_r,
'id NOT IN (%Ld)',
$this->notIDs);
}
if ($this->getStatusConstants()) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ls)',
$this->getStatusConstants());
}
if ($this->daemonClasses !== null) {
$where[] = qsprintf(
$conn_r,
'daemon IN (%Ls)',
$this->daemonClasses);
}
if ($this->daemonIDs !== null) {
$where[] = qsprintf(
$conn_r,
'daemonID IN (%Ls)',
$this->daemonIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function getStatusConstants() {
$status = $this->status;
switch ($status) {
case self::STATUS_ALL:
return array();
case self::STATUS_RUNNING:
return array(
PhabricatorDaemonLog::STATUS_RUNNING,
);
case self::STATUS_ALIVE:
return array(
PhabricatorDaemonLog::STATUS_UNKNOWN,
PhabricatorDaemonLog::STATUS_RUNNING,
PhabricatorDaemonLog::STATUS_WAIT,
PhabricatorDaemonLog::STATUS_EXITING,
);
default:
throw new Exception(pht('Unknown status "%s"!', $status));
}
}
public function getQueryApplicationClass() {
return 'PhabricatorDaemonsApplication';
}
}
diff --git a/src/applications/dashboard/query/PhabricatorDashboardPanelQuery.php b/src/applications/dashboard/query/PhabricatorDashboardPanelQuery.php
index 9641f33338..a9a062ffb2 100644
--- a/src/applications/dashboard/query/PhabricatorDashboardPanelQuery.php
+++ b/src/applications/dashboard/query/PhabricatorDashboardPanelQuery.php
@@ -1,86 +1,86 @@
<?php
final class PhabricatorDashboardPanelQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $archived;
private $panelTypes;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withArchived($archived) {
$this->archived = $archived;
return $this;
}
public function withPanelTypes(array $types) {
$this->panelTypes = $types;
return $this;
}
protected function loadPage() {
$table = new PhabricatorDashboardPanel();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->archived !== null) {
$where[] = qsprintf(
$conn_r,
'isArchived = %d',
(int)$this->archived);
}
if ($this->panelTypes !== null) {
$where[] = qsprintf(
$conn_r,
'panelType IN (%Ls)',
$this->panelTypes);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDashboardApplication';
}
}
diff --git a/src/applications/dashboard/query/PhabricatorDashboardQuery.php b/src/applications/dashboard/query/PhabricatorDashboardQuery.php
index d8ba184e81..324151e722 100644
--- a/src/applications/dashboard/query/PhabricatorDashboardQuery.php
+++ b/src/applications/dashboard/query/PhabricatorDashboardQuery.php
@@ -1,102 +1,102 @@
<?php
final class PhabricatorDashboardQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $needPanels;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function needPanels($need_panels) {
$this->needPanels = $need_panels;
return $this;
}
protected function loadPage() {
$table = new PhabricatorDashboard();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function didFilterPage(array $dashboards) {
if ($this->needPanels) {
$edge_query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($dashboards, 'getPHID'))
->withEdgeTypes(
array(
PhabricatorDashboardDashboardHasPanelEdgeType::EDGECONST,
));
$edge_query->execute();
$panel_phids = $edge_query->getDestinationPHIDs();
if ($panel_phids) {
$panels = id(new PhabricatorDashboardPanelQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($panel_phids)
->execute();
$panels = mpull($panels, null, 'getPHID');
} else {
$panels = array();
}
foreach ($dashboards as $dashboard) {
$dashboard_phids = $edge_query->getDestinationPHIDs(
array($dashboard->getPHID()));
$dashboard_panels = array_select_keys($panels, $dashboard_phids);
$dashboard->attachPanelPHIDs($dashboard_phids);
$dashboard->attachPanels($dashboard_panels);
}
}
return $dashboards;
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDashboardApplication';
}
}
diff --git a/src/applications/differential/query/DifferentialChangesetQuery.php b/src/applications/differential/query/DifferentialChangesetQuery.php
index 6cb60e04e9..7b9f2e6d10 100644
--- a/src/applications/differential/query/DifferentialChangesetQuery.php
+++ b/src/applications/differential/query/DifferentialChangesetQuery.php
@@ -1,153 +1,153 @@
<?php
final class DifferentialChangesetQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $diffs;
private $needAttachToDiffs;
private $needHunks;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withDiffs(array $diffs) {
assert_instances_of($diffs, 'DifferentialDiff');
$this->diffs = $diffs;
return $this;
}
public function needAttachToDiffs($attach) {
$this->needAttachToDiffs = $attach;
return $this;
}
public function needHunks($need) {
$this->needHunks = $need;
return $this;
}
protected function willExecute() {
// If we fail to load any changesets (which is possible in the case of an
// empty commit) we'll never call didFilterPage(). Attach empty changeset
// lists now so that we end up with the right result.
if ($this->needAttachToDiffs) {
foreach ($this->diffs as $diff) {
$diff->attachChangesets(array());
}
}
}
protected function loadPage() {
$table = new DifferentialChangeset();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $changesets) {
// First, attach all the diffs we already have. We can just do this
// directly without worrying about querying for them. When we don't have
// a diff, record that we need to load it.
if ($this->diffs) {
$have_diffs = mpull($this->diffs, null, 'getID');
} else {
$have_diffs = array();
}
$must_load = array();
foreach ($changesets as $key => $changeset) {
$diff_id = $changeset->getDiffID();
if (isset($have_diffs[$diff_id])) {
$changeset->attachDiff($have_diffs[$diff_id]);
} else {
$must_load[$key] = $changeset;
}
}
// Load all the diffs we don't have.
$need_diff_ids = mpull($must_load, 'getDiffID');
$more_diffs = array();
if ($need_diff_ids) {
$more_diffs = id(new DifferentialDiffQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withIDs($need_diff_ids)
->execute();
$more_diffs = mpull($more_diffs, null, 'getID');
}
// Attach the diffs we loaded.
foreach ($must_load as $key => $changeset) {
$diff_id = $changeset->getDiffID();
if (isset($more_diffs[$diff_id])) {
$changeset->attachDiff($more_diffs[$diff_id]);
} else {
// We didn't have the diff, and could not load it (it does not exist,
// or we can't see it), so filter this result out.
unset($changesets[$key]);
}
}
return $changesets;
}
protected function didFilterPage(array $changesets) {
if ($this->needAttachToDiffs) {
$changeset_groups = mgroup($changesets, 'getDiffID');
foreach ($this->diffs as $diff) {
$diff_changesets = idx($changeset_groups, $diff->getID(), array());
$diff->attachChangesets($diff_changesets);
}
}
if ($this->needHunks) {
id(new DifferentialHunkQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withChangesets($changesets)
->needAttachToChangesets(true)
->execute();
}
return $changesets;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->diffs !== null) {
$where[] = qsprintf(
$conn_r,
'diffID IN (%Ld)',
mpull($this->diffs, 'getID'));
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
}
diff --git a/src/applications/differential/query/DifferentialDiffQuery.php b/src/applications/differential/query/DifferentialDiffQuery.php
index 3d58e12f8a..15ddc9c46b 100644
--- a/src/applications/differential/query/DifferentialDiffQuery.php
+++ b/src/applications/differential/query/DifferentialDiffQuery.php
@@ -1,156 +1,156 @@
<?php
final class DifferentialDiffQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $revisionIDs;
private $needChangesets = false;
private $needArcanistProjects = false;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRevisionIDs(array $revision_ids) {
$this->revisionIDs = $revision_ids;
return $this;
}
public function needChangesets($bool) {
$this->needChangesets = $bool;
return $this;
}
public function needArcanistProjects($bool) {
$this->needArcanistProjects = $bool;
return $this;
}
protected function loadPage() {
$table = new DifferentialDiff();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $diffs) {
$revision_ids = array_filter(mpull($diffs, 'getRevisionID'));
$revisions = array();
if ($revision_ids) {
$revisions = id(new DifferentialRevisionQuery())
->setViewer($this->getViewer())
->withIDs($revision_ids)
->execute();
}
foreach ($diffs as $key => $diff) {
if (!$diff->getRevisionID()) {
continue;
}
$revision = idx($revisions, $diff->getRevisionID());
if ($revision) {
$diff->attachRevision($revision);
continue;
}
unset($diffs[$key]);
}
if ($diffs && $this->needChangesets) {
$diffs = $this->loadChangesets($diffs);
}
if ($diffs && $this->needArcanistProjects) {
$diffs = $this->loadArcanistProjects($diffs);
}
return $diffs;
}
private function loadChangesets(array $diffs) {
id(new DifferentialChangesetQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withDiffs($diffs)
->needAttachToDiffs(true)
->needHunks(true)
->execute();
return $diffs;
}
private function loadArcanistProjects(array $diffs) {
$phids = array_filter(mpull($diffs, 'getArcanistProjectPHID'));
$projects = array();
$project_map = array();
if ($phids) {
$projects = id(new PhabricatorRepositoryArcanistProject())
->loadAllWhere(
'phid IN (%Ls)',
$phids);
$project_map = mpull($projects, null, 'getPHID');
}
foreach ($diffs as $diff) {
$project = null;
if ($diff->getArcanistProjectPHID()) {
$project = idx($project_map, $diff->getArcanistProjectPHID());
}
$diff->attachArcanistProject($project);
}
return $diffs;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->revisionIDs) {
$where[] = qsprintf(
$conn_r,
'revisionID IN (%Ld)',
$this->revisionIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
}
diff --git a/src/applications/differential/query/DifferentialHunkQuery.php b/src/applications/differential/query/DifferentialHunkQuery.php
index 94bc0297b3..3c9f898810 100644
--- a/src/applications/differential/query/DifferentialHunkQuery.php
+++ b/src/applications/differential/query/DifferentialHunkQuery.php
@@ -1,120 +1,120 @@
<?php
final class DifferentialHunkQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $changesets;
private $shouldAttachToChangesets;
public function withChangesets(array $changesets) {
assert_instances_of($changesets, 'DifferentialChangeset');
$this->changesets = $changesets;
return $this;
}
public function needAttachToChangesets($attach) {
$this->shouldAttachToChangesets = $attach;
return $this;
}
protected function willExecute() {
// If we fail to load any hunks at all (for example, because all of
// the requested changesets are directories or empty files and have no
// hunks) we'll never call didFilterPage(), and thus never have an
// opportunity to attach hunks. Attach empty hunk lists now so that we
// end up with the right result.
if ($this->shouldAttachToChangesets) {
foreach ($this->changesets as $changeset) {
$changeset->attachHunks(array());
}
}
}
protected function loadPage() {
$all_results = array();
// Load modern hunks.
$table = new DifferentialModernHunk();
$conn_r = $table->establishConnection('r');
$modern_data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$modern_results = $table->loadAllFromArray($modern_data);
// Now, load legacy hunks.
$table = new DifferentialLegacyHunk();
$conn_r = $table->establishConnection('r');
$legacy_data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$legacy_results = $table->loadAllFromArray($legacy_data);
// Strip all the IDs off since they're not unique and nothing should be
// using them.
return array_values(array_merge($legacy_results, $modern_results));
}
protected function willFilterPage(array $hunks) {
$changesets = mpull($this->changesets, null, 'getID');
foreach ($hunks as $key => $hunk) {
$changeset = idx($changesets, $hunk->getChangesetID());
if (!$changeset) {
unset($hunks[$key]);
}
$hunk->attachChangeset($changeset);
}
return $hunks;
}
protected function didFilterPage(array $hunks) {
if ($this->shouldAttachToChangesets) {
$hunk_groups = mgroup($hunks, 'getChangesetID');
foreach ($this->changesets as $changeset) {
$hunks = idx($hunk_groups, $changeset->getID(), array());
$changeset->attachHunks($hunks);
}
}
return $hunks;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if (!$this->changesets) {
throw new Exception(
pht('You must load hunks via changesets, with withChangesets()!'));
}
$where[] = qsprintf(
$conn_r,
'changesetID IN (%Ld)',
mpull($this->changesets, 'getID'));
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
protected function getDefaultOrderVector() {
// TODO: Do we need this?
return array('-id');
}
}
diff --git a/src/applications/differential/query/DifferentialInlineCommentQuery.php b/src/applications/differential/query/DifferentialInlineCommentQuery.php
index f605a78b02..127dcb7c7d 100644
--- a/src/applications/differential/query/DifferentialInlineCommentQuery.php
+++ b/src/applications/differential/query/DifferentialInlineCommentQuery.php
@@ -1,170 +1,170 @@
<?php
/**
* Temporary wrapper for transitioning Differential to ApplicationTransactions.
*/
final class DifferentialInlineCommentQuery
extends PhabricatorOffsetPagedQuery {
private $revisionIDs;
private $notDraft;
private $ids;
private $phids;
private $commentIDs;
private $viewerAndChangesetIDs;
private $draftComments;
private $draftsByAuthors;
public function withRevisionIDs(array $ids) {
$this->revisionIDs = $ids;
return $this;
}
public function withNotDraft($not_draft) {
$this->notDraft = $not_draft;
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withViewerAndChangesetIDs($author_phid, array $ids) {
$this->viewerAndChangesetIDs = array($author_phid, $ids);
return $this;
}
public function withDraftComments($author_phid, $revision_id) {
$this->draftComments = array($author_phid, $revision_id);
return $this;
}
public function withDraftsByAuthors(array $author_phids) {
$this->draftsByAuthors = $author_phids;
return $this;
}
public function execute() {
$table = new DifferentialTransactionComment();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildLimitClause($conn_r));
$comments = $table->loadAllFromArray($data);
foreach ($comments as $key => $value) {
$comments[$key] = DifferentialInlineComment::newFromModernComment(
$value);
}
return $comments;
}
public function executeOne() {
return head($this->execute());
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
// Only find inline comments.
$where[] = qsprintf(
$conn_r,
'changesetID IS NOT NULL');
if ($this->revisionIDs) {
// Look up revision PHIDs.
$revision_phids = queryfx_all(
$conn_r,
'SELECT phid FROM %T WHERE id IN (%Ld)',
id(new DifferentialRevision())->getTableName(),
$this->revisionIDs);
if (!$revision_phids) {
throw new PhabricatorEmptyQueryException();
}
$revision_phids = ipull($revision_phids, 'phid');
$where[] = qsprintf(
$conn_r,
'revisionPHID IN (%Ls)',
$revision_phids);
}
if ($this->notDraft) {
$where[] = qsprintf(
$conn_r,
'transactionPHID IS NOT NULL');
}
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->viewerAndChangesetIDs) {
list($phid, $ids) = $this->viewerAndChangesetIDs;
$where[] = qsprintf(
$conn_r,
'changesetID IN (%Ld) AND
((authorPHID = %s AND isDeleted = 0) OR transactionPHID IS NOT NULL)',
$ids,
$phid);
}
if ($this->draftComments) {
list($phid, $rev_id) = $this->draftComments;
$rev_phid = queryfx_one(
$conn_r,
'SELECT phid FROM %T WHERE id = %d',
id(new DifferentialRevision())->getTableName(),
$rev_id);
if (!$rev_phid) {
throw new PhabricatorEmptyQueryException();
}
$rev_phid = $rev_phid['phid'];
$where[] = qsprintf(
$conn_r,
'authorPHID = %s AND revisionPHID = %s AND transactionPHID IS NULL
AND isDeleted = 0',
$phid,
$rev_phid);
}
if ($this->draftsByAuthors) {
$where[] = qsprintf(
$conn_r,
'authorPHID IN (%Ls) AND isDeleted = 0 AND transactionPHID IS NULL',
$this->draftsByAuthors);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/differential/query/DifferentialRevisionQuery.php b/src/applications/differential/query/DifferentialRevisionQuery.php
index 13399bd7cc..63b5256454 100644
--- a/src/applications/differential/query/DifferentialRevisionQuery.php
+++ b/src/applications/differential/query/DifferentialRevisionQuery.php
@@ -1,1164 +1,1164 @@
<?php
/**
* Flexible query API for Differential revisions. Example:
*
* // Load open revisions
* $revisions = id(new DifferentialRevisionQuery())
* ->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
* ->execute();
*
* @task config Query Configuration
* @task exec Query Execution
* @task internal Internals
*/
final class DifferentialRevisionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $pathIDs = array();
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
const STATUS_ACCEPTED = 'status-accepted';
const STATUS_NEEDS_REVIEW = 'status-needs-review';
const STATUS_NEEDS_REVISION = 'status-needs-revision';
const STATUS_CLOSED = 'status-closed';
const STATUS_ABANDONED = 'status-abandoned';
private $authors = array();
private $draftAuthors = array();
private $ccs = array();
private $reviewers = array();
private $revIDs = array();
private $commitHashes = array();
private $commitPHIDs = array();
private $phids = array();
private $responsibles = array();
private $branches = array();
private $arcanistProjectPHIDs = array();
private $repositoryPHIDs;
private $updatedEpochMin;
private $updatedEpochMax;
const ORDER_MODIFIED = 'order-modified';
const ORDER_CREATED = 'order-created';
private $needRelationships = false;
private $needActiveDiffs = false;
private $needDiffIDs = false;
private $needCommitPHIDs = false;
private $needHashes = false;
private $needReviewerStatus = false;
private $needReviewerAuthority;
private $needDrafts;
private $needFlags;
private $buildingGlobalOrder;
/* -( Query Configuration )------------------------------------------------ */
/**
* Filter results to revisions which affect a Diffusion path ID in a given
* repository. You can call this multiple times to select revisions for
* several paths.
*
* @param int Diffusion repository ID.
* @param int Diffusion path ID.
* @return this
* @task config
*/
public function withPath($repository_id, $path_id) {
$this->pathIDs[] = array(
'repositoryID' => $repository_id,
'pathID' => $path_id,
);
return $this;
}
/**
* Filter results to revisions authored by one of the given PHIDs. Calling
* this function will clear anything set by previous calls to
* @{method:withAuthors}.
*
* @param array List of PHIDs of authors
* @return this
* @task config
*/
public function withAuthors(array $author_phids) {
$this->authors = $author_phids;
return $this;
}
/**
* Filter results to revisions with comments authored by the given PHIDs.
*
* @param array List of PHIDs of authors
* @return this
* @task config
*/
public function withDraftRepliesByAuthors(array $author_phids) {
$this->draftAuthors = $author_phids;
return $this;
}
/**
* Filter results to revisions which CC one of the listed people. Calling this
* function will clear anything set by previous calls to @{method:withCCs}.
*
* @param array List of PHIDs of subscribers.
* @return this
* @task config
*/
public function withCCs(array $cc_phids) {
$this->ccs = $cc_phids;
return $this;
}
/**
* Filter results to revisions that have one of the provided PHIDs as
* reviewers. Calling this function will clear anything set by previous calls
* to @{method:withReviewers}.
*
* @param array List of PHIDs of reviewers
* @return this
* @task config
*/
public function withReviewers(array $reviewer_phids) {
$this->reviewers = $reviewer_phids;
return $this;
}
/**
* Filter results to revisions that have one of the provided commit hashes.
* Calling this function will clear anything set by previous calls to
* @{method:withCommitHashes}.
*
* @param array List of pairs <Class
* ArcanistDifferentialRevisionHash::HASH_$type constant,
* hash>
* @return this
* @task config
*/
public function withCommitHashes(array $commit_hashes) {
$this->commitHashes = $commit_hashes;
return $this;
}
/**
* Filter results to revisions that have one of the provided PHIDs as
* commits. Calling this function will clear anything set by previous calls
* to @{method:withCommitPHIDs}.
*
* @param array List of PHIDs of commits
* @return this
* @task config
*/
public function withCommitPHIDs(array $commit_phids) {
$this->commitPHIDs = $commit_phids;
return $this;
}
/**
* Filter results to revisions with a given status. Provide a class constant,
* such as `DifferentialRevisionQuery::STATUS_OPEN`.
*
* @param const Class STATUS constant, like STATUS_OPEN.
* @return this
* @task config
*/
public function withStatus($status_constant) {
$this->status = $status_constant;
return $this;
}
/**
* Filter results to revisions on given branches.
*
* @param list List of branch names.
* @return this
* @task config
*/
public function withBranches(array $branches) {
$this->branches = $branches;
return $this;
}
/**
* Filter results to only return revisions whose ids are in the given set.
*
* @param array List of revision ids
* @return this
* @task config
*/
public function withIDs(array $ids) {
$this->revIDs = $ids;
return $this;
}
/**
* Filter results to only return revisions whose PHIDs are in the given set.
*
* @param array List of revision PHIDs
* @return this
* @task config
*/
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
/**
* Given a set of users, filter results to return only revisions they are
* responsible for (i.e., they are either authors or reviewers).
*
* @param array List of user PHIDs.
* @return this
* @task config
*/
public function withResponsibleUsers(array $responsible_phids) {
$this->responsibles = $responsible_phids;
return $this;
}
/**
* Filter results to only return revisions with a given set of arcanist
* projects.
*
* @param array List of project PHIDs.
* @return this
* @task config
*/
public function withArcanistProjectPHIDs(array $arc_project_phids) {
$this->arcanistProjectPHIDs = $arc_project_phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
public function withUpdatedEpochBetween($min, $max) {
$this->updatedEpochMin = $min;
$this->updatedEpochMax = $max;
return $this;
}
/**
* Set result ordering. Provide a class constant, such as
* `DifferentialRevisionQuery::ORDER_CREATED`.
*
* @task config
*/
public function setOrder($order_constant) {
switch ($order_constant) {
case self::ORDER_CREATED:
$this->setOrderVector(array('id'));
break;
case self::ORDER_MODIFIED:
$this->setOrderVector(array('updated', 'id'));
break;
default:
throw new Exception(pht('Unknown order "%s".', $order_constant));
}
return $this;
}
/**
* Set whether or not the query will load and attach relationships.
*
* @param bool True to load and attach relationships.
* @return this
* @task config
*/
public function needRelationships($need_relationships) {
$this->needRelationships = $need_relationships;
return $this;
}
/**
* Set whether or not the query should load the active diff for each
* revision.
*
* @param bool True to load and attach diffs.
* @return this
* @task config
*/
public function needActiveDiffs($need_active_diffs) {
$this->needActiveDiffs = $need_active_diffs;
return $this;
}
/**
* Set whether or not the query should load the associated commit PHIDs for
* each revision.
*
* @param bool True to load and attach diffs.
* @return this
* @task config
*/
public function needCommitPHIDs($need_commit_phids) {
$this->needCommitPHIDs = $need_commit_phids;
return $this;
}
/**
* Set whether or not the query should load associated diff IDs for each
* revision.
*
* @param bool True to load and attach diff IDs.
* @return this
* @task config
*/
public function needDiffIDs($need_diff_ids) {
$this->needDiffIDs = $need_diff_ids;
return $this;
}
/**
* Set whether or not the query should load associated commit hashes for each
* revision.
*
* @param bool True to load and attach commit hashes.
* @return this
* @task config
*/
public function needHashes($need_hashes) {
$this->needHashes = $need_hashes;
return $this;
}
/**
* Set whether or not the query should load associated reviewer status.
*
* @param bool True to load and attach reviewers.
* @return this
* @task config
*/
public function needReviewerStatus($need_reviewer_status) {
$this->needReviewerStatus = $need_reviewer_status;
return $this;
}
/**
* Request information about the viewer's authority to act on behalf of each
* reviewer. In particular, they have authority to act on behalf of projects
* they are a member of.
*
* @param bool True to load and attach authority.
* @return this
* @task config
*/
public function needReviewerAuthority($need_reviewer_authority) {
$this->needReviewerAuthority = $need_reviewer_authority;
return $this;
}
public function needFlags($need_flags) {
$this->needFlags = $need_flags;
return $this;
}
public function needDrafts($need_drafts) {
$this->needDrafts = $need_drafts;
return $this;
}
/* -( Query Execution )---------------------------------------------------- */
/**
* Execute the query as configured, returning matching
* @{class:DifferentialRevision} objects.
*
* @return list List of matching DifferentialRevision objects.
* @task exec
*/
protected function loadPage() {
$table = new DifferentialRevision();
$conn_r = $table->establishConnection('r');
$data = $this->loadData();
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $revisions) {
$viewer = $this->getViewer();
$repository_phids = mpull($revisions, 'getRepositoryPHID');
$repository_phids = array_filter($repository_phids);
$repositories = array();
if ($repository_phids) {
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
}
// If a revision is associated with a repository:
//
// - the viewer must be able to see the repository; or
// - the viewer must have an automatic view capability.
//
// In the latter case, we'll load the revision but not load the repository.
$can_view = PhabricatorPolicyCapability::CAN_VIEW;
foreach ($revisions as $key => $revision) {
$repo_phid = $revision->getRepositoryPHID();
if (!$repo_phid) {
// The revision has no associated repository. Attach `null` and move on.
$revision->attachRepository(null);
continue;
}
$repository = idx($repositories, $repo_phid);
if ($repository) {
// The revision has an associated repository, and the viewer can see
// it. Attach it and move on.
$revision->attachRepository($repository);
continue;
}
if ($revision->hasAutomaticCapability($can_view, $viewer)) {
// The revision has an associated repository which the viewer can not
// see, but the viewer has an automatic capability on this revision.
// Load the revision without attaching a repository.
$revision->attachRepository(null);
continue;
}
if ($this->getViewer()->isOmnipotent()) {
// The viewer is omnipotent. Allow the revision to load even without
// a repository.
$revision->attachRepository(null);
continue;
}
// The revision has an associated repository, and the viewer can't see
// it, and the viewer has no special capabilities. Filter out this
// revision.
$this->didRejectResult($revision);
unset($revisions[$key]);
}
if (!$revisions) {
return array();
}
$table = new DifferentialRevision();
$conn_r = $table->establishConnection('r');
if ($this->needRelationships) {
$this->loadRelationships($conn_r, $revisions);
}
if ($this->needCommitPHIDs) {
$this->loadCommitPHIDs($conn_r, $revisions);
}
$need_active = $this->needActiveDiffs;
$need_ids = $need_active || $this->needDiffIDs;
if ($need_ids) {
$this->loadDiffIDs($conn_r, $revisions);
}
if ($need_active) {
$this->loadActiveDiffs($conn_r, $revisions);
}
if ($this->needHashes) {
$this->loadHashes($conn_r, $revisions);
}
if ($this->needReviewerStatus || $this->needReviewerAuthority) {
$this->loadReviewers($conn_r, $revisions);
}
return $revisions;
}
protected function didFilterPage(array $revisions) {
$viewer = $this->getViewer();
if ($this->needFlags) {
$flags = id(new PhabricatorFlagQuery())
->setViewer($viewer)
->withOwnerPHIDs(array($viewer->getPHID()))
->withObjectPHIDs(mpull($revisions, 'getPHID'))
->execute();
$flags = mpull($flags, null, 'getObjectPHID');
foreach ($revisions as $revision) {
$revision->attachFlag(
$viewer,
idx($flags, $revision->getPHID()));
}
}
if ($this->needDrafts) {
$drafts = id(new DifferentialDraft())->loadAllWhere(
'authorPHID = %s AND objectPHID IN (%Ls)',
$viewer->getPHID(),
mpull($revisions, 'getPHID'));
$drafts = mgroup($drafts, 'getObjectPHID');
foreach ($revisions as $revision) {
$revision->attachDrafts(
$viewer,
idx($drafts, $revision->getPHID(), array()));
}
}
return $revisions;
}
private function loadData() {
$table = new DifferentialRevision();
$conn_r = $table->establishConnection('r');
$selects = array();
// NOTE: If the query includes "responsiblePHIDs", we execute it as a
// UNION of revisions they own and revisions they're reviewing. This has
// much better performance than doing it with JOIN/WHERE.
if ($this->responsibles) {
$basic_authors = $this->authors;
$basic_reviewers = $this->reviewers;
$authority_projects = id(new PhabricatorProjectQuery())
->setViewer($this->getViewer())
->withMemberPHIDs($this->responsibles)
->execute();
$authority_phids = mpull($authority_projects, 'getPHID');
try {
// Build the query where the responsible users are authors.
$this->authors = array_merge($basic_authors, $this->responsibles);
$this->reviewers = $basic_reviewers;
$selects[] = $this->buildSelectStatement($conn_r);
// Build the query where the responsible users are reviewers, or
// projects they are members of are reviewers.
$this->authors = $basic_authors;
$this->reviewers = array_merge(
$basic_reviewers,
$this->responsibles,
$authority_phids);
$selects[] = $this->buildSelectStatement($conn_r);
// Put everything back like it was.
$this->authors = $basic_authors;
$this->reviewers = $basic_reviewers;
} catch (Exception $ex) {
$this->authors = $basic_authors;
$this->reviewers = $basic_reviewers;
throw $ex;
}
} else {
$selects[] = $this->buildSelectStatement($conn_r);
}
if (count($selects) > 1) {
$this->buildingGlobalOrder = true;
$query = qsprintf(
$conn_r,
'%Q %Q %Q',
implode(' UNION DISTINCT ', $selects),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
} else {
$query = head($selects);
}
return queryfx_all($conn_r, '%Q', $query);
}
private function buildSelectStatement(AphrontDatabaseConnection $conn_r) {
$table = new DifferentialRevision();
$select = qsprintf(
$conn_r,
'SELECT r.* FROM %T r',
$table->getTableName());
$joins = $this->buildJoinsClause($conn_r);
$where = $this->buildWhereClause($conn_r);
$group_by = $this->buildGroupByClause($conn_r);
$this->buildingGlobalOrder = false;
$order_by = $this->buildOrderClause($conn_r);
$limit = $this->buildLimitClause($conn_r);
return qsprintf(
$conn_r,
'(%Q %Q %Q %Q %Q %Q)',
$select,
$joins,
$where,
$group_by,
$order_by,
$limit);
}
/* -( Internals )---------------------------------------------------------- */
/**
* @task internal
*/
private function buildJoinsClause($conn_r) {
$joins = array();
if ($this->pathIDs) {
$path_table = new DifferentialAffectedPath();
$joins[] = qsprintf(
$conn_r,
'JOIN %T p ON p.revisionID = r.id',
$path_table->getTableName());
}
if ($this->commitHashes) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T hash_rel ON hash_rel.revisionID = r.id',
ArcanistDifferentialRevisionHash::TABLE_NAME);
}
if ($this->ccs) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T e_ccs ON e_ccs.src = r.phid '.
'AND e_ccs.type = %s '.
'AND e_ccs.dst in (%Ls)',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
PhabricatorObjectHasSubscriberEdgeType::EDGECONST,
$this->ccs);
}
if ($this->reviewers) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T e_reviewers ON e_reviewers.src = r.phid '.
'AND e_reviewers.type = %s '.
'AND e_reviewers.dst in (%Ls)',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
DifferentialRevisionHasReviewerEdgeType::EDGECONST,
$this->reviewers);
}
if ($this->draftAuthors) {
$differential_draft = new DifferentialDraft();
$joins[] = qsprintf(
$conn_r,
'JOIN %T has_draft ON has_draft.objectPHID = r.phid '.
'AND has_draft.authorPHID IN (%Ls)',
$differential_draft->getTableName(),
$this->draftAuthors);
}
if ($this->commitPHIDs) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T commits ON commits.revisionID = r.id',
DifferentialRevision::TABLE_COMMIT);
}
$joins = implode(' ', $joins);
return $joins;
}
/**
* @task internal
*/
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->pathIDs) {
$path_clauses = array();
$repo_info = igroup($this->pathIDs, 'repositoryID');
foreach ($repo_info as $repository_id => $paths) {
$path_clauses[] = qsprintf(
$conn_r,
'(p.repositoryID = %d AND p.pathID IN (%Ld))',
$repository_id,
ipull($paths, 'pathID'));
}
$path_clauses = '('.implode(' OR ', $path_clauses).')';
$where[] = $path_clauses;
}
if ($this->authors) {
$where[] = qsprintf(
$conn_r,
'r.authorPHID IN (%Ls)',
$this->authors);
}
if ($this->revIDs) {
$where[] = qsprintf(
$conn_r,
'r.id IN (%Ld)',
$this->revIDs);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
'r.repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->commitHashes) {
$hash_clauses = array();
foreach ($this->commitHashes as $info) {
list($type, $hash) = $info;
$hash_clauses[] = qsprintf(
$conn_r,
'(hash_rel.type = %s AND hash_rel.hash = %s)',
$type,
$hash);
}
$hash_clauses = '('.implode(' OR ', $hash_clauses).')';
$where[] = $hash_clauses;
}
if ($this->commitPHIDs) {
$where[] = qsprintf(
$conn_r,
'commits.commitPHID IN (%Ls)',
$this->commitPHIDs);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'r.phid IN (%Ls)',
$this->phids);
}
if ($this->branches) {
$where[] = qsprintf(
$conn_r,
'r.branchName in (%Ls)',
$this->branches);
}
if ($this->arcanistProjectPHIDs) {
$where[] = qsprintf(
$conn_r,
'r.arcanistProjectPHID in (%Ls)',
$this->arcanistProjectPHIDs);
}
if ($this->updatedEpochMin !== null) {
$where[] = qsprintf(
$conn_r,
'r.dateModified >= %d',
$this->updatedEpochMin);
}
if ($this->updatedEpochMax !== null) {
$where[] = qsprintf(
$conn_r,
'r.dateModified <= %d',
$this->updatedEpochMax);
}
switch ($this->status) {
case self::STATUS_ANY:
break;
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
DifferentialRevisionStatus::getOpenStatuses());
break;
case self::STATUS_NEEDS_REVIEW:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
array(
ArcanistDifferentialRevisionStatus::NEEDS_REVIEW,
));
break;
case self::STATUS_NEEDS_REVISION:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
array(
ArcanistDifferentialRevisionStatus::NEEDS_REVISION,
));
break;
case self::STATUS_ACCEPTED:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
array(
ArcanistDifferentialRevisionStatus::ACCEPTED,
));
break;
case self::STATUS_CLOSED:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
DifferentialRevisionStatus::getClosedStatuses());
break;
case self::STATUS_ABANDONED:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
array(
ArcanistDifferentialRevisionStatus::ABANDONED,
));
break;
default:
throw new Exception(
"Unknown revision status filter constant '{$this->status}'!");
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
/**
* @task internal
*/
private function buildGroupByClause($conn_r) {
$join_triggers = array_merge(
$this->pathIDs,
$this->ccs,
$this->reviewers);
$needs_distinct = (count($join_triggers) > 1);
if ($needs_distinct) {
return 'GROUP BY r.id';
} else {
return '';
}
}
protected function getDefaultOrderVector() {
return array('updated', 'id');
}
public function getOrderableColumns() {
$primary = ($this->buildingGlobalOrder ? null : 'r');
return array(
'id' => array(
'table' => $primary,
'column' => 'id',
'type' => 'int',
'unique' => true,
),
'updated' => array(
'table' => $primary,
'column' => 'dateModified',
'type' => 'int',
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
$revision = $this->loadCursorObject($cursor);
return array(
'id' => $revision->getID(),
'updated' => $revision->getDateModified(),
);
}
private function loadRelationships($conn_r, array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$type_reviewer = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
$type_subscriber = PhabricatorObjectHasSubscriberEdgeType::EDGECONST;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($revisions, 'getPHID'))
->withEdgeTypes(array($type_reviewer, $type_subscriber))
->setOrder(PhabricatorEdgeQuery::ORDER_OLDEST_FIRST)
->execute();
$type_map = array(
DifferentialRevision::RELATION_REVIEWER => $type_reviewer,
DifferentialRevision::RELATION_SUBSCRIBED => $type_subscriber,
);
foreach ($revisions as $revision) {
$data = array();
foreach ($type_map as $rel_type => $edge_type) {
$revision_edges = $edges[$revision->getPHID()][$edge_type];
foreach ($revision_edges as $dst_phid => $edge_data) {
$data[] = array(
'relation' => $rel_type,
'objectPHID' => $dst_phid,
'reasonPHID' => null,
);
}
}
$revision->attachRelationships($data);
}
}
private function loadCommitPHIDs($conn_r, array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$commit_phids = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE revisionID IN (%Ld)',
DifferentialRevision::TABLE_COMMIT,
mpull($revisions, 'getID'));
$commit_phids = igroup($commit_phids, 'revisionID');
foreach ($revisions as $revision) {
$phids = idx($commit_phids, $revision->getID(), array());
$phids = ipull($phids, 'commitPHID');
$revision->attachCommitPHIDs($phids);
}
}
private function loadDiffIDs($conn_r, array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$diff_table = new DifferentialDiff();
$diff_ids = queryfx_all(
$conn_r,
'SELECT revisionID, id FROM %T WHERE revisionID IN (%Ld)
ORDER BY id DESC',
$diff_table->getTableName(),
mpull($revisions, 'getID'));
$diff_ids = igroup($diff_ids, 'revisionID');
foreach ($revisions as $revision) {
$ids = idx($diff_ids, $revision->getID(), array());
$ids = ipull($ids, 'id');
$revision->attachDiffIDs($ids);
}
}
private function loadActiveDiffs($conn_r, array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$diff_table = new DifferentialDiff();
$load_ids = array();
foreach ($revisions as $revision) {
$diffs = $revision->getDiffIDs();
if ($diffs) {
$load_ids[] = max($diffs);
}
}
$active_diffs = array();
if ($load_ids) {
$active_diffs = $diff_table->loadAllWhere(
'id IN (%Ld)',
$load_ids);
}
$active_diffs = mpull($active_diffs, null, 'getRevisionID');
foreach ($revisions as $revision) {
$revision->attachActiveDiff(idx($active_diffs, $revision->getID()));
}
}
private function loadHashes(
AphrontDatabaseConnection $conn_r,
array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE revisionID IN (%Ld)',
'differential_revisionhash',
mpull($revisions, 'getID'));
$data = igroup($data, 'revisionID');
foreach ($revisions as $revision) {
$hashes = idx($data, $revision->getID(), array());
$list = array();
foreach ($hashes as $hash) {
$list[] = array($hash['type'], $hash['hash']);
}
$revision->attachHashes($list);
}
}
private function loadReviewers(
AphrontDatabaseConnection $conn_r,
array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($revisions, 'getPHID'))
->withEdgeTypes(array($edge_type))
->needEdgeData(true)
->setOrder(PhabricatorEdgeQuery::ORDER_OLDEST_FIRST)
->execute();
$viewer = $this->getViewer();
$viewer_phid = $viewer->getPHID();
$allow_key = 'differential.allow-self-accept';
$allow_self = PhabricatorEnv::getEnvConfig($allow_key);
// Figure out which of these reviewers the viewer has authority to act as.
if ($this->needReviewerAuthority && $viewer_phid) {
$authority = $this->loadReviewerAuthority(
$revisions,
$edges,
$allow_self);
}
foreach ($revisions as $revision) {
$revision_edges = $edges[$revision->getPHID()][$edge_type];
$reviewers = array();
foreach ($revision_edges as $reviewer_phid => $edge) {
$reviewer = new DifferentialReviewer($reviewer_phid, $edge['data']);
if ($this->needReviewerAuthority) {
if (!$viewer_phid) {
// Logged-out users never have authority.
$has_authority = false;
} else if ((!$allow_self) &&
($revision->getAuthorPHID() == $viewer_phid)) {
// The author can never have authority unless we allow self-accept.
$has_authority = false;
} else {
// Otherwise, look up whether th viewer has authority.
$has_authority = isset($authority[$reviewer_phid]);
}
$reviewer->attachAuthority($viewer, $has_authority);
}
$reviewers[$reviewer_phid] = $reviewer;
}
$revision->attachReviewerStatus($reviewers);
}
}
public static function splitResponsible(array $revisions, array $user_phids) {
$blocking = array();
$active = array();
$waiting = array();
$status_review = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW;
// Bucket revisions into $blocking (revisions where you are blocking
// others), $active (revisions you need to do something about) and $waiting
// (revisions you're waiting on someone else to do something about).
foreach ($revisions as $revision) {
$needs_review = ($revision->getStatus() == $status_review);
$filter_is_author = in_array($revision->getAuthorPHID(), $user_phids);
if (!$revision->getReviewers()) {
$needs_review = false;
$author_is_reviewer = false;
} else {
$author_is_reviewer = in_array(
$revision->getAuthorPHID(),
$revision->getReviewers());
}
// If exactly one of "needs review" and "the user is the author" is
// true, the user needs to act on it. Otherwise, they're waiting on
// it.
if ($needs_review ^ $filter_is_author) {
if ($needs_review) {
array_unshift($blocking, $revision);
} else {
$active[] = $revision;
}
// User is author **and** reviewer. An exotic but configurable workflow.
// User needs to act on it double.
} else if ($needs_review && $author_is_reviewer) {
array_unshift($blocking, $revision);
$active[] = $revision;
} else {
$waiting[] = $revision;
}
}
return array($blocking, $active, $waiting);
}
private function loadReviewerAuthority(
array $revisions,
array $edges,
$allow_self) {
$revision_map = mpull($revisions, null, 'getPHID');
$viewer_phid = $this->getViewer()->getPHID();
// Find all the project reviewers which the user may have authority over.
$project_phids = array();
$project_type = PhabricatorProjectProjectPHIDType::TYPECONST;
$edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
foreach ($edges as $src => $types) {
if (!$allow_self) {
if ($revision_map[$src]->getAuthorPHID() == $viewer_phid) {
// If self-review isn't permitted, the user will never have
// authority over projects on revisions they authored because you
// can't accept your own revisions, so we don't need to load any
// data about these reviewers.
continue;
}
}
$edge_data = idx($types, $edge_type, array());
foreach ($edge_data as $dst => $data) {
if (phid_get_type($dst) == $project_type) {
$project_phids[] = $dst;
}
}
}
// Now, figure out which of these projects the viewer is actually a
// member of.
$project_authority = array();
if ($project_phids) {
$project_authority = id(new PhabricatorProjectQuery())
->setViewer($this->getViewer())
->withPHIDs($project_phids)
->withMemberPHIDs(array($viewer_phid))
->execute();
$project_authority = mpull($project_authority, 'getPHID');
}
// Finally, the viewer has authority over themselves.
return array(
$viewer_phid => true,
) + array_fuse($project_authority);
}
public function getQueryApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
}
diff --git a/src/applications/diffusion/query/DiffusionCommitQuery.php b/src/applications/diffusion/query/DiffusionCommitQuery.php
index 22331e8510..8fd9d0c73e 100644
--- a/src/applications/diffusion/query/DiffusionCommitQuery.php
+++ b/src/applications/diffusion/query/DiffusionCommitQuery.php
@@ -1,566 +1,566 @@
<?php
final class DiffusionCommitQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $defaultRepository;
private $identifiers;
private $repositoryIDs;
private $repositoryPHIDs;
private $identifierMap;
private $needAuditRequests;
private $auditIDs;
private $auditorPHIDs;
private $auditAwaitingUser;
private $auditStatus;
const AUDIT_STATUS_ANY = 'audit-status-any';
const AUDIT_STATUS_OPEN = 'audit-status-open';
const AUDIT_STATUS_CONCERN = 'audit-status-concern';
const AUDIT_STATUS_ACCEPTED = 'audit-status-accepted';
const AUDIT_STATUS_PARTIAL = 'audit-status-partial';
private $needCommitData;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
/**
* Load commits by partial or full identifiers, e.g. "rXab82393", "rX1234",
* or "a9caf12". When an identifier matches multiple commits, they will all
* be returned; callers should be prepared to deal with more results than
* they queried for.
*/
public function withIdentifiers(array $identifiers) {
$this->identifiers = $identifiers;
return $this;
}
/**
* Look up commits in a specific repository. This is a shorthand for calling
* @{method:withDefaultRepository} and @{method:withRepositoryIDs}.
*/
public function withRepository(PhabricatorRepository $repository) {
$this->withDefaultRepository($repository);
$this->withRepositoryIDs(array($repository->getID()));
return $this;
}
/**
* Look up commits in a specific repository. Prefer
* @{method:withRepositoryIDs}; the underyling table is keyed by ID such
* that this method requires a separate initial query to map PHID to ID.
*/
public function withRepositoryPHIDs(array $phids) {
$this->repositoryPHIDs = $phids;
}
/**
* If a default repository is provided, ambiguous commit identifiers will
* be assumed to belong to the default repository.
*
* For example, "r123" appearing in a commit message in repository X is
* likely to be unambiguously "rX123". Normally the reference would be
* considered ambiguous, but if you provide a default repository it will
* be correctly resolved.
*/
public function withDefaultRepository(PhabricatorRepository $repository) {
$this->defaultRepository = $repository;
return $this;
}
public function withRepositoryIDs(array $repository_ids) {
$this->repositoryIDs = $repository_ids;
return $this;
}
public function needCommitData($need) {
$this->needCommitData = $need;
return $this;
}
public function needAuditRequests($need) {
$this->needAuditRequests = $need;
return $this;
}
/**
* Returns true if we should join the audit table, either because we're
* interested in the information if it's available or because matching rows
* must always have it.
*/
private function shouldJoinAudits() {
return $this->auditStatus ||
$this->rowsMustHaveAudits();
}
/**
* Return true if we should `JOIN` (vs `LEFT JOIN`) the audit table, because
* matching commits will always have audit rows.
*/
private function rowsMustHaveAudits() {
return
$this->auditIDs ||
$this->auditorPHIDs ||
$this->auditAwaitingUser;
}
public function withAuditIDs(array $ids) {
$this->auditIDs = $ids;
return $this;
}
public function withAuditorPHIDs(array $auditor_phids) {
$this->auditorPHIDs = $auditor_phids;
return $this;
}
public function withAuditAwaitingUser(PhabricatorUser $user) {
$this->auditAwaitingUser = $user;
return $this;
}
public function withAuditStatus($status) {
$this->auditStatus = $status;
return $this;
}
public function getIdentifierMap() {
if ($this->identifierMap === null) {
throw new Exception(
'You must execute() the query before accessing the identifier map.');
}
return $this->identifierMap;
}
protected function getPrimaryTableAlias() {
return 'commit';
}
protected function willExecute() {
if ($this->identifierMap === null) {
$this->identifierMap = array();
}
}
protected function loadPage() {
$table = new PhabricatorRepositoryCommit();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT commit.* FROM %T commit %Q %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $commits) {
$repository_ids = mpull($commits, 'getRepositoryID', 'getRepositoryID');
$repos = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIDs($repository_ids)
->execute();
$min_qualified = PhabricatorRepository::MINIMUM_QUALIFIED_HASH;
$result = array();
foreach ($commits as $key => $commit) {
$repo = idx($repos, $commit->getRepositoryID());
if ($repo) {
$commit->attachRepository($repo);
} else {
unset($commits[$key]);
continue;
}
// Build the identifierMap
if ($this->identifiers !== null) {
$ids = array_fuse($this->identifiers);
$prefixes = array(
'r'.$commit->getRepository()->getCallsign(),
'r'.$commit->getRepository()->getCallsign().':',
'R'.$commit->getRepository()->getID().':',
'', // No prefix is valid too and will only match the commitIdentifier
);
$suffix = $commit->getCommitIdentifier();
if ($commit->getRepository()->isSVN()) {
foreach ($prefixes as $prefix) {
if (isset($ids[$prefix.$suffix])) {
$result[$prefix.$suffix][] = $commit;
}
}
} else {
// This awkward construction is so we can link the commits up in O(N)
// time instead of O(N^2).
for ($ii = $min_qualified; $ii <= strlen($suffix); $ii++) {
$part = substr($suffix, 0, $ii);
foreach ($prefixes as $prefix) {
if (isset($ids[$prefix.$part])) {
$result[$prefix.$part][] = $commit;
}
}
}
}
}
}
if ($result) {
foreach ($result as $identifier => $matching_commits) {
if (count($matching_commits) == 1) {
$result[$identifier] = head($matching_commits);
} else {
// This reference is ambiguous (it matches more than one commit) so
// don't link it.
unset($result[$identifier]);
}
}
$this->identifierMap += $result;
}
return $commits;
}
protected function didFilterPage(array $commits) {
if ($this->needCommitData) {
$data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
'commitID in (%Ld)',
mpull($commits, 'getID'));
$data = mpull($data, null, 'getCommitID');
foreach ($commits as $commit) {
$commit_data = idx($data, $commit->getID());
if (!$commit_data) {
$commit_data = new PhabricatorRepositoryCommitData();
}
$commit->attachCommitData($commit_data);
}
}
// TODO: This should just be `needAuditRequests`, not `shouldJoinAudits()`,
// but leave that for a future diff.
if ($this->needAuditRequests || $this->shouldJoinAudits()) {
$requests = id(new PhabricatorRepositoryAuditRequest())->loadAllWhere(
'commitPHID IN (%Ls)',
mpull($commits, 'getPHID'));
$requests = mgroup($requests, 'getCommitPHID');
foreach ($commits as $commit) {
$audit_requests = idx($requests, $commit->getPHID(), array());
$commit->attachAudits($audit_requests);
foreach ($audit_requests as $audit_request) {
$audit_request->attachCommit($commit);
}
}
}
return $commits;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->repositoryPHIDs !== null) {
$map_repositories = id (new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($this->repositoryPHIDs)
->execute();
if (!$map_repositories) {
throw new PhabricatorEmptyQueryException();
}
$repository_ids = mpull($map_repositories, 'getID');
if ($this->repositoryIDs !== null) {
$repository_ids = array_merge($repository_ids, $this->repositoryIDs);
}
$this->withRepositoryIDs($repository_ids);
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'commit.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'commit.phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryIDs !== null) {
$where[] = qsprintf(
$conn_r,
'commit.repositoryID IN (%Ld)',
$this->repositoryIDs);
}
if ($this->authorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'commit.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->identifiers !== null) {
$min_unqualified = PhabricatorRepository::MINIMUM_UNQUALIFIED_HASH;
$min_qualified = PhabricatorRepository::MINIMUM_QUALIFIED_HASH;
$refs = array();
$bare = array();
foreach ($this->identifiers as $identifier) {
$matches = null;
preg_match('/^(?:[rR]([A-Z]+:?|[0-9]+:))?(.*)$/',
$identifier, $matches);
$repo = nonempty(rtrim($matches[1], ':'), null);
$commit_identifier = nonempty($matches[2], null);
if ($repo === null) {
if ($this->defaultRepository) {
$repo = $this->defaultRepository->getCallsign();
}
}
if ($repo === null) {
if (strlen($commit_identifier) < $min_unqualified) {
continue;
}
$bare[] = $commit_identifier;
} else {
$refs[] = array(
'callsign' => $repo,
'identifier' => $commit_identifier,
);
}
}
$sql = array();
foreach ($bare as $identifier) {
$sql[] = qsprintf(
$conn_r,
'(commit.commitIdentifier LIKE %> AND '.
'LENGTH(commit.commitIdentifier) = 40)',
$identifier);
}
if ($refs) {
$callsigns = ipull($refs, 'callsign');
$repos = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIdentifiers($callsigns);
$repos->execute();
$repos = $repos->getIdentifierMap();
foreach ($refs as $key => $ref) {
$repo = idx($repos, $ref['callsign']);
if (!$repo) {
continue;
}
if ($repo->isSVN()) {
if (!ctype_digit($ref['identifier'])) {
continue;
}
$sql[] = qsprintf(
$conn_r,
'(commit.repositoryID = %d AND commit.commitIdentifier = %s)',
$repo->getID(),
// NOTE: Because the 'commitIdentifier' column is a string, MySQL
// ignores the index if we hand it an integer. Hand it a string.
// See T3377.
(int)$ref['identifier']);
} else {
if (strlen($ref['identifier']) < $min_qualified) {
continue;
}
$sql[] = qsprintf(
$conn_r,
'(commit.repositoryID = %d AND commit.commitIdentifier LIKE %>)',
$repo->getID(),
$ref['identifier']);
}
}
}
if (!$sql) {
// If we discarded all possible identifiers (e.g., they all referenced
// bogus repositories or were all too short), make sure the query finds
// nothing.
throw new PhabricatorEmptyQueryException(
pht('No commit identifiers.'));
}
$where[] = '('.implode(' OR ', $sql).')';
}
if ($this->auditIDs !== null) {
$where[] = qsprintf(
$conn_r,
'audit.id IN (%Ld)',
$this->auditIDs);
}
if ($this->auditorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'audit.auditorPHID IN (%Ls)',
$this->auditorPHIDs);
}
if ($this->auditAwaitingUser) {
$awaiting_user_phid = $this->auditAwaitingUser->getPHID();
// Exclude package and project audits associated with commits where
// the user is the author.
$where[] = qsprintf(
$conn_r,
'(commit.authorPHID IS NULL OR commit.authorPHID != %s)
OR (audit.auditorPHID = %s)',
$awaiting_user_phid,
$awaiting_user_phid);
}
$status = $this->auditStatus;
if ($status !== null) {
switch ($status) {
case self::AUDIT_STATUS_PARTIAL:
$where[] = qsprintf(
$conn_r,
'commit.auditStatus = %d',
PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED);
break;
case self::AUDIT_STATUS_ACCEPTED:
$where[] = qsprintf(
$conn_r,
'commit.auditStatus = %d',
PhabricatorAuditCommitStatusConstants::FULLY_AUDITED);
break;
case self::AUDIT_STATUS_CONCERN:
$where[] = qsprintf(
$conn_r,
'audit.auditStatus = %s',
PhabricatorAuditStatusConstants::CONCERNED);
break;
case self::AUDIT_STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'audit.auditStatus in (%Ls)',
PhabricatorAuditStatusConstants::getOpenStatusConstants());
if ($this->auditAwaitingUser) {
$where[] = qsprintf(
$conn_r,
'awaiting.auditStatus IS NULL OR awaiting.auditStatus != %s',
PhabricatorAuditStatusConstants::RESIGNED);
}
break;
case self::AUDIT_STATUS_ANY:
break;
default:
$valid = array(
self::AUDIT_STATUS_ANY,
self::AUDIT_STATUS_OPEN,
self::AUDIT_STATUS_CONCERN,
self::AUDIT_STATUS_ACCEPTED,
self::AUDIT_STATUS_PARTIAL,
);
throw new Exception(
"Unknown audit status '{$status}'! Valid statuses are: ".
implode(', ', $valid));
}
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function didFilterResults(array $filtered) {
if ($this->identifierMap) {
foreach ($this->identifierMap as $name => $commit) {
if (isset($filtered[$commit->getPHID()])) {
unset($this->identifierMap[$name]);
}
}
}
}
private function buildJoinClause($conn_r) {
$joins = array();
$audit_request = new PhabricatorRepositoryAuditRequest();
if ($this->shouldJoinAudits()) {
$joins[] = qsprintf(
$conn_r,
'%Q %T audit ON commit.phid = audit.commitPHID',
($this->rowsMustHaveAudits() ? 'JOIN' : 'LEFT JOIN'),
$audit_request->getTableName());
}
if ($this->auditAwaitingUser) {
// Join the request table on the awaiting user's requests, so we can
// filter out package and project requests which the user has resigned
// from.
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T awaiting ON audit.commitPHID = awaiting.commitPHID AND
awaiting.auditorPHID = %s',
$audit_request->getTableName(),
$this->auditAwaitingUser->getPHID());
}
if ($joins) {
return implode(' ', $joins);
} else {
return '';
}
}
private function buildGroupClause(AphrontDatabaseConnection $conn_r) {
$should_group = $this->shouldJoinAudits();
// TODO: Currently, the audit table is missing a unique key, so we may
// require a GROUP BY if we perform this join. See T1768. This can be
// removed once the table has the key.
if ($this->auditAwaitingUser) {
$should_group = true;
}
if ($should_group) {
return 'GROUP BY commit.id';
} else {
return '';
}
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/diffusion/query/DiffusionLintCountQuery.php b/src/applications/diffusion/query/DiffusionLintCountQuery.php
index 89fca4cded..f85505af76 100644
--- a/src/applications/diffusion/query/DiffusionLintCountQuery.php
+++ b/src/applications/diffusion/query/DiffusionLintCountQuery.php
@@ -1,120 +1,123 @@
<?php
final class DiffusionLintCountQuery extends PhabricatorQuery {
private $branchIDs;
private $paths;
private $codes;
public function withBranchIDs(array $branch_ids) {
$this->branchIDs = $branch_ids;
return $this;
}
public function withPaths(array $paths) {
$this->paths = $paths;
return $this;
}
public function withCodes(array $codes) {
$this->codes = $codes;
return $this;
}
public function execute() {
if (!$this->paths) {
throw new Exception(pht('Call withPaths() before execute()!'));
}
if (!$this->branchIDs) {
throw new Exception(pht('Call withBranchIDs() before execute()!'));
}
$conn_r = id(new PhabricatorRepositoryCommit())->establishConnection('r');
$this->paths = array_unique($this->paths);
list($dirs, $paths) = $this->processPaths();
$parts = array();
foreach ($dirs as $dir) {
$parts[$dir] = qsprintf(
$conn_r,
'path LIKE %>',
$dir);
}
foreach ($paths as $path) {
$parts[$path] = qsprintf(
$conn_r,
'path = %s',
$path);
}
$queries = array();
foreach ($parts as $key => $part) {
$queries[] = qsprintf(
$conn_r,
'SELECT %s path_prefix, COUNT(*) N FROM %T %Q',
$key,
PhabricatorRepository::TABLE_LINTMESSAGE,
- $this->buildWhereClause($conn_r, $part));
+ $this->buildCustomWhereClause($conn_r, $part));
}
$huge_union_query = '('.implode(') UNION ALL (', $queries).')';
$data = queryfx_all(
$conn_r,
'%Q',
$huge_union_query);
return $this->processResults($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r, $part) {
+ protected function buildCustomWhereClause(
+ AphrontDatabaseConnection $conn_r,
+ $part) {
+
$where = array();
$where[] = $part;
if ($this->codes !== null) {
$where[] = qsprintf(
$conn_r,
'code IN (%Ls)',
$this->codes);
}
if ($this->branchIDs !== null) {
$where[] = qsprintf(
$conn_r,
'branchID IN (%Ld)',
$this->branchIDs);
}
return $this->formatWhereClause($where);
}
private function processPaths() {
$dirs = array();
$paths = array();
foreach ($this->paths as $path) {
$path = '/'.$path;
if (substr($path, -1) == '/') {
$dirs[] = $path;
} else {
$paths[] = $path;
}
}
return array($dirs, $paths);
}
private function processResults(array $data) {
$data = ipull($data, 'N', 'path_prefix');
// Strip the leading "/" back off each path.
$output = array();
foreach ($data as $path => $count) {
$output[substr($path, 1)] = $count;
}
return $output;
}
}
diff --git a/src/applications/diffusion/query/DiffusionPathQuery.php b/src/applications/diffusion/query/DiffusionPathQuery.php
index 33e7b57909..f442da7173 100644
--- a/src/applications/diffusion/query/DiffusionPathQuery.php
+++ b/src/applications/diffusion/query/DiffusionPathQuery.php
@@ -1,43 +1,43 @@
<?php
final class DiffusionPathQuery {
private $pathIDs;
public function withPathIDs(array $path_ids) {
$this->pathIDs = $path_ids;
return $this;
}
public function execute() {
$conn_r = id(new PhabricatorRepository())->establishConnection('r');
$where = $this->buildWhereClause($conn_r);
$results = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q',
PhabricatorRepository::TABLE_PATH,
$where);
return ipull($results, null, 'id');
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->pathIDs) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->pathIDs);
}
if ($where) {
return 'WHERE ('.implode(') AND (', $where).')';
} else {
return '';
}
}
}
diff --git a/src/applications/diffusion/query/DiffusionSymbolQuery.php b/src/applications/diffusion/query/DiffusionSymbolQuery.php
index e5cb2b91c4..053f4a222e 100644
--- a/src/applications/diffusion/query/DiffusionSymbolQuery.php
+++ b/src/applications/diffusion/query/DiffusionSymbolQuery.php
@@ -1,299 +1,299 @@
<?php
/**
* Query symbol information (class and function names and location), returning
* a list of matching @{class:PhabricatorRepositorySymbol} objects and possibly
* attached data.
*
* @task config Configuring the Query
* @task exec Executing the Query
* @task internal Internals
*/
final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery {
private $viewer;
private $context;
private $namePrefix;
private $name;
private $projectIDs;
private $language;
private $type;
private $needPaths;
private $needArcanistProject;
private $needRepositories;
/* -( Configuring the Query )---------------------------------------------- */
/**
* @task config
*/
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
/**
* @task config
*/
public function getViewer() {
return $this->viewer;
}
/**
* @task config
*/
public function setContext($context) {
$this->context = $context;
return $this;
}
/**
* @task config
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* @task config
*/
public function setNamePrefix($name_prefix) {
$this->namePrefix = $name_prefix;
return $this;
}
/**
* @task config
*/
public function setProjectIDs(array $project_ids) {
$this->projectIDs = $project_ids;
return $this;
}
/**
* @task config
*/
public function setLanguage($language) {
$this->language = $language;
return $this;
}
/**
* @task config
*/
public function setType($type) {
$this->type = $type;
return $this;
}
/**
* @task config
*/
public function needPaths($need_paths) {
$this->needPaths = $need_paths;
return $this;
}
/**
* @task config
*/
public function needArcanistProjects($need_arcanist_projects) {
$this->needArcanistProjects = $need_arcanist_projects;
return $this;
}
/**
* @task config
*/
public function needRepositories($need_repositories) {
$this->needRepositories = $need_repositories;
return $this;
}
/* -( Executing the Query )------------------------------------------------ */
/**
* @task exec
*/
public function execute() {
if ($this->name && $this->namePrefix) {
throw new Exception(
'You can not set both a name and a name prefix!');
} else if (!$this->name && !$this->namePrefix) {
throw new Exception(
'You must set a name or a name prefix!');
}
$symbol = new PhabricatorRepositorySymbol();
$conn_r = $symbol->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$symbol->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$symbols = $symbol->loadAllFromArray($data);
if ($symbols) {
if ($this->needPaths) {
$this->loadPaths($symbols);
}
if ($this->needArcanistProjects || $this->needRepositories) {
$this->loadArcanistProjects($symbols);
}
if ($this->needRepositories) {
$this->loadRepositories($symbols);
}
}
return $symbols;
}
/* -( Internals )---------------------------------------------------------- */
/**
* @task internal
*/
private function buildOrderClause($conn_r) {
return qsprintf(
$conn_r,
'ORDER BY symbolName ASC');
}
/**
* @task internal
*/
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if (isset($this->context)) {
$where[] = qsprintf(
$conn_r,
'symbolContext = %s',
$this->context);
}
if ($this->name) {
$where[] = qsprintf(
$conn_r,
'symbolName = %s',
$this->name);
}
if ($this->namePrefix) {
$where[] = qsprintf(
$conn_r,
'symbolName LIKE %>',
$this->namePrefix);
}
if ($this->projectIDs) {
$where[] = qsprintf(
$conn_r,
'arcanistProjectID IN (%Ld)',
$this->projectIDs);
}
if ($this->language) {
$where[] = qsprintf(
$conn_r,
'symbolLanguage = %s',
$this->language);
}
if ($this->type) {
$where[] = qsprintf(
$conn_r,
'symbolType = %s',
$this->type);
}
return $this->formatWhereClause($where);
}
/**
* @task internal
*/
private function loadPaths(array $symbols) {
assert_instances_of($symbols, 'PhabricatorRepositorySymbol');
$path_map = queryfx_all(
id(new PhabricatorRepository())->establishConnection('r'),
'SELECT * FROM %T WHERE id IN (%Ld)',
PhabricatorRepository::TABLE_PATH,
mpull($symbols, 'getPathID'));
$path_map = ipull($path_map, 'path', 'id');
foreach ($symbols as $symbol) {
$symbol->attachPath(idx($path_map, $symbol->getPathID()));
}
}
/**
* @task internal
*/
private function loadArcanistProjects(array $symbols) {
assert_instances_of($symbols, 'PhabricatorRepositorySymbol');
$projects = id(new PhabricatorRepositoryArcanistProject())->loadAllWhere(
'id IN (%Ld)',
mpull($symbols, 'getArcanistProjectID'));
foreach ($symbols as $symbol) {
$project = idx($projects, $symbol->getArcanistProjectID());
$symbol->attachArcanistProject($project);
}
}
/**
* @task internal
*/
private function loadRepositories(array $symbols) {
assert_instances_of($symbols, 'PhabricatorRepositorySymbol');
$projects = mpull($symbols, 'getArcanistProject');
$projects = array_filter($projects);
$repo_ids = mpull($projects, 'getRepositoryID');
$repo_ids = array_filter($repo_ids);
if ($repo_ids) {
$repos = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIDs($repo_ids)
->execute();
} else {
$repos = array();
}
foreach ($symbols as $symbol) {
$proj = $symbol->getArcanistProject();
if ($proj) {
$symbol->attachRepository(idx($repos, $proj->getRepositoryID()));
} else {
$symbol->attachRepository(null);
}
}
}
}
diff --git a/src/applications/diviner/query/DivinerAtomQuery.php b/src/applications/diviner/query/DivinerAtomQuery.php
index 5b9b8814f7..70759a2cc1 100644
--- a/src/applications/diviner/query/DivinerAtomQuery.php
+++ b/src/applications/diviner/query/DivinerAtomQuery.php
@@ -1,447 +1,447 @@
<?php
final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $bookPHIDs;
private $names;
private $types;
private $contexts;
private $indexes;
private $includeUndocumentable;
private $includeGhosts;
private $nodeHashes;
private $titles;
private $nameContains;
private $needAtoms;
private $needExtends;
private $needChildren;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBookPHIDs(array $phids) {
$this->bookPHIDs = $phids;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function withContexts(array $contexts) {
$this->contexts = $contexts;
return $this;
}
public function withIndexes(array $indexes) {
$this->indexes = $indexes;
return $this;
}
public function withNodeHashes(array $hashes) {
$this->nodeHashes = $hashes;
return $this;
}
public function withTitles($titles) {
$this->titles = $titles;
return $this;
}
public function withNameContains($text) {
$this->nameContains = $text;
return $this;
}
public function needAtoms($need) {
$this->needAtoms = $need;
return $this;
}
public function needChildren($need) {
$this->needChildren = $need;
return $this;
}
/**
* Include "ghosts", which are symbols which used to exist but do not exist
* currently (for example, a function which existed in an older version of
* the codebase but was deleted).
*
* These symbols had PHIDs assigned to them, and may have other sorts of
* metadata that we don't want to lose (like comments or flags), so we don't
* delete them outright. They might also come back in the future: the change
* which deleted the symbol might be reverted, or the documentation might
* have been generated incorrectly by accident. In these cases, we can
* restore the original data.
*
* However, most callers are not interested in these symbols, so they are
* excluded by default. You can use this method to include them in results.
*
* @param bool True to include ghosts.
* @return this
*/
public function withIncludeGhosts($include) {
$this->includeGhosts = $include;
return $this;
}
public function needExtends($need) {
$this->needExtends = $need;
return $this;
}
public function withIncludeUndocumentable($include) {
$this->includeUndocumentable = $include;
return $this;
}
protected function loadPage() {
$table = new DivinerLiveSymbol();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $atoms) {
$books = array_unique(mpull($atoms, 'getBookPHID'));
$books = id(new DivinerBookQuery())
->setViewer($this->getViewer())
->withPHIDs($books)
->execute();
$books = mpull($books, null, 'getPHID');
foreach ($atoms as $key => $atom) {
$book = idx($books, $atom->getBookPHID());
if (!$book) {
unset($atoms[$key]);
continue;
}
$atom->attachBook($book);
}
if ($this->needAtoms) {
$atom_data = id(new DivinerLiveAtom())->loadAllWhere(
'symbolPHID IN (%Ls)',
mpull($atoms, 'getPHID'));
$atom_data = mpull($atom_data, null, 'getSymbolPHID');
foreach ($atoms as $key => $atom) {
$data = idx($atom_data, $atom->getPHID());
if (!$data) {
unset($atoms[$key]);
continue;
}
$atom->attachAtom($data);
}
}
// Load all of the symbols this symbol extends, recursively. Commonly,
// this means all the ancestor classes and interfaces it extends and
// implements.
if ($this->needExtends) {
// First, load all the matching symbols by name. This does 99% of the
// work in most cases, assuming things are named at all reasonably.
$names = array();
foreach ($atoms as $atom) {
foreach ($atom->getAtom()->getExtends() as $xref) {
$names[] = $xref->getName();
}
}
if ($names) {
$xatoms = id(new DivinerAtomQuery())
->setViewer($this->getViewer())
->withNames($names)
->needExtends(true)
->needAtoms(true)
->needChildren($this->needChildren)
->execute();
$xatoms = mgroup($xatoms, 'getName', 'getType', 'getBookPHID');
} else {
$xatoms = array();
}
foreach ($atoms as $atom) {
$alang = $atom->getAtom()->getLanguage();
$extends = array();
foreach ($atom->getAtom()->getExtends() as $xref) {
// If there are no symbols of the matching name and type, we can't
// resolve this.
if (empty($xatoms[$xref->getName()][$xref->getType()])) {
continue;
}
// If we found matches in the same documentation book, prefer them
// over other matches. Otherwise, look at all the the matches.
$matches = $xatoms[$xref->getName()][$xref->getType()];
if (isset($matches[$atom->getBookPHID()])) {
$maybe = $matches[$atom->getBookPHID()];
} else {
$maybe = array_mergev($matches);
}
if (!$maybe) {
continue;
}
// Filter out matches in a different language, since, e.g., PHP
// classes can not implement JS classes.
$same_lang = array();
foreach ($maybe as $xatom) {
if ($xatom->getAtom()->getLanguage() == $alang) {
$same_lang[] = $xatom;
}
}
if (!$same_lang) {
continue;
}
// If we have duplicates remaining, just pick the first one. There's
// nothing more we can do to figure out which is the real one.
$extends[] = head($same_lang);
}
$atom->attachExtends($extends);
}
}
if ($this->needChildren) {
$child_hashes = $this->getAllChildHashes($atoms, $this->needExtends);
if ($child_hashes) {
$children = id(new DivinerAtomQuery())
->setViewer($this->getViewer())
->withIncludeUndocumentable(true)
->withNodeHashes($child_hashes)
->needAtoms($this->needAtoms)
->execute();
$children = mpull($children, null, 'getNodeHash');
} else {
$children = array();
}
$this->attachAllChildren($atoms, $children, $this->needExtends);
}
return $atoms;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->bookPHIDs) {
$where[] = qsprintf(
$conn_r,
'bookPHID IN (%Ls)',
$this->bookPHIDs);
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'type IN (%Ls)',
$this->types);
}
if ($this->names) {
$where[] = qsprintf(
$conn_r,
'name IN (%Ls)',
$this->names);
}
if ($this->titles) {
$hashes = array();
foreach ($this->titles as $title) {
$slug = DivinerAtomRef::normalizeTitleString($title);
$hash = PhabricatorHash::digestForIndex($slug);
$hashes[] = $hash;
}
$where[] = qsprintf(
$conn_r,
'titleSlugHash in (%Ls)',
$hashes);
}
if ($this->contexts) {
$with_null = false;
$contexts = $this->contexts;
foreach ($contexts as $key => $value) {
if ($value === null) {
unset($contexts[$key]);
$with_null = true;
continue;
}
}
if ($contexts && $with_null) {
$where[] = qsprintf(
$conn_r,
'context IN (%Ls) OR context IS NULL',
$contexts);
} else if ($contexts) {
$where[] = qsprintf(
$conn_r,
'context IN (%Ls)',
$contexts);
} else if ($with_null) {
$where[] = qsprintf(
$conn_r,
'context IS NULL');
}
}
if ($this->indexes) {
$where[] = qsprintf(
$conn_r,
'atomIndex IN (%Ld)',
$this->indexes);
}
if (!$this->includeUndocumentable) {
$where[] = qsprintf(
$conn_r,
'isDocumentable = 1');
}
if (!$this->includeGhosts) {
$where[] = qsprintf(
$conn_r,
'graphHash IS NOT NULL');
}
if ($this->nodeHashes) {
$where[] = qsprintf(
$conn_r,
'nodeHash IN (%Ls)',
$this->nodeHashes);
}
if ($this->nameContains) {
// NOTE: This CONVERT() call makes queries case-insensitive, since the
// column has binary collation. Eventually, this should move into
// fulltext.
$where[] = qsprintf(
$conn_r,
'CONVERT(name USING utf8) LIKE %~',
$this->nameContains);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
/**
* Walk a list of atoms and collect all the node hashes of the atoms'
* children. When recursing, also walk up the tree and collect children of
* atoms they extend.
*
* @param list<DivinerLiveSymbol> List of symbols to collect child hashes of.
* @param bool True to collect children of extended atoms,
* as well.
* @return map<string, string> Hashes of atoms' children.
*/
private function getAllChildHashes(array $symbols, $recurse_up) {
assert_instances_of($symbols, 'DivinerLiveSymbol');
$hashes = array();
foreach ($symbols as $symbol) {
foreach ($symbol->getAtom()->getChildHashes() as $hash) {
$hashes[$hash] = $hash;
}
if ($recurse_up) {
$hashes += $this->getAllChildHashes($symbol->getExtends(), true);
}
}
return $hashes;
}
/**
* Attach child atoms to existing atoms. In recursive mode, also attach child
* atoms to atoms that these atoms extend.
*
* @param list<DivinerLiveSymbol> List of symbols to attach children to.
* @param map<string, DivinerLiveSymbol> Map of symbols, keyed by node hash.
* @param bool True to attach children to extended atoms, as well.
* @return void
*/
private function attachAllChildren(
array $symbols,
array $children,
$recurse_up) {
assert_instances_of($symbols, 'DivinerLiveSymbol');
assert_instances_of($children, 'DivinerLiveSymbol');
foreach ($symbols as $symbol) {
$symbol_children = array();
foreach ($symbol->getAtom()->getChildHashes() as $hash) {
if (isset($children[$hash])) {
$symbol_children[] = $children[$hash];
}
}
$symbol->attachChildren($symbol_children);
if ($recurse_up) {
$this->attachAllChildren($symbol->getExtends(), $children, true);
}
}
}
public function getQueryApplicationClass() {
return 'PhabricatorDivinerApplication';
}
}
diff --git a/src/applications/diviner/query/DivinerBookQuery.php b/src/applications/diviner/query/DivinerBookQuery.php
index 31e6f336a9..90fed52a23 100644
--- a/src/applications/diviner/query/DivinerBookQuery.php
+++ b/src/applications/diviner/query/DivinerBookQuery.php
@@ -1,72 +1,72 @@
<?php
final class DivinerBookQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $names;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
protected function loadPage() {
$table = new DivinerLiveBook();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->names) {
$where[] = qsprintf(
$conn_r,
'name IN (%Ls)',
$this->names);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDivinerApplication';
}
}
diff --git a/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php b/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php
index 75ace905da..770678a687 100644
--- a/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php
+++ b/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php
@@ -1,59 +1,59 @@
<?php
final class DoorkeeperExternalObjectQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
protected $phids;
protected $objectKeys;
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withObjectKeys(array $keys) {
$this->objectKeys = $keys;
return $this;
}
protected function loadPage() {
$table = new DoorkeeperExternalObject();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->objectKeys) {
$where[] = qsprintf(
$conn_r,
'objectKey IN (%Ls)',
$this->objectKeys);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDoorkeeperApplication';
}
}
diff --git a/src/applications/drydock/query/DrydockBlueprintQuery.php b/src/applications/drydock/query/DrydockBlueprintQuery.php
index 4afdb582c2..b698855bcf 100644
--- a/src/applications/drydock/query/DrydockBlueprintQuery.php
+++ b/src/applications/drydock/query/DrydockBlueprintQuery.php
@@ -1,65 +1,65 @@
<?php
final class DrydockBlueprintQuery extends DrydockQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new DrydockBlueprint();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT blueprint.* FROM %T blueprint %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$blueprints = $table->loadAllFromArray($data);
$implementations =
DrydockBlueprintImplementation::getAllBlueprintImplementations();
foreach ($blueprints as $blueprint) {
if (array_key_exists($blueprint->getClassName(), $implementations)) {
$blueprint->attachImplementation(
$implementations[$blueprint->getClassName()]);
}
}
return $blueprints;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/drydock/query/DrydockLeaseQuery.php b/src/applications/drydock/query/DrydockLeaseQuery.php
index 028351bdae..d5d62f950e 100644
--- a/src/applications/drydock/query/DrydockLeaseQuery.php
+++ b/src/applications/drydock/query/DrydockLeaseQuery.php
@@ -1,108 +1,108 @@
<?php
final class DrydockLeaseQuery extends DrydockQuery {
private $ids;
private $phids;
private $resourceIDs;
private $statuses;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withResourceIDs(array $ids) {
$this->resourceIDs = $ids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
protected function loadPage() {
$table = new DrydockLease();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT lease.* FROM %T lease %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $leases) {
$resource_ids = array_filter(mpull($leases, 'getResourceID'));
if ($resource_ids) {
$resources = id(new DrydockResourceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withIDs($resource_ids)
->execute();
} else {
$resources = array();
}
foreach ($leases as $key => $lease) {
$resource = null;
if ($lease->getResourceID()) {
$resource = idx($resources, $lease->getResourceID());
if (!$resource) {
unset($leases[$key]);
continue;
}
}
$lease->attachResource($resource);
}
return $leases;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->resourceIDs) {
$where[] = qsprintf(
$conn_r,
'resourceID IN (%Ld)',
$this->resourceIDs);
}
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->statuses) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ld)',
$this->statuses);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/drydock/query/DrydockLogQuery.php b/src/applications/drydock/query/DrydockLogQuery.php
index 83413d79c0..1e21864f10 100644
--- a/src/applications/drydock/query/DrydockLogQuery.php
+++ b/src/applications/drydock/query/DrydockLogQuery.php
@@ -1,113 +1,113 @@
<?php
final class DrydockLogQuery extends DrydockQuery {
private $resourceIDs;
private $leaseIDs;
public function withResourceIDs(array $ids) {
$this->resourceIDs = $ids;
return $this;
}
public function withLeaseIDs(array $ids) {
$this->leaseIDs = $ids;
return $this;
}
protected function loadPage() {
$table = new DrydockLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT log.* FROM %T log %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $logs) {
$resource_ids = array_filter(mpull($logs, 'getResourceID'));
if ($resource_ids) {
$resources = id(new DrydockResourceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withIDs($resource_ids)
->execute();
} else {
$resources = array();
}
foreach ($logs as $key => $log) {
$resource = null;
if ($log->getResourceID()) {
$resource = idx($resources, $log->getResourceID());
if (!$resource) {
unset($logs[$key]);
continue;
}
}
$log->attachResource($resource);
}
$lease_ids = array_filter(mpull($logs, 'getLeaseID'));
if ($lease_ids) {
$leases = id(new DrydockLeaseQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withIDs($lease_ids)
->execute();
} else {
$leases = array();
}
foreach ($logs as $key => $log) {
$lease = null;
if ($log->getLeaseID()) {
$lease = idx($leases, $log->getLeaseID());
if (!$lease) {
unset($logs[$key]);
continue;
}
}
$log->attachLease($lease);
}
// These logs are meaningless and their policies aren't computable. They
// shouldn't exist, but throw them away if they do.
foreach ($logs as $key => $log) {
if (!$log->getResource() && !$log->getLease()) {
unset($logs[$key]);
}
}
return $logs;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->resourceIDs) {
$where[] = qsprintf(
$conn_r,
'resourceID IN (%Ld)',
$this->resourceIDs);
}
if ($this->leaseIDs) {
$where[] = qsprintf(
$conn_r,
'leaseID IN (%Ld)',
$this->leaseIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/drydock/query/DrydockResourceQuery.php b/src/applications/drydock/query/DrydockResourceQuery.php
index 468af91db4..af84fefa4a 100644
--- a/src/applications/drydock/query/DrydockResourceQuery.php
+++ b/src/applications/drydock/query/DrydockResourceQuery.php
@@ -1,96 +1,96 @@
<?php
final class DrydockResourceQuery extends DrydockQuery {
private $ids;
private $phids;
private $statuses;
private $types;
private $blueprintPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function withBlueprintPHIDs(array $blueprint_phids) {
$this->blueprintPHIDs = $blueprint_phids;
return $this;
}
protected function loadPage() {
$table = new DrydockResource();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT resource.* FROM %T resource %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$resources = $table->loadAllFromArray($data);
return $resources;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'type IN (%Ls)',
$this->types);
}
if ($this->statuses) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ls)',
$this->statuses);
}
if ($this->blueprintPHIDs) {
$where[] = qsprintf(
$conn_r,
'blueprintPHID IN (%Ls)',
$this->blueprintPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/feed/query/PhabricatorFeedQuery.php b/src/applications/feed/query/PhabricatorFeedQuery.php
index 5f3efe5aaf..424658b342 100644
--- a/src/applications/feed/query/PhabricatorFeedQuery.php
+++ b/src/applications/feed/query/PhabricatorFeedQuery.php
@@ -1,126 +1,126 @@
<?php
final class PhabricatorFeedQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $filterPHIDs;
private $chronologicalKeys;
public function setFilterPHIDs(array $phids) {
$this->filterPHIDs = $phids;
return $this;
}
public function withChronologicalKeys(array $keys) {
$this->chronologicalKeys = $keys;
return $this;
}
protected function loadPage() {
$story_table = new PhabricatorFeedStoryData();
$conn = $story_table->establishConnection('r');
$data = queryfx_all(
$conn,
'SELECT story.* FROM %T story %Q %Q %Q %Q %Q',
$story_table->getTableName(),
$this->buildJoinClause($conn),
$this->buildWhereClause($conn),
$this->buildGroupClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $data;
}
protected function willFilterPage(array $data) {
return PhabricatorFeedStory::loadAllFromRows($data, $this->getViewer());
}
private function buildJoinClause(AphrontDatabaseConnection $conn_r) {
// NOTE: We perform this join unconditionally (even if we have no filter
// PHIDs) to omit rows which have no story references. These story data
// rows are notifications or realtime alerts.
$ref_table = new PhabricatorFeedStoryReference();
return qsprintf(
$conn_r,
'JOIN %T ref ON ref.chronologicalKey = story.chronologicalKey',
$ref_table->getTableName());
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->filterPHIDs) {
$where[] = qsprintf(
$conn_r,
'ref.objectPHID IN (%Ls)',
$this->filterPHIDs);
}
if ($this->chronologicalKeys) {
// NOTE: We want to use integers in the query so we can take advantage
// of keys, but can't use %d on 32-bit systems. Make sure all the keys
// are integers and then format them raw.
$keys = $this->chronologicalKeys;
foreach ($keys as $key) {
if (!ctype_digit($key)) {
throw new Exception("Key '{$key}' is not a valid chronological key!");
}
}
$where[] = qsprintf(
$conn_r,
'ref.chronologicalKey IN (%Q)',
implode(', ', $keys));
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function buildGroupClause(AphrontDatabaseConnection $conn_r) {
if ($this->filterPHIDs) {
return qsprintf($conn_r, 'GROUP BY ref.chronologicalKey');
} else {
return qsprintf($conn_r, 'GROUP BY story.chronologicalKey');
}
}
protected function getDefaultOrderVector() {
return array('key');
}
public function getOrderableColumns() {
$table = ($this->filterPHIDs ? 'ref' : 'story');
return array(
'key' => array(
'table' => $table,
'column' => 'chronologicalKey',
'type' => 'int',
'unique' => true,
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
return array(
'key' => $cursor,
);
}
protected function getResultCursor($item) {
if ($item instanceof PhabricatorFeedStory) {
return $item->getChronologicalKey();
}
return $item['chronologicalKey'];
}
public function getQueryApplicationClass() {
return 'PhabricatorFeedApplication';
}
}
diff --git a/src/applications/files/query/PhabricatorFileChunkQuery.php b/src/applications/files/query/PhabricatorFileChunkQuery.php
index 7c2a961fd0..b6fda13103 100644
--- a/src/applications/files/query/PhabricatorFileChunkQuery.php
+++ b/src/applications/files/query/PhabricatorFileChunkQuery.php
@@ -1,134 +1,134 @@
<?php
final class PhabricatorFileChunkQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $chunkHandles;
private $rangeStart;
private $rangeEnd;
private $isComplete;
private $needDataFiles;
public function withChunkHandles(array $handles) {
$this->chunkHandles = $handles;
return $this;
}
public function withByteRange($start, $end) {
$this->rangeStart = $start;
$this->rangeEnd = $end;
return $this;
}
public function withIsComplete($complete) {
$this->isComplete = $complete;
return $this;
}
public function needDataFiles($need) {
$this->needDataFiles = $need;
return $this;
}
protected function loadPage() {
$table = new PhabricatorFileChunk();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $chunks) {
if ($this->needDataFiles) {
$file_phids = mpull($chunks, 'getDataFilePHID');
$file_phids = array_filter($file_phids);
if ($file_phids) {
$files = id(new PhabricatorFileQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
} else {
$files = array();
}
foreach ($chunks as $key => $chunk) {
$data_phid = $chunk->getDataFilePHID();
if (!$data_phid) {
$chunk->attachDataFile(null);
continue;
}
$file = idx($files, $data_phid);
if (!$file) {
unset($chunks[$key]);
$this->didRejectResult($chunk);
continue;
}
$chunk->attachDataFile($file);
}
if (!$chunks) {
return $chunks;
}
}
return $chunks;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->chunkHandles !== null) {
$where[] = qsprintf(
$conn_r,
'chunkHandle IN (%Ls)',
$this->chunkHandles);
}
if ($this->rangeStart !== null) {
$where[] = qsprintf(
$conn_r,
'byteEnd > %d',
$this->rangeStart);
}
if ($this->rangeEnd !== null) {
$where[] = qsprintf(
$conn_r,
'byteStart < %d',
$this->rangeEnd);
}
if ($this->isComplete !== null) {
if ($this->isComplete) {
$where[] = qsprintf(
$conn_r,
'dataFilePHID IS NOT NULL');
} else {
$where[] = qsprintf(
$conn_r,
'dataFilePHID IS NULL');
}
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorFilesApplication';
}
}
diff --git a/src/applications/files/query/PhabricatorFileQuery.php b/src/applications/files/query/PhabricatorFileQuery.php
index ad0bbbac1b..a15be0c0bb 100644
--- a/src/applications/files/query/PhabricatorFileQuery.php
+++ b/src/applications/files/query/PhabricatorFileQuery.php
@@ -1,342 +1,342 @@
<?php
final class PhabricatorFileQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $explicitUploads;
private $transforms;
private $dateCreatedAfter;
private $dateCreatedBefore;
private $contentHashes;
private $minLength;
private $maxLength;
private $names;
private $isPartial;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
public function withDateCreatedBefore($date_created_before) {
$this->dateCreatedBefore = $date_created_before;
return $this;
}
public function withDateCreatedAfter($date_created_after) {
$this->dateCreatedAfter = $date_created_after;
return $this;
}
public function withContentHashes(array $content_hashes) {
$this->contentHashes = $content_hashes;
return $this;
}
/**
* Select files which are transformations of some other file. For example,
* you can use this query to find previously generated thumbnails of an image
* file.
*
* As a parameter, provide a list of transformation specifications. Each
* specification is a dictionary with the keys `originalPHID` and `transform`.
* The `originalPHID` is the PHID of the original file (the file which was
* transformed) and the `transform` is the name of the transform to query
* for. If you pass `true` as the `transform`, all transformations of the
* file will be selected.
*
* For example:
*
* array(
* array(
* 'originalPHID' => 'PHID-FILE-aaaa',
* 'transform' => 'sepia',
* ),
* array(
* 'originalPHID' => 'PHID-FILE-bbbb',
* 'transform' => true,
* ),
* )
*
* This selects the `"sepia"` transformation of the file with PHID
* `PHID-FILE-aaaa` and all transformations of the file with PHID
* `PHID-FILE-bbbb`.
*
* @param list<dict> List of transform specifications, described above.
* @return this
*/
public function withTransforms(array $specs) {
foreach ($specs as $spec) {
if (!is_array($spec) ||
empty($spec['originalPHID']) ||
empty($spec['transform'])) {
throw new Exception(
"Transform specification must be a dictionary with keys ".
"'originalPHID' and 'transform'!");
}
}
$this->transforms = $specs;
return $this;
}
public function withLengthBetween($min, $max) {
$this->minLength = $min;
$this->maxLength = $max;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function withIsPartial($partial) {
$this->isPartial = $partial;
return $this;
}
public function showOnlyExplicitUploads($explicit_uploads) {
$this->explicitUploads = $explicit_uploads;
return $this;
}
protected function loadPage() {
$table = new PhabricatorFile();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT f.* FROM %T f %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$files = $table->loadAllFromArray($data);
if (!$files) {
return $files;
}
// We need to load attached objects to perform policy checks for files.
// First, load the edges.
$edge_type = PhabricatorFileHasObjectEdgeType::EDGECONST;
$file_phids = mpull($files, 'getPHID');
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs($file_phids)
->withEdgeTypes(array($edge_type))
->execute();
$object_phids = array();
foreach ($files as $file) {
$phids = array_keys($edges[$file->getPHID()][$edge_type]);
$file->attachObjectPHIDs($phids);
foreach ($phids as $phid) {
$object_phids[$phid] = true;
}
}
// If this file is a transform of another file, load that file too. If you
// can see the original file, you can see the thumbnail.
// TODO: It might be nice to put this directly on PhabricatorFile and remove
// the PhabricatorTransformedFile table, which would be a little simpler.
$xforms = id(new PhabricatorTransformedFile())->loadAllWhere(
'transformedPHID IN (%Ls)',
$file_phids);
$xform_phids = mpull($xforms, 'getOriginalPHID', 'getTransformedPHID');
foreach ($xform_phids as $derived_phid => $original_phid) {
$object_phids[$original_phid] = true;
}
$object_phids = array_keys($object_phids);
// Now, load the objects.
$objects = array();
if ($object_phids) {
// NOTE: We're explicitly turning policy exceptions off, since the rule
// here is "you can see the file if you can see ANY associated object".
// Without this explicit flag, we'll incorrectly throw unless you can
// see ALL associated objects.
$objects = id(new PhabricatorObjectQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($object_phids)
->setRaisePolicyExceptions(false)
->execute();
$objects = mpull($objects, null, 'getPHID');
}
foreach ($files as $file) {
$file_objects = array_select_keys($objects, $file->getObjectPHIDs());
$file->attachObjects($file_objects);
}
foreach ($files as $key => $file) {
$original_phid = idx($xform_phids, $file->getPHID());
if ($original_phid == PhabricatorPHIDConstants::PHID_VOID) {
// This is a special case for builtin files, which are handled
// oddly.
$original = null;
} else if ($original_phid) {
$original = idx($objects, $original_phid);
if (!$original) {
// If the viewer can't see the original file, also prevent them from
// seeing the transformed file.
$this->didRejectResult($file);
unset($files[$key]);
continue;
}
} else {
$original = null;
}
$file->attachOriginalFile($original);
}
return $files;
}
private function buildJoinClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
if ($this->transforms) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T t ON t.transformedPHID = f.phid',
id(new PhabricatorTransformedFile())->getTableName());
}
return implode(' ', $joins);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'f.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'f.phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'f.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->explicitUploads !== null) {
$where[] = qsprintf(
$conn_r,
'f.isExplicitUpload = true');
}
if ($this->transforms !== null) {
$clauses = array();
foreach ($this->transforms as $transform) {
if ($transform['transform'] === true) {
$clauses[] = qsprintf(
$conn_r,
'(t.originalPHID = %s)',
$transform['originalPHID']);
} else {
$clauses[] = qsprintf(
$conn_r,
'(t.originalPHID = %s AND t.transform = %s)',
$transform['originalPHID'],
$transform['transform']);
}
}
$where[] = qsprintf($conn_r, '(%Q)', implode(') OR (', $clauses));
}
if ($this->dateCreatedAfter !== null) {
$where[] = qsprintf(
$conn_r,
'f.dateCreated >= %d',
$this->dateCreatedAfter);
}
if ($this->dateCreatedBefore !== null) {
$where[] = qsprintf(
$conn_r,
'f.dateCreated <= %d',
$this->dateCreatedBefore);
}
if ($this->contentHashes !== null) {
$where[] = qsprintf(
$conn_r,
'f.contentHash IN (%Ls)',
$this->contentHashes);
}
if ($this->minLength !== null) {
$where[] = qsprintf(
$conn_r,
'byteSize >= %d',
$this->minLength);
}
if ($this->maxLength !== null) {
$where[] = qsprintf(
$conn_r,
'byteSize <= %d',
$this->maxLength);
}
if ($this->names !== null) {
$where[] = qsprintf(
$conn_r,
'name in (%Ls)',
$this->names);
}
if ($this->isPartial !== null) {
$where[] = qsprintf(
$conn_r,
'isPartial = %d',
(int)$this->isPartial);
}
return $this->formatWhereClause($where);
}
protected function getPrimaryTableAlias() {
return 'f';
}
public function getQueryApplicationClass() {
return 'PhabricatorFilesApplication';
}
}
diff --git a/src/applications/flag/query/PhabricatorFlagQuery.php b/src/applications/flag/query/PhabricatorFlagQuery.php
index 910ed7dfa9..0b1902f6f1 100644
--- a/src/applications/flag/query/PhabricatorFlagQuery.php
+++ b/src/applications/flag/query/PhabricatorFlagQuery.php
@@ -1,165 +1,165 @@
<?php
final class PhabricatorFlagQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
const GROUP_COLOR = 'color';
const GROUP_NONE = 'none';
private $ownerPHIDs;
private $types;
private $objectPHIDs;
private $colors;
private $groupBy = self::GROUP_NONE;
private $needHandles;
private $needObjects;
public function withOwnerPHIDs(array $owner_phids) {
$this->ownerPHIDs = $owner_phids;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
public function withColors(array $colors) {
$this->colors = $colors;
return $this;
}
/**
* NOTE: this is done in PHP and not in MySQL, which means its inappropriate
* for large datasets. Pragmatically, this is fine for user flags which are
* typically well under 100 flags per user.
*/
public function setGroupBy($group) {
$this->groupBy = $group;
return $this;
}
public function needHandles($need) {
$this->needHandles = $need;
return $this;
}
public function needObjects($need) {
$this->needObjects = $need;
return $this;
}
public static function loadUserFlag(PhabricatorUser $user, $object_phid) {
// Specifying the type in the query allows us to use a key.
return id(new PhabricatorFlagQuery())
->setViewer($user)
->withOwnerPHIDs(array($user->getPHID()))
->withTypes(array(phid_get_type($object_phid)))
->withObjectPHIDs(array($object_phid))
->executeOne();
}
protected function loadPage() {
$table = new PhabricatorFlag();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T flag %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $flags) {
if ($this->needObjects) {
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($flags, 'getObjectPHID'))
->execute();
$objects = mpull($objects, null, 'getPHID');
foreach ($flags as $key => $flag) {
$object = idx($objects, $flag->getObjectPHID());
if ($object) {
$flags[$key]->attachObject($object);
} else {
unset($flags[$key]);
}
}
}
if ($this->needHandles) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($flags, 'getObjectPHID'))
->execute();
foreach ($flags as $flag) {
$flag->attachHandle($handles[$flag->getObjectPHID()]);
}
}
switch ($this->groupBy) {
case self::GROUP_COLOR:
$flags = msort($flags, 'getColor');
break;
case self::GROUP_NONE:
break;
default:
throw new Exception("Unknown groupBy parameter: $this->groupBy");
break;
}
return $flags;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ownerPHIDs) {
$where[] = qsprintf(
$conn_r,
'flag.ownerPHID IN (%Ls)',
$this->ownerPHIDs);
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'flag.type IN (%Ls)',
$this->types);
}
if ($this->objectPHIDs) {
$where[] = qsprintf(
$conn_r,
'flag.objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->colors) {
$where[] = qsprintf(
$conn_r,
'flag.color IN (%Ld)',
$this->colors);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorFlagsApplication';
}
}
diff --git a/src/applications/fund/query/FundBackerQuery.php b/src/applications/fund/query/FundBackerQuery.php
index 505de2bdf3..5f7406f5ad 100644
--- a/src/applications/fund/query/FundBackerQuery.php
+++ b/src/applications/fund/query/FundBackerQuery.php
@@ -1,118 +1,118 @@
<?php
final class FundBackerQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $statuses;
private $initiativePHIDs;
private $backerPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function withInitiativePHIDs(array $phids) {
$this->initiativePHIDs = $phids;
return $this;
}
public function withBackerPHIDs(array $phids) {
$this->backerPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new FundBacker();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $backers) {
$initiative_phids = mpull($backers, 'getInitiativePHID');
$initiatives = id(new PhabricatorObjectQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($initiative_phids)
->execute();
$initiatives = mpull($initiatives, null, 'getPHID');
foreach ($backers as $backer) {
$initiative_phid = $backer->getInitiativePHID();
$initiative = idx($initiatives, $initiative_phid);
$backer->attachInitiative($initiative);
}
return $backers;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->initiativePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'initiativePHID IN (%Ls)',
$this->initiativePHIDs);
}
if ($this->backerPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'backerPHID IN (%Ls)',
$this->backerPHIDs);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ls)',
$this->statuses);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorFundApplication';
}
}
diff --git a/src/applications/fund/query/FundInitiativeQuery.php b/src/applications/fund/query/FundInitiativeQuery.php
index 8fd910c046..66f87a883c 100644
--- a/src/applications/fund/query/FundInitiativeQuery.php
+++ b/src/applications/fund/query/FundInitiativeQuery.php
@@ -1,116 +1,116 @@
<?php
final class FundInitiativeQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $ownerPHIDs;
private $statuses;
private $needProjectPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withOwnerPHIDs(array $phids) {
$this->ownerPHIDs = $phids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function needProjectPHIDs($need) {
$this->needProjectPHIDs = $need;
return $this;
}
protected function loadPage() {
$table = new FundInitiative();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($rows);
}
protected function didFilterPage(array $initiatives) {
if ($this->needProjectPHIDs) {
$edge_query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($initiatives, 'getPHID'))
->withEdgeTypes(
array(
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
));
$edge_query->execute();
foreach ($initiatives as $initiative) {
$phids = $edge_query->getDestinationPHIDs(
array(
$initiative->getPHID(),
));
$initiative->attachProjectPHIDs($phids);
}
}
return $initiatives;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->ownerPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'ownerPHID IN (%Ls)',
$this->ownerPHIDs);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ls)',
$this->statuses);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorFundApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildArtifactQuery.php b/src/applications/harbormaster/query/HarbormasterBuildArtifactQuery.php
index 077e77a4bd..553780aa76 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildArtifactQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildArtifactQuery.php
@@ -1,124 +1,124 @@
<?php
final class HarbormasterBuildArtifactQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $buildTargetPHIDs;
private $artifactTypes;
private $artifactKeys;
private $keyBuildPHID;
private $keyBuildGeneration;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withBuildTargetPHIDs(array $build_target_phids) {
$this->buildTargetPHIDs = $build_target_phids;
return $this;
}
public function withArtifactTypes(array $artifact_types) {
$this->artifactTypes = $artifact_types;
return $this;
}
public function withArtifactKeys(
$build_phid,
$build_gen,
array $artifact_keys) {
$this->keyBuildPHID = $build_phid;
$this->keyBuildGeneration = $build_gen;
$this->artifactKeys = $artifact_keys;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuildArtifact();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $page) {
$build_targets = array();
$build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID'));
if ($build_target_phids) {
$build_targets = id(new HarbormasterBuildTargetQuery())
->setViewer($this->getViewer())
->withPHIDs($build_target_phids)
->setParentQuery($this)
->execute();
$build_targets = mpull($build_targets, null, 'getPHID');
}
foreach ($page as $key => $build_log) {
$build_target_phid = $build_log->getBuildTargetPHID();
if (empty($build_targets[$build_target_phid])) {
unset($page[$key]);
continue;
}
$build_log->attachBuildTarget($build_targets[$build_target_phid]);
}
return $page;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->buildTargetPHIDs) {
$where[] = qsprintf(
$conn_r,
'buildTargetPHID IN (%Ls)',
$this->buildTargetPHIDs);
}
if ($this->artifactTypes) {
$where[] = qsprintf(
$conn_r,
'artifactType in (%Ls)',
$this->artifactTypes);
}
if ($this->artifactKeys) {
$indexes = array();
foreach ($this->artifactKeys as $key) {
$indexes[] = PhabricatorHash::digestForIndex(
$this->keyBuildPHID.$this->keyBuildGeneration.$key);
}
$where[] = qsprintf(
$conn_r,
'artifactIndex IN (%Ls)',
$indexes);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildItemQuery.php b/src/applications/harbormaster/query/HarbormasterBuildItemQuery.php
index 2c82588940..1c54cf1fa7 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildItemQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildItemQuery.php
@@ -1,60 +1,60 @@
<?php
final class HarbormasterBuildItemQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuildItem();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid in (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildLogQuery.php b/src/applications/harbormaster/query/HarbormasterBuildLogQuery.php
index 461697a1e4..f0f2021fd8 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildLogQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildLogQuery.php
@@ -1,98 +1,98 @@
<?php
final class HarbormasterBuildLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $buildPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBuildTargetPHIDs(array $build_target_phids) {
$this->buildTargetPHIDs = $build_target_phids;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuildLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $page) {
$build_targets = array();
$build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID'));
if ($build_target_phids) {
$build_targets = id(new HarbormasterBuildTargetQuery())
->setViewer($this->getViewer())
->withPHIDs($build_target_phids)
->setParentQuery($this)
->execute();
$build_targets = mpull($build_targets, null, 'getPHID');
}
foreach ($page as $key => $build_log) {
$build_target_phid = $build_log->getBuildTargetPHID();
if (empty($build_targets[$build_target_phid])) {
unset($page[$key]);
continue;
}
$build_log->attachBuildTarget($build_targets[$build_target_phid]);
}
return $page;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->buildTargetPHIDs) {
$where[] = qsprintf(
$conn_r,
'buildTargetPHID IN (%Ls)',
$this->buildTargetPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildMessageQuery.php b/src/applications/harbormaster/query/HarbormasterBuildMessageQuery.php
index 816bafc1ad..749fdd76d4 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildMessageQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildMessageQuery.php
@@ -1,98 +1,98 @@
<?php
final class HarbormasterBuildMessageQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $buildTargetPHIDs;
private $consumed;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withBuildTargetPHIDs(array $phids) {
$this->buildTargetPHIDs = $phids;
return $this;
}
public function withConsumed($consumed) {
$this->consumed = $consumed;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuildMessage();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $page) {
$build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID'));
if ($build_target_phids) {
$build_targets = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($build_target_phids)
->setParentQuery($this)
->execute();
$build_targets = mpull($build_targets, null, 'getPHID');
} else {
$build_targets = array();
}
foreach ($page as $key => $message) {
$build_target_phid = $message->getBuildTargetPHID();
if (empty($build_targets[$build_target_phid])) {
unset($page[$key]);
continue;
}
$message->attachBuildTarget($build_targets[$build_target_phid]);
}
return $page;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->buildTargetPHIDs) {
$where[] = qsprintf(
$conn_r,
'buildTargetPHID IN (%Ls)',
$this->buildTargetPHIDs);
}
if ($this->consumed !== null) {
$where[] = qsprintf(
$conn_r,
'isConsumed = %d',
(int)$this->consumed);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildPlanQuery.php b/src/applications/harbormaster/query/HarbormasterBuildPlanQuery.php
index 8ea76ba36f..4123941665 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildPlanQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildPlanQuery.php
@@ -1,113 +1,113 @@
<?php
final class HarbormasterBuildPlanQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $statuses;
private $datasourceQuery;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function withDatasourceQuery($query) {
$this->datasourceQuery = $query;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuildPlan();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->statuses) {
$where[] = qsprintf(
$conn_r,
'planStatus IN (%Ls)',
$this->statuses);
}
if (strlen($this->datasourceQuery)) {
$where[] = qsprintf(
$conn_r,
'name LIKE %>',
$this->datasourceQuery);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
public function getOrderableColumns() {
return parent::getOrderableColumns() + array(
'name' => array(
'column' => 'name',
'type' => 'string',
'reverse' => true,
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
$plan = $this->loadCursorObject($cursor);
return array(
'id' => $plan->getID(),
'name' => $plan->getName(),
);
}
public function getBuiltinOrders() {
return array(
'name' => array(
'vector' => array('name', 'id'),
'name' => pht('Name'),
),
) + parent::getBuiltinOrders();
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildQuery.php b/src/applications/harbormaster/query/HarbormasterBuildQuery.php
index 0daf5ac906..d0b1e7420c 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildQuery.php
@@ -1,186 +1,186 @@
<?php
final class HarbormasterBuildQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $buildStatuses;
private $buildablePHIDs;
private $buildPlanPHIDs;
private $needBuildTargets;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBuildStatuses(array $build_statuses) {
$this->buildStatuses = $build_statuses;
return $this;
}
public function withBuildablePHIDs(array $buildable_phids) {
$this->buildablePHIDs = $buildable_phids;
return $this;
}
public function withBuildPlanPHIDs(array $build_plan_phids) {
$this->buildPlanPHIDs = $build_plan_phids;
return $this;
}
public function needBuildTargets($need_targets) {
$this->needBuildTargets = $need_targets;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuild();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $page) {
$buildables = array();
$buildable_phids = array_filter(mpull($page, 'getBuildablePHID'));
if ($buildable_phids) {
$buildables = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($buildable_phids)
->setParentQuery($this)
->execute();
$buildables = mpull($buildables, null, 'getPHID');
}
foreach ($page as $key => $build) {
$buildable_phid = $build->getBuildablePHID();
if (empty($buildables[$buildable_phid])) {
unset($page[$key]);
continue;
}
$build->attachBuildable($buildables[$buildable_phid]);
}
return $page;
}
protected function didFilterPage(array $page) {
$plans = array();
$plan_phids = array_filter(mpull($page, 'getBuildPlanPHID'));
if ($plan_phids) {
$plans = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($plan_phids)
->setParentQuery($this)
->execute();
$plans = mpull($plans, null, 'getPHID');
}
foreach ($page as $key => $build) {
$plan_phid = $build->getBuildPlanPHID();
$build->attachBuildPlan(idx($plans, $plan_phid));
}
$build_phids = mpull($page, 'getPHID');
$commands = id(new HarbormasterBuildCommand())->loadAllWhere(
'targetPHID IN (%Ls) ORDER BY id ASC',
$build_phids);
$commands = mgroup($commands, 'getTargetPHID');
foreach ($page as $build) {
$unprocessed_commands = idx($commands, $build->getPHID(), array());
$build->attachUnprocessedCommands($unprocessed_commands);
}
if ($this->needBuildTargets) {
$targets = id(new HarbormasterBuildTargetQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withBuildPHIDs($build_phids)
->execute();
// TODO: Some day, when targets have dependencies, we should toposort
// these. For now, just put them into chronological order.
$targets = array_reverse($targets);
$targets = mgroup($targets, 'getBuildPHID');
foreach ($page as $build) {
$build_targets = idx($targets, $build->getPHID(), array());
foreach ($build_targets as $phid => $target) {
if ($target->getBuildGeneration() !== $build->getBuildGeneration()) {
unset($build_targets[$phid]);
}
}
$build->attachBuildTargets($build_targets);
}
}
return $page;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid in (%Ls)',
$this->phids);
}
if ($this->buildStatuses !== null) {
$where[] = qsprintf(
$conn_r,
'buildStatus in (%Ls)',
$this->buildStatuses);
}
if ($this->buildablePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'buildablePHID IN (%Ls)',
$this->buildablePHIDs);
}
if ($this->buildPlanPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'buildPlanPHID IN (%Ls)',
$this->buildPlanPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildStepQuery.php b/src/applications/harbormaster/query/HarbormasterBuildStepQuery.php
index bea3ec10f0..c14185116c 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildStepQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildStepQuery.php
@@ -1,98 +1,98 @@
<?php
final class HarbormasterBuildStepQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $buildPlanPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBuildPlanPHIDs(array $phids) {
$this->buildPlanPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuildStep();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid in (%Ls)',
$this->phids);
}
if ($this->buildPlanPHIDs) {
$where[] = qsprintf(
$conn_r,
'buildPlanPHID in (%Ls)',
$this->buildPlanPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $page) {
$plans = array();
$buildplan_phids = array_filter(mpull($page, 'getBuildPlanPHID'));
if ($buildplan_phids) {
$plans = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($buildplan_phids)
->setParentQuery($this)
->execute();
$plans = mpull($plans, null, 'getPHID');
}
foreach ($page as $key => $build) {
$buildable_phid = $build->getBuildPlanPHID();
if (empty($plans[$buildable_phid])) {
unset($page[$key]);
continue;
}
$build->attachBuildPlan($plans[$buildable_phid]);
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php b/src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php
index 213a6a4a20..c61c0bd8b0 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php
@@ -1,142 +1,142 @@
<?php
final class HarbormasterBuildTargetQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $buildPHIDs;
private $buildGenerations;
private $needBuildSteps;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBuildPHIDs(array $build_phids) {
$this->buildPHIDs = $build_phids;
return $this;
}
public function withBuildGenerations(array $build_generations) {
$this->buildGenerations = $build_generations;
return $this;
}
public function needBuildSteps($need_build_steps) {
$this->needBuildSteps = $need_build_steps;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuildTarget();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid in (%Ls)',
$this->phids);
}
if ($this->buildPHIDs) {
$where[] = qsprintf(
$conn_r,
'buildPHID in (%Ls)',
$this->buildPHIDs);
}
if ($this->buildGenerations) {
$where[] = qsprintf(
$conn_r,
'buildGeneration in (%Ld)',
$this->buildGenerations);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function didFilterPage(array $page) {
if ($this->needBuildSteps) {
$step_phids = array();
foreach ($page as $target) {
$step_phids[] = $target->getBuildStepPHID();
}
$steps = id(new HarbormasterBuildStepQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($step_phids)
->execute();
$steps = mpull($steps, null, 'getPHID');
foreach ($page as $target) {
$target->attachBuildStep(
idx($steps, $target->getBuildStepPHID()));
}
}
return $page;
}
protected function willFilterPage(array $page) {
$builds = array();
$build_phids = array_filter(mpull($page, 'getBuildPHID'));
if ($build_phids) {
$builds = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($build_phids)
->setParentQuery($this)
->execute();
$builds = mpull($builds, null, 'getPHID');
}
foreach ($page as $key => $build_target) {
$build_phid = $build_target->getBuildPHID();
if (empty($builds[$build_phid])) {
unset($page[$key]);
continue;
}
$build_target->attachBuild($builds[$build_phid]);
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildableQuery.php b/src/applications/harbormaster/query/HarbormasterBuildableQuery.php
index 5b5972fa2f..1b1956a0c7 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildableQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildableQuery.php
@@ -1,222 +1,222 @@
<?php
final class HarbormasterBuildableQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $buildablePHIDs;
private $containerPHIDs;
private $manualBuildables;
private $needContainerObjects;
private $needContainerHandles;
private $needBuildableHandles;
private $needBuilds;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBuildablePHIDs(array $buildable_phids) {
$this->buildablePHIDs = $buildable_phids;
return $this;
}
public function withContainerPHIDs(array $container_phids) {
$this->containerPHIDs = $container_phids;
return $this;
}
public function withManualBuildables($manual) {
$this->manualBuildables = $manual;
return $this;
}
public function needContainerObjects($need) {
$this->needContainerObjects = $need;
return $this;
}
public function needContainerHandles($need) {
$this->needContainerHandles = $need;
return $this;
}
public function needBuildableHandles($need) {
$this->needBuildableHandles = $need;
return $this;
}
public function needBuilds($need) {
$this->needBuilds = $need;
return $this;
}
protected function loadPage() {
$table = new HarbormasterBuildable();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $page) {
$buildables = array();
$buildable_phids = array_filter(mpull($page, 'getBuildablePHID'));
if ($buildable_phids) {
$buildables = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($buildable_phids)
->setParentQuery($this)
->execute();
$buildables = mpull($buildables, null, 'getPHID');
}
foreach ($page as $key => $buildable) {
$buildable_phid = $buildable->getBuildablePHID();
if (empty($buildables[$buildable_phid])) {
unset($page[$key]);
continue;
}
$buildable->attachBuildableObject($buildables[$buildable_phid]);
}
return $page;
}
protected function didFilterPage(array $page) {
if ($this->needContainerObjects || $this->needContainerHandles) {
$container_phids = array_filter(mpull($page, 'getContainerPHID'));
if ($this->needContainerObjects) {
$containers = array();
if ($container_phids) {
$containers = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($container_phids)
->setParentQuery($this)
->execute();
$containers = mpull($containers, null, 'getPHID');
}
foreach ($page as $key => $buildable) {
$container_phid = $buildable->getContainerPHID();
$buildable->attachContainerObject(idx($containers, $container_phid));
}
}
if ($this->needContainerHandles) {
$handles = array();
if ($container_phids) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs($container_phids)
->setParentQuery($this)
->execute();
}
foreach ($page as $key => $buildable) {
$container_phid = $buildable->getContainerPHID();
$buildable->attachContainerHandle(idx($handles, $container_phid));
}
}
}
if ($this->needBuildableHandles) {
$handles = array();
$handle_phids = array_filter(mpull($page, 'getBuildablePHID'));
if ($handle_phids) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs($handle_phids)
->setParentQuery($this)
->execute();
}
foreach ($page as $key => $buildable) {
$handle_phid = $buildable->getBuildablePHID();
$buildable->attachBuildableHandle(idx($handles, $handle_phid));
}
}
if ($this->needBuilds) {
$builds = id(new HarbormasterBuildQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withBuildablePHIDs(mpull($page, 'getPHID'))
->execute();
$builds = mgroup($builds, 'getBuildablePHID');
foreach ($page as $key => $buildable) {
$buildable->attachBuilds(idx($builds, $buildable->getPHID(), array()));
}
}
return $page;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->buildablePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'buildablePHID IN (%Ls)',
$this->buildablePHIDs);
}
if ($this->containerPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'containerPHID in (%Ls)',
$this->containerPHIDs);
}
if ($this->manualBuildables !== null) {
$where[] = qsprintf(
$conn_r,
'isManualBuildable = %d',
(int)$this->manualBuildables);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/herald/query/HeraldRuleQuery.php b/src/applications/herald/query/HeraldRuleQuery.php
index 6e88dc40a0..5967c6ffc9 100644
--- a/src/applications/herald/query/HeraldRuleQuery.php
+++ b/src/applications/herald/query/HeraldRuleQuery.php
@@ -1,276 +1,276 @@
<?php
final class HeraldRuleQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $ruleTypes;
private $contentTypes;
private $disabled;
private $triggerObjectPHIDs;
private $needConditionsAndActions;
private $needAppliedToPHIDs;
private $needValidateAuthors;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withRuleTypes(array $types) {
$this->ruleTypes = $types;
return $this;
}
public function withContentTypes(array $types) {
$this->contentTypes = $types;
return $this;
}
public function withExecutableRules($executable) {
$this->executable = $executable;
return $this;
}
public function withDisabled($disabled) {
$this->disabled = $disabled;
return $this;
}
public function withTriggerObjectPHIDs(array $phids) {
$this->triggerObjectPHIDs = $phids;
return $this;
}
public function needConditionsAndActions($need) {
$this->needConditionsAndActions = $need;
return $this;
}
public function needAppliedToPHIDs(array $phids) {
$this->needAppliedToPHIDs = $phids;
return $this;
}
public function needValidateAuthors($need) {
$this->needValidateAuthors = $need;
return $this;
}
protected function loadPage() {
$table = new HeraldRule();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT rule.* FROM %T rule %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $rules) {
$rule_ids = mpull($rules, 'getID');
// Filter out any rules that have invalid adapters, or have adapters the
// viewer isn't permitted to see or use (for example, Differential rules
// if the user can't use Differential or Differential is not installed).
$types = HeraldAdapter::getEnabledAdapterMap($this->getViewer());
foreach ($rules as $key => $rule) {
if (empty($types[$rule->getContentType()])) {
$this->didRejectResult($rule);
unset($rules[$key]);
}
}
if ($this->needValidateAuthors) {
$this->validateRuleAuthors($rules);
}
if ($this->needConditionsAndActions) {
$conditions = id(new HeraldCondition())->loadAllWhere(
'ruleID IN (%Ld)',
$rule_ids);
$conditions = mgroup($conditions, 'getRuleID');
$actions = id(new HeraldAction())->loadAllWhere(
'ruleID IN (%Ld)',
$rule_ids);
$actions = mgroup($actions, 'getRuleID');
foreach ($rules as $rule) {
$rule->attachActions(idx($actions, $rule->getID(), array()));
$rule->attachConditions(idx($conditions, $rule->getID(), array()));
}
}
if ($this->needAppliedToPHIDs) {
$conn_r = id(new HeraldRule())->establishConnection('r');
$applied = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE ruleID IN (%Ld) AND phid IN (%Ls)',
HeraldRule::TABLE_RULE_APPLIED,
$rule_ids,
$this->needAppliedToPHIDs);
$map = array();
foreach ($applied as $row) {
$map[$row['ruleID']][$row['phid']] = true;
}
foreach ($rules as $rule) {
foreach ($this->needAppliedToPHIDs as $phid) {
$rule->setRuleApplied(
$phid,
isset($map[$rule->getID()][$phid]));
}
}
}
$object_phids = array();
foreach ($rules as $rule) {
if ($rule->isObjectRule()) {
$object_phids[] = $rule->getTriggerObjectPHID();
}
}
if ($object_phids) {
$objects = id(new PhabricatorObjectQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($object_phids)
->execute();
$objects = mpull($objects, null, 'getPHID');
} else {
$objects = array();
}
foreach ($rules as $key => $rule) {
if ($rule->isObjectRule()) {
$object = idx($objects, $rule->getTriggerObjectPHID());
if (!$object) {
unset($rules[$key]);
continue;
}
$rule->attachTriggerObject($object);
}
}
return $rules;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'rule.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'rule.phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'rule.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->ruleTypes) {
$where[] = qsprintf(
$conn_r,
'rule.ruleType IN (%Ls)',
$this->ruleTypes);
}
if ($this->contentTypes) {
$where[] = qsprintf(
$conn_r,
'rule.contentType IN (%Ls)',
$this->contentTypes);
}
if ($this->disabled !== null) {
$where[] = qsprintf(
$conn_r,
'rule.isDisabled = %d',
(int)$this->disabled);
}
if ($this->triggerObjectPHIDs) {
$where[] = qsprintf(
$conn_r,
'rule.triggerObjectPHID IN (%Ls)',
$this->triggerObjectPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function validateRuleAuthors(array $rules) {
// "Global" and "Object" rules always have valid authors.
foreach ($rules as $key => $rule) {
if ($rule->isGlobalRule() || $rule->isObjectRule()) {
$rule->attachValidAuthor(true);
unset($rules[$key]);
continue;
}
}
if (!$rules) {
return;
}
// For personal rules, the author needs to exist and not be disabled.
$user_phids = mpull($rules, 'getAuthorPHID');
$users = id(new PhabricatorPeopleQuery())
->setViewer($this->getViewer())
->withPHIDs($user_phids)
->execute();
$users = mpull($users, null, 'getPHID');
foreach ($rules as $key => $rule) {
$author_phid = $rule->getAuthorPHID();
if (empty($users[$author_phid])) {
$rule->attachValidAuthor(false);
continue;
}
if (!$users[$author_phid]->isUserActivated()) {
$rule->attachValidAuthor(false);
continue;
}
$rule->attachValidAuthor(true);
$rule->attachAuthor($users[$author_phid]);
}
}
public function getQueryApplicationClass() {
return 'PhabricatorHeraldApplication';
}
}
diff --git a/src/applications/herald/query/HeraldTranscriptQuery.php b/src/applications/herald/query/HeraldTranscriptQuery.php
index b76b657a7f..d679009c4e 100644
--- a/src/applications/herald/query/HeraldTranscriptQuery.php
+++ b/src/applications/herald/query/HeraldTranscriptQuery.php
@@ -1,114 +1,114 @@
<?php
final class HeraldTranscriptQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $objectPHIDs;
private $needPartialRecords;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
public function needPartialRecords($need_partial) {
$this->needPartialRecords = $need_partial;
return $this;
}
protected function loadPage() {
$transcript = new HeraldTranscript();
$conn_r = $transcript->establishConnection('r');
// NOTE: Transcripts include a potentially enormous amount of serialized
// data, so we're loading only some of the fields here if the caller asked
// for partial records.
if ($this->needPartialRecords) {
$fields = implode(
', ',
array(
'id',
'phid',
'objectPHID',
'time',
'duration',
'dryRun',
'host',
));
} else {
$fields = '*';
}
$rows = queryfx_all(
$conn_r,
'SELECT %Q FROM %T t %Q %Q %Q',
$fields,
$transcript->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$transcripts = $transcript->loadAllFromArray($rows);
if ($this->needPartialRecords) {
// Make sure nothing tries to write these; they aren't complete.
foreach ($transcripts as $transcript) {
$transcript->makeEphemeral();
}
}
return $transcripts;
}
protected function willFilterPage(array $transcripts) {
$phids = mpull($transcripts, 'getObjectPHID');
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($phids)
->execute();
foreach ($transcripts as $key => $transcript) {
if (empty($objects[$transcript->getObjectPHID()])) {
$this->didRejectResult($transcript);
unset($transcripts[$key]);
}
}
return $transcripts;
}
- public function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->objectPHIDs) {
$where[] = qsprintf(
$conn_r,
'objectPHID in (%Ls)',
$this->objectPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHeraldApplication';
}
}
diff --git a/src/applications/legalpad/query/LegalpadDocumentQuery.php b/src/applications/legalpad/query/LegalpadDocumentQuery.php
index 03ec6b3d3c..e2e43e0e28 100644
--- a/src/applications/legalpad/query/LegalpadDocumentQuery.php
+++ b/src/applications/legalpad/query/LegalpadDocumentQuery.php
@@ -1,278 +1,278 @@
<?php
final class LegalpadDocumentQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $creatorPHIDs;
private $contributorPHIDs;
private $signerPHIDs;
private $dateCreatedAfter;
private $dateCreatedBefore;
private $signatureRequired;
private $needDocumentBodies;
private $needContributors;
private $needSignatures;
private $needViewerSignatures;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCreatorPHIDs(array $phids) {
$this->creatorPHIDs = $phids;
return $this;
}
public function withContributorPHIDs(array $phids) {
$this->contributorPHIDs = $phids;
return $this;
}
public function withSignerPHIDs(array $phids) {
$this->signerPHIDs = $phids;
return $this;
}
public function withSignatureRequired($bool) {
$this->signatureRequired = $bool;
return $this;
}
public function needDocumentBodies($need_bodies) {
$this->needDocumentBodies = $need_bodies;
return $this;
}
public function needContributors($need_contributors) {
$this->needContributors = $need_contributors;
return $this;
}
public function needSignatures($need_signatures) {
$this->needSignatures = $need_signatures;
return $this;
}
public function withDateCreatedBefore($date_created_before) {
$this->dateCreatedBefore = $date_created_before;
return $this;
}
public function withDateCreatedAfter($date_created_after) {
$this->dateCreatedAfter = $date_created_after;
return $this;
}
public function needViewerSignatures($need) {
$this->needViewerSignatures = $need;
return $this;
}
protected function loadPage() {
$table = new LegalpadDocument();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT d.* FROM %T d %Q %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$documents = $table->loadAllFromArray($data);
return $documents;
}
protected function willFilterPage(array $documents) {
if ($this->needDocumentBodies) {
$documents = $this->loadDocumentBodies($documents);
}
if ($this->needContributors) {
$documents = $this->loadContributors($documents);
}
if ($this->needSignatures) {
$documents = $this->loadSignatures($documents);
}
if ($this->needViewerSignatures) {
if ($documents) {
if ($this->getViewer()->getPHID()) {
$signatures = id(new LegalpadDocumentSignatureQuery())
->setViewer($this->getViewer())
->withSignerPHIDs(array($this->getViewer()->getPHID()))
->withDocumentPHIDs(mpull($documents, 'getPHID'))
->execute();
$signatures = mpull($signatures, null, 'getDocumentPHID');
} else {
$signatures = array();
}
foreach ($documents as $document) {
$signature = idx($signatures, $document->getPHID());
$document->attachUserSignature(
$this->getViewer()->getPHID(),
$signature);
}
}
}
return $documents;
}
private function buildJoinClause($conn_r) {
$joins = array();
if ($this->contributorPHIDs !== null) {
$joins[] = qsprintf(
$conn_r,
'JOIN edge contributor ON contributor.src = d.phid
AND contributor.type = %d',
PhabricatorObjectHasContributorEdgeType::EDGECONST);
}
if ($this->signerPHIDs !== null) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T signer ON signer.documentPHID = d.phid
AND signer.signerPHID IN (%Ls)',
id(new LegalpadDocumentSignature())->getTableName(),
$this->signerPHIDs);
}
return implode(' ', $joins);
}
private function buildGroupClause(AphrontDatabaseConnection $conn_r) {
if ($this->contributorPHIDs || $this->signerPHIDs) {
return 'GROUP BY d.id';
} else {
return '';
}
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'd.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'd.phid IN (%Ls)',
$this->phids);
}
if ($this->creatorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'd.creatorPHID IN (%Ls)',
$this->creatorPHIDs);
}
if ($this->dateCreatedAfter !== null) {
$where[] = qsprintf(
$conn_r,
'd.dateCreated >= %d',
$this->dateCreatedAfter);
}
if ($this->dateCreatedBefore !== null) {
$where[] = qsprintf(
$conn_r,
'd.dateCreated <= %d',
$this->dateCreatedBefore);
}
if ($this->contributorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'contributor.dst IN (%Ls)',
$this->contributorPHIDs);
}
if ($this->signatureRequired !== null) {
$where[] = qsprintf(
$conn_r,
'd.requireSignature = %d',
$this->signatureRequired);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function loadDocumentBodies(array $documents) {
$body_phids = mpull($documents, 'getDocumentBodyPHID');
$bodies = id(new LegalpadDocumentBody())->loadAllWhere(
'phid IN (%Ls)',
$body_phids);
$bodies = mpull($bodies, null, 'getPHID');
foreach ($documents as $document) {
$body = idx($bodies, $document->getDocumentBodyPHID());
$document->attachDocumentBody($body);
}
return $documents;
}
private function loadContributors(array $documents) {
$document_map = mpull($documents, null, 'getPHID');
$edge_type = PhabricatorObjectHasContributorEdgeType::EDGECONST;
$contributor_data = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array_keys($document_map))
->withEdgeTypes(array($edge_type))
->execute();
foreach ($document_map as $document_phid => $document) {
$data = $contributor_data[$document_phid];
$contributors = array_keys(idx($data, $edge_type, array()));
$document->attachContributors($contributors);
}
return $documents;
}
private function loadSignatures(array $documents) {
$document_map = mpull($documents, null, 'getPHID');
$signatures = id(new LegalpadDocumentSignatureQuery())
->setViewer($this->getViewer())
->withDocumentPHIDs(array_keys($document_map))
->execute();
$signatures = mgroup($signatures, 'getDocumentPHID');
foreach ($documents as $document) {
$sigs = idx($signatures, $document->getPHID(), array());
$document->attachSignatures($sigs);
}
return $documents;
}
public function getQueryApplicationClass() {
return 'PhabricatorLegalpadApplication';
}
}
diff --git a/src/applications/legalpad/query/LegalpadDocumentSignatureQuery.php b/src/applications/legalpad/query/LegalpadDocumentSignatureQuery.php
index 3bb3628c99..452ea6759b 100644
--- a/src/applications/legalpad/query/LegalpadDocumentSignatureQuery.php
+++ b/src/applications/legalpad/query/LegalpadDocumentSignatureQuery.php
@@ -1,150 +1,150 @@
<?php
final class LegalpadDocumentSignatureQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $documentPHIDs;
private $signerPHIDs;
private $documentVersions;
private $secretKeys;
private $nameContains;
private $emailContains;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withDocumentPHIDs(array $phids) {
$this->documentPHIDs = $phids;
return $this;
}
public function withSignerPHIDs(array $phids) {
$this->signerPHIDs = $phids;
return $this;
}
public function withDocumentVersions(array $versions) {
$this->documentVersions = $versions;
return $this;
}
public function withSecretKeys(array $keys) {
$this->secretKeys = $keys;
return $this;
}
public function withNameContains($text) {
$this->nameContains = $text;
return $this;
}
public function withEmailContains($text) {
$this->emailContains = $text;
return $this;
}
protected function loadPage() {
$table = new LegalpadDocumentSignature();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$signatures = $table->loadAllFromArray($data);
return $signatures;
}
protected function willFilterPage(array $signatures) {
$document_phids = mpull($signatures, 'getDocumentPHID');
$documents = id(new LegalpadDocumentQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($document_phids)
->execute();
$documents = mpull($documents, null, 'getPHID');
foreach ($signatures as $key => $signature) {
$document_phid = $signature->getDocumentPHID();
$document = idx($documents, $document_phid);
if ($document) {
$signature->attachDocument($document);
} else {
unset($signatures[$key]);
}
}
return $signatures;
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->documentPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'documentPHID IN (%Ls)',
$this->documentPHIDs);
}
if ($this->signerPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'signerPHID IN (%Ls)',
$this->signerPHIDs);
}
if ($this->documentVersions !== null) {
$where[] = qsprintf(
$conn_r,
'documentVersion IN (%Ld)',
$this->documentVersions);
}
if ($this->secretKeys !== null) {
$where[] = qsprintf(
$conn_r,
'secretKey IN (%Ls)',
$this->secretKeys);
}
if ($this->nameContains !== null) {
$where[] = qsprintf(
$conn_r,
'signerName LIKE %~',
$this->nameContains);
}
if ($this->emailContains !== null) {
$where[] = qsprintf(
$conn_r,
'signerEmail LIKE %~',
$this->emailContains);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorLegalpadApplication';
}
}
diff --git a/src/applications/mailinglists/query/PhabricatorMailingListQuery.php b/src/applications/mailinglists/query/PhabricatorMailingListQuery.php
index 44f54edbda..113bb4c80d 100644
--- a/src/applications/mailinglists/query/PhabricatorMailingListQuery.php
+++ b/src/applications/mailinglists/query/PhabricatorMailingListQuery.php
@@ -1,86 +1,86 @@
<?php
final class PhabricatorMailingListQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids;
private $ids;
private $emails;
private $names;
public function withIDs($ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs($phids) {
$this->phids = $phids;
return $this;
}
public function withEmails(array $emails) {
$this->emails = $emails;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
protected function loadPage() {
$table = new PhabricatorMetaMTAMailingList();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->names) {
$where[] = qsprintf(
$conn_r,
'name IN (%Ls)',
$this->names);
}
if ($this->emails) {
$where[] = qsprintf(
$conn_r,
'email IN (%Ls)',
$this->emails);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorMailingListsApplication';
}
}
diff --git a/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php b/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php
index d2ac2f17a6..b173224914 100644
--- a/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php
+++ b/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php
@@ -1,125 +1,125 @@
<?php
final class PhabricatorMetaMTAApplicationEmailQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $addresses;
private $addressPrefix;
private $applicationPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAddresses(array $addresses) {
$this->addresses = $addresses;
return $this;
}
public function withAddressPrefix($prefix) {
$this->addressPrefix = $prefix;
return $this;
}
public function withApplicationPHIDs(array $phids) {
$this->applicationPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorMetaMTAApplicationEmail();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T appemail %Q %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildApplicationSearchGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $app_emails) {
$app_emails_map = mgroup($app_emails, 'getApplicationPHID');
$applications = id(new PhabricatorApplicationQuery())
->setViewer($this->getViewer())
->withPHIDs(array_keys($app_emails_map))
->execute();
$applications = mpull($applications, null, 'getPHID');
foreach ($app_emails_map as $app_phid => $app_emails_group) {
foreach ($app_emails_group as $app_email) {
$application = idx($applications, $app_phid);
if (!$application) {
unset($app_emails[$app_phid]);
continue;
}
$app_email->attachApplication($application);
}
}
return $app_emails;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->addresses !== null) {
$where[] = qsprintf(
$conn_r,
'appemail.address IN (%Ls)',
$this->addresses);
}
if ($this->addressPrefix !== null) {
$where[] = qsprintf(
$conn_r,
'appemail.address LIKE %>',
$this->addressPrefix);
}
if ($this->applicationPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'appemail.applicationPHID IN (%Ls)',
$this->applicationPHIDs);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'appemail.phid IN (%Ls)',
$this->phids);
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'appemail.id IN (%Ld)',
$this->ids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function getPrimaryTableAlias() {
return 'appemail';
}
public function getQueryApplicationClass() {
return 'PhabricatorMetaMTAApplication';
}
}
diff --git a/src/applications/notification/query/PhabricatorNotificationQuery.php b/src/applications/notification/query/PhabricatorNotificationQuery.php
index a1f8ac63c7..aa430a2518 100644
--- a/src/applications/notification/query/PhabricatorNotificationQuery.php
+++ b/src/applications/notification/query/PhabricatorNotificationQuery.php
@@ -1,114 +1,114 @@
<?php
/**
* @task config Configuring the Query
* @task exec Query Execution
*/
final class PhabricatorNotificationQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $userPHIDs;
private $keys;
private $unread;
/* -( Configuring the Query )---------------------------------------------- */
public function withUserPHIDs(array $user_phids) {
$this->userPHIDs = $user_phids;
return $this;
}
public function withKeys(array $keys) {
$this->keys = $keys;
return $this;
}
/**
* Filter results by read/unread status. Note that `true` means to return
* only unread notifications, while `false` means to return only //read//
* notifications. The default is `null`, which returns both.
*
* @param mixed True or false to filter results by read status. Null to remove
* the filter.
* @return this
* @task config
*/
public function withUnread($unread) {
$this->unread = $unread;
return $this;
}
/* -( Query Execution )---------------------------------------------------- */
protected function loadPage() {
$story_table = new PhabricatorFeedStoryData();
$notification_table = new PhabricatorFeedStoryNotification();
$conn = $story_table->establishConnection('r');
$data = queryfx_all(
$conn,
'SELECT story.*, notif.hasViewed FROM %T notif
JOIN %T story ON notif.chronologicalKey = story.chronologicalKey
%Q
ORDER BY notif.chronologicalKey DESC
%Q',
$notification_table->getTableName(),
$story_table->getTableName(),
$this->buildWhereClause($conn),
$this->buildLimitClause($conn));
$viewed_map = ipull($data, 'hasViewed', 'chronologicalKey');
$stories = PhabricatorFeedStory::loadAllFromRows(
$data,
$this->getViewer());
foreach ($stories as $key => $story) {
$story->setHasViewed($viewed_map[$key]);
}
return $stories;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->userPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'notif.userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->unread !== null) {
$where[] = qsprintf(
$conn_r,
'notif.hasViewed = %d',
(int)!$this->unread);
}
if ($this->keys) {
$where[] = qsprintf(
$conn_r,
'notif.chronologicalKey IN (%Ls)',
$this->keys);
}
return $this->formatWhereClause($where);
}
protected function getResultCursor($item) {
return $item->getChronologicalKey();
}
public function getQueryApplicationClass() {
return 'PhabricatorNotificationsApplication';
}
}
diff --git a/src/applications/nuance/query/NuanceItemQuery.php b/src/applications/nuance/query/NuanceItemQuery.php
index 5264c4b527..4b87f38a77 100644
--- a/src/applications/nuance/query/NuanceItemQuery.php
+++ b/src/applications/nuance/query/NuanceItemQuery.php
@@ -1,70 +1,70 @@
<?php
final class NuanceItemQuery
extends NuanceQuery {
private $ids;
private $phids;
private $sourceIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withSourceIDs($source_ids) {
$this->sourceIDs = $source_ids;
return $this;
}
protected function loadPage() {
$table = new NuanceItem();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->sourceID) {
$where[] = qsprintf(
$conn_r,
'sourceID IN (%Ld)',
$this->sourceIDs);
}
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/nuance/query/NuanceQueueQuery.php b/src/applications/nuance/query/NuanceQueueQuery.php
index b4a067f01c..822a60c620 100644
--- a/src/applications/nuance/query/NuanceQueueQuery.php
+++ b/src/applications/nuance/query/NuanceQueueQuery.php
@@ -1,56 +1,56 @@
<?php
final class NuanceQueueQuery
extends NuanceQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new NuanceQueue();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/nuance/query/NuanceRequestorQuery.php b/src/applications/nuance/query/NuanceRequestorQuery.php
index e23cc71343..91a9878b83 100644
--- a/src/applications/nuance/query/NuanceRequestorQuery.php
+++ b/src/applications/nuance/query/NuanceRequestorQuery.php
@@ -1,56 +1,56 @@
<?php
final class NuanceRequestorQuery
extends NuanceQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new NuanceRequestor();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/nuance/query/NuanceSourceQuery.php b/src/applications/nuance/query/NuanceSourceQuery.php
index 3a177a4e42..77421656e7 100644
--- a/src/applications/nuance/query/NuanceSourceQuery.php
+++ b/src/applications/nuance/query/NuanceSourceQuery.php
@@ -1,83 +1,83 @@
<?php
final class NuanceSourceQuery
extends NuanceQuery {
private $ids;
private $phids;
private $creatorPHIDs;
private $types;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCreatorPHIDs(array $phids) {
$this->CreatorPHIDs = $phids;
return $this;
}
public function withTypes($types) {
$this->types = $types;
return $this;
}
protected function loadPage() {
$table = new NuanceSource();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->creatorPHIDs) {
$where[] = qsprintf(
$conn_r,
'creatorPHID IN (%Ls)',
$this->creatorPHIDs);
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'type IN (%Ld)',
$this->types);
}
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php b/src/applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php
index 754e3474ab..f19be14434 100644
--- a/src/applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php
+++ b/src/applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php
@@ -1,95 +1,95 @@
<?php
final class PhabricatorOAuthClientAuthorizationQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids;
private $userPHIDs;
private $clientPHIDs;
public function witHPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withUserPHIDs(array $phids) {
$this->userPHIDs = $phids;
return $this;
}
public function withClientPHIDs(array $phids) {
$this->clientPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorOAuthClientAuthorization();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T auth %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $authorizations) {
$client_phids = mpull($authorizations, 'getClientPHID');
$clients = id(new PhabricatorOAuthServerClientQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($client_phids)
->execute();
$clients = mpull($clients, null, 'getPHID');
foreach ($authorizations as $key => $authorization) {
$client = idx($clients, $authorization->getClientPHID());
if (!$client) {
unset($authorizations[$key]);
continue;
}
$authorization->attachClient($client);
}
return $authorizations;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->userPHIDs) {
$where[] = qsprintf(
$conn_r,
'userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->clientPHIDs) {
$where[] = qsprintf(
$conn_r,
'clientPHID IN (%Ls)',
$this->clientPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorOAuthServerApplication';
}
}
diff --git a/src/applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php b/src/applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php
index bf22a2a701..b5da9ecd5f 100644
--- a/src/applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php
+++ b/src/applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php
@@ -1,73 +1,73 @@
<?php
final class PhabricatorOAuthServerClientQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $creatorPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCreatorPHIDs(array $phids) {
$this->creatorPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorOAuthServerClient();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T client %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->creatorPHIDs) {
$where[] = qsprintf(
$conn_r,
'creatorPHID IN (%Ls)',
$this->creatorPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorOAuthServerApplication';
}
}
diff --git a/src/applications/owners/query/PhabricatorOwnersPackageQuery.php b/src/applications/owners/query/PhabricatorOwnersPackageQuery.php
index bdfb6f5a4e..64640c3ab8 100644
--- a/src/applications/owners/query/PhabricatorOwnersPackageQuery.php
+++ b/src/applications/owners/query/PhabricatorOwnersPackageQuery.php
@@ -1,86 +1,86 @@
<?php
final class PhabricatorOwnersPackageQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids;
private $ownerPHIDs;
/**
* Owners are direct owners, and members of owning projects.
*/
public function withOwnerPHIDs(array $phids) {
$this->ownerPHIDs = $phids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorOwnersPackage();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT p.* FROM %T p %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
private function buildJoinClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
if ($this->ownerPHIDs) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T o ON o.packageID = p.id',
id(new PhabricatorOwnersOwner())->getTableName());
}
return implode(' ', $joins);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'p.phid IN (%Ls)',
$this->phids);
}
if ($this->ownerPHIDs) {
$base_phids = $this->ownerPHIDs;
$query = new PhabricatorProjectQuery();
$query->setViewer($this->getViewer());
$query->withMemberPHIDs($base_phids);
$projects = $query->execute();
$project_phids = mpull($projects, 'getPHID');
$all_phids = array_merge($base_phids, $project_phids);
$where[] = qsprintf(
$conn_r,
'o.userPHID IN (%Ls)',
$all_phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorOwnersApplication';
}
}
diff --git a/src/applications/passphrase/query/PassphraseCredentialQuery.php b/src/applications/passphrase/query/PassphraseCredentialQuery.php
index 29f661397d..9cae8b1f85 100644
--- a/src/applications/passphrase/query/PassphraseCredentialQuery.php
+++ b/src/applications/passphrase/query/PassphraseCredentialQuery.php
@@ -1,163 +1,163 @@
<?php
final class PassphraseCredentialQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $credentialTypes;
private $providesTypes;
private $isDestroyed;
private $allowConduit;
private $nameContains;
private $needSecrets;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCredentialTypes(array $credential_types) {
$this->credentialTypes = $credential_types;
return $this;
}
public function withProvidesTypes(array $provides_types) {
$this->providesTypes = $provides_types;
return $this;
}
public function withIsDestroyed($destroyed) {
$this->isDestroyed = $destroyed;
return $this;
}
public function withAllowConduit($allow_conduit) {
$this->allowConduit = $allow_conduit;
return $this;
}
public function withNameContains($name_contains) {
$this->nameContains = $name_contains;
return $this;
}
public function needSecrets($need_secrets) {
$this->needSecrets = $need_secrets;
return $this;
}
protected function loadPage() {
$table = new PassphraseCredential();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $page) {
if ($this->needSecrets) {
$secret_ids = mpull($page, 'getSecretID');
$secret_ids = array_filter($secret_ids);
$secrets = array();
if ($secret_ids) {
$secret_objects = id(new PassphraseSecret())->loadAllWhere(
'id IN (%Ld)',
$secret_ids);
foreach ($secret_objects as $secret) {
$secret_data = $secret->getSecretData();
$secrets[$secret->getID()] = new PhutilOpaqueEnvelope($secret_data);
}
}
foreach ($page as $key => $credential) {
$secret_id = $credential->getSecretID();
if (!$secret_id) {
$credential->attachSecret(null);
} else if (isset($secrets[$secret_id])) {
$credential->attachSecret($secrets[$secret_id]);
} else {
unset($page[$key]);
}
}
}
return $page;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->credentialTypes) {
$where[] = qsprintf(
$conn_r,
'credentialType in (%Ls)',
$this->credentialTypes);
}
if ($this->providesTypes) {
$where[] = qsprintf(
$conn_r,
'providesType IN (%Ls)',
$this->providesTypes);
}
if ($this->isDestroyed !== null) {
$where[] = qsprintf(
$conn_r,
'isDestroyed = %d',
(int)$this->isDestroyed);
}
if ($this->allowConduit !== null) {
$where[] = qsprintf(
$conn_r,
'allowConduit = %d',
(int)$this->allowConduit);
}
if (strlen($this->nameContains)) {
$where[] = qsprintf(
$conn_r,
'name LIKE %~',
$this->nameContains);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPassphraseApplication';
}
}
diff --git a/src/applications/paste/query/PhabricatorPasteQuery.php b/src/applications/paste/query/PhabricatorPasteQuery.php
index 35c3820311..ae74978510 100644
--- a/src/applications/paste/query/PhabricatorPasteQuery.php
+++ b/src/applications/paste/query/PhabricatorPasteQuery.php
@@ -1,252 +1,252 @@
<?php
final class PhabricatorPasteQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $parentPHIDs;
private $needContent;
private $needRawContent;
private $languages;
private $includeNoLanguage;
private $dateCreatedAfter;
private $dateCreatedBefore;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
public function withParentPHIDs(array $phids) {
$this->parentPHIDs = $phids;
return $this;
}
public function needContent($need_content) {
$this->needContent = $need_content;
return $this;
}
public function needRawContent($need_raw_content) {
$this->needRawContent = $need_raw_content;
return $this;
}
public function withLanguages(array $languages) {
$this->includeNoLanguage = false;
foreach ($languages as $key => $language) {
if ($language === null) {
$languages[$key] = '';
continue;
}
}
$this->languages = $languages;
return $this;
}
public function withDateCreatedBefore($date_created_before) {
$this->dateCreatedBefore = $date_created_before;
return $this;
}
public function withDateCreatedAfter($date_created_after) {
$this->dateCreatedAfter = $date_created_after;
return $this;
}
protected function loadPage() {
$table = new PhabricatorPaste();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT paste.* FROM %T paste %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$pastes = $table->loadAllFromArray($data);
return $pastes;
}
protected function didFilterPage(array $pastes) {
if ($this->needRawContent) {
$pastes = $this->loadRawContent($pastes);
}
if ($this->needContent) {
$this->loadContent($pastes);
}
return $pastes;
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->parentPHIDs) {
$where[] = qsprintf(
$conn_r,
'parentPHID IN (%Ls)',
$this->parentPHIDs);
}
if ($this->languages) {
$where[] = qsprintf(
$conn_r,
'language IN (%Ls)',
$this->languages);
}
if ($this->dateCreatedAfter) {
$where[] = qsprintf(
$conn_r,
'dateCreated >= %d',
$this->dateCreatedAfter);
}
if ($this->dateCreatedBefore) {
$where[] = qsprintf(
$conn_r,
'dateCreated <= %d',
$this->dateCreatedBefore);
}
return $this->formatWhereClause($where);
}
private function getContentCacheKey(PhabricatorPaste $paste) {
return implode(
':',
array(
'P'.$paste->getID(),
$paste->getFilePHID(),
$paste->getLanguage(),
));
}
private function loadRawContent(array $pastes) {
$file_phids = mpull($pastes, 'getFilePHID');
$files = id(new PhabricatorFileQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
foreach ($pastes as $key => $paste) {
$file = idx($files, $paste->getFilePHID());
if (!$file) {
unset($pastes[$key]);
continue;
}
try {
$paste->attachRawContent($file->loadFileData());
} catch (Exception $ex) {
// We can hit various sorts of file storage issues here. Just drop the
// paste if the file is dead.
unset($pastes[$key]);
continue;
}
}
return $pastes;
}
private function loadContent(array $pastes) {
$cache = new PhabricatorKeyValueDatabaseCache();
$cache = new PhutilKeyValueCacheProfiler($cache);
$cache->setProfiler(PhutilServiceProfiler::getInstance());
$keys = array();
foreach ($pastes as $paste) {
$keys[] = $this->getContentCacheKey($paste);
}
$caches = $cache->getKeys($keys);
$need_raw = array();
foreach ($pastes as $key => $paste) {
$key = $this->getContentCacheKey($paste);
if (isset($caches[$key])) {
$paste->attachContent(phutil_safe_html($caches[$key]));
} else {
$need_raw[$key] = $paste;
}
}
if (!$need_raw) {
return;
}
$write_data = array();
$need_raw = $this->loadRawContent($need_raw);
foreach ($need_raw as $key => $paste) {
$content = $this->buildContent($paste);
$paste->attachContent($content);
$write_data[$this->getContentCacheKey($paste)] = (string)$content;
}
$cache->setKeys($write_data);
}
private function buildContent(PhabricatorPaste $paste) {
$language = $paste->getLanguage();
$source = $paste->getRawContent();
if (empty($language)) {
return PhabricatorSyntaxHighlighter::highlightWithFilename(
$paste->getTitle(),
$source);
} else {
return PhabricatorSyntaxHighlighter::highlightWithLanguage(
$language,
$source);
}
}
public function getQueryApplicationClass() {
return 'PhabricatorPasteApplication';
}
}
diff --git a/src/applications/people/query/PhabricatorPeopleLogQuery.php b/src/applications/people/query/PhabricatorPeopleLogQuery.php
index 3315234d12..9bcdc53f49 100644
--- a/src/applications/people/query/PhabricatorPeopleLogQuery.php
+++ b/src/applications/people/query/PhabricatorPeopleLogQuery.php
@@ -1,113 +1,113 @@
<?php
final class PhabricatorPeopleLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $actorPHIDs;
private $userPHIDs;
private $relatedPHIDs;
private $sessionKeys;
private $actions;
private $remoteAddressPrefix;
public function withActorPHIDs(array $actor_phids) {
$this->actorPHIDs = $actor_phids;
return $this;
}
public function withUserPHIDs(array $user_phids) {
$this->userPHIDs = $user_phids;
return $this;
}
public function withRelatedPHIDs(array $related_phids) {
$this->relatedPHIDs = $related_phids;
return $this;
}
public function withSessionKeys(array $session_keys) {
$this->sessionKeys = $session_keys;
return $this;
}
public function withActions(array $actions) {
$this->actions = $actions;
return $this;
}
public function withRemoteAddressPrefix($remote_address_prefix) {
$this->remoteAddressPrefix = $remote_address_prefix;
return $this;
}
protected function loadPage() {
$table = new PhabricatorUserLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->actorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'actorPHID IN (%Ls)',
$this->actorPHIDs);
}
if ($this->userPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->relatedPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'actorPHID IN (%Ls) OR userPHID IN (%Ls)',
$this->relatedPHIDs,
$this->relatedPHIDs);
}
if ($this->sessionKeys !== null) {
$where[] = qsprintf(
$conn_r,
'session IN (%Ls)',
$this->sessionKeys);
}
if ($this->actions !== null) {
$where[] = qsprintf(
$conn_r,
'action IN (%Ls)',
$this->actions);
}
if ($this->remoteAddressPrefix !== null) {
$where[] = qsprintf(
$conn_r,
'remoteAddr LIKE %>',
$this->remoteAddressPrefix);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPeopleApplication';
}
}
diff --git a/src/applications/people/query/PhabricatorPeopleQuery.php b/src/applications/people/query/PhabricatorPeopleQuery.php
index 472e76a8a1..437f764fe9 100644
--- a/src/applications/people/query/PhabricatorPeopleQuery.php
+++ b/src/applications/people/query/PhabricatorPeopleQuery.php
@@ -1,350 +1,350 @@
<?php
final class PhabricatorPeopleQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $usernames;
private $realnames;
private $emails;
private $phids;
private $ids;
private $dateCreatedAfter;
private $dateCreatedBefore;
private $isAdmin;
private $isSystemAgent;
private $isDisabled;
private $isApproved;
private $nameLike;
private $nameTokens;
private $needPrimaryEmail;
private $needProfile;
private $needProfileImage;
private $needStatus;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withEmails(array $emails) {
$this->emails = $emails;
return $this;
}
public function withRealnames(array $realnames) {
$this->realnames = $realnames;
return $this;
}
public function withUsernames(array $usernames) {
$this->usernames = $usernames;
return $this;
}
public function withDateCreatedBefore($date_created_before) {
$this->dateCreatedBefore = $date_created_before;
return $this;
}
public function withDateCreatedAfter($date_created_after) {
$this->dateCreatedAfter = $date_created_after;
return $this;
}
public function withIsAdmin($admin) {
$this->isAdmin = $admin;
return $this;
}
public function withIsSystemAgent($system_agent) {
$this->isSystemAgent = $system_agent;
return $this;
}
public function withIsDisabled($disabled) {
$this->isDisabled = $disabled;
return $this;
}
public function withIsApproved($approved) {
$this->isApproved = $approved;
return $this;
}
public function withNameLike($like) {
$this->nameLike = $like;
return $this;
}
public function withNameTokens(array $tokens) {
$this->nameTokens = array_values($tokens);
return $this;
}
public function needPrimaryEmail($need) {
$this->needPrimaryEmail = $need;
return $this;
}
public function needProfile($need) {
$this->needProfile = $need;
return $this;
}
public function needProfileImage($need) {
$this->needProfileImage = $need;
return $this;
}
public function needStatus($need) {
$this->needStatus = $need;
return $this;
}
protected function loadPage() {
$table = new PhabricatorUser();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T user %Q %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinsClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
if ($this->needPrimaryEmail) {
$table->putInSet(new LiskDAOSet());
}
return $table->loadAllFromArray($data);
}
protected function didFilterPage(array $users) {
if ($this->needProfile) {
$user_list = mpull($users, null, 'getPHID');
$profiles = new PhabricatorUserProfile();
$profiles = $profiles->loadAllWhere('userPHID IN (%Ls)',
array_keys($user_list));
$profiles = mpull($profiles, null, 'getUserPHID');
foreach ($user_list as $user_phid => $user) {
$profile = idx($profiles, $user_phid);
if (!$profile) {
$profile = new PhabricatorUserProfile();
$profile->setUserPHID($user_phid);
}
$user->attachUserProfile($profile);
}
}
if ($this->needProfileImage) {
$user_profile_file_phids = mpull($users, 'getProfileImagePHID');
$user_profile_file_phids = array_filter($user_profile_file_phids);
if ($user_profile_file_phids) {
$files = id(new PhabricatorFileQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($user_profile_file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
} else {
$files = array();
}
foreach ($users as $user) {
$image_phid = $user->getProfileImagePHID();
if (isset($files[$image_phid])) {
$profile_image_uri = $files[$image_phid]->getBestURI();
} else {
$profile_image_uri = PhabricatorUser::getDefaultProfileImageURI();
}
$user->attachProfileImageURI($profile_image_uri);
}
}
if ($this->needStatus) {
$user_list = mpull($users, null, 'getPHID');
$statuses = id(new PhabricatorCalendarEvent())->loadCurrentStatuses(
array_keys($user_list));
foreach ($user_list as $phid => $user) {
$status = idx($statuses, $phid);
if ($status) {
$user->attachStatus($status);
}
}
}
return $users;
}
private function buildGroupClause(AphrontDatabaseConnection $conn) {
if ($this->nameTokens) {
return qsprintf(
$conn,
'GROUP BY user.id');
} else {
return $this->buildApplicationSearchGroupClause($conn);
}
}
private function buildJoinsClause($conn_r) {
$joins = array();
if ($this->emails) {
$email_table = new PhabricatorUserEmail();
$joins[] = qsprintf(
$conn_r,
'JOIN %T email ON email.userPHID = user.PHID',
$email_table->getTableName());
}
if ($this->nameTokens) {
foreach ($this->nameTokens as $key => $token) {
$token_table = 'token_'.$key;
$joins[] = qsprintf(
$conn_r,
'JOIN %T %T ON %T.userID = user.id AND %T.token LIKE %>',
PhabricatorUser::NAMETOKEN_TABLE,
$token_table,
$token_table,
$token_table,
$token);
}
}
$joins[] = $this->buildApplicationSearchJoinClause($conn_r);
$joins = implode(' ', $joins);
return $joins;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->usernames !== null) {
$where[] = qsprintf(
$conn_r,
'user.userName IN (%Ls)',
$this->usernames);
}
if ($this->emails !== null) {
$where[] = qsprintf(
$conn_r,
'email.address IN (%Ls)',
$this->emails);
}
if ($this->realnames !== null) {
$where[] = qsprintf(
$conn_r,
'user.realName IN (%Ls)',
$this->realnames);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'user.phid IN (%Ls)',
$this->phids);
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'user.id IN (%Ld)',
$this->ids);
}
if ($this->dateCreatedAfter) {
$where[] = qsprintf(
$conn_r,
'user.dateCreated >= %d',
$this->dateCreatedAfter);
}
if ($this->dateCreatedBefore) {
$where[] = qsprintf(
$conn_r,
'user.dateCreated <= %d',
$this->dateCreatedBefore);
}
if ($this->isAdmin) {
$where[] = qsprintf(
$conn_r,
'user.isAdmin = 1');
}
if ($this->isDisabled !== null) {
$where[] = qsprintf(
$conn_r,
'user.isDisabled = %d',
(int)$this->isDisabled);
}
if ($this->isApproved !== null) {
$where[] = qsprintf(
$conn_r,
'user.isApproved = %d',
(int)$this->isApproved);
}
if ($this->isSystemAgent) {
$where[] = qsprintf(
$conn_r,
'user.isSystemAgent = 1');
}
if (strlen($this->nameLike)) {
$where[] = qsprintf(
$conn_r,
'user.username LIKE %~ OR user.realname LIKE %~',
$this->nameLike,
$this->nameLike);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function getPrimaryTableAlias() {
return 'user';
}
public function getQueryApplicationClass() {
return 'PhabricatorPeopleApplication';
}
public function getOrderableColumns() {
return parent::getOrderableColumns() + array(
'username' => array(
'table' => 'user',
'column' => 'username',
'type' => 'string',
'reverse' => true,
'unique' => true,
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
$user = $this->loadCursorObject($cursor);
return array(
'id' => $user->getID(),
'username' => $user->getUsername(),
);
}
}
diff --git a/src/applications/phame/query/PhameBlogQuery.php b/src/applications/phame/query/PhameBlogQuery.php
index 160749a18f..a3e88e5143 100644
--- a/src/applications/phame/query/PhameBlogQuery.php
+++ b/src/applications/phame/query/PhameBlogQuery.php
@@ -1,80 +1,80 @@
<?php
final class PhameBlogQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $domain;
private $needBloggers;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withDomain($domain) {
$this->domain = $domain;
return $this;
}
protected function loadPage() {
$table = new PhameBlog();
$conn_r = $table->establishConnection('r');
$where_clause = $this->buildWhereClause($conn_r);
$order_clause = $this->buildOrderClause($conn_r);
$limit_clause = $this->buildLimitClause($conn_r);
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T b %Q %Q %Q',
$table->getTableName(),
$where_clause,
$order_clause,
$limit_clause);
$blogs = $table->loadAllFromArray($data);
return $blogs;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ls)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->domain) {
$where[] = qsprintf(
$conn_r,
'domain = %s',
$this->domain);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
// TODO: Can we set this without breaking public blogs?
return null;
}
}
diff --git a/src/applications/phame/query/PhamePostQuery.php b/src/applications/phame/query/PhamePostQuery.php
index d87c26e35e..2eed8d2960 100644
--- a/src/applications/phame/query/PhamePostQuery.php
+++ b/src/applications/phame/query/PhamePostQuery.php
@@ -1,146 +1,146 @@
<?php
final class PhamePostQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $blogPHIDs;
private $bloggerPHIDs;
private $phameTitles;
private $visibility;
private $publishedAfter;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBloggerPHIDs(array $blogger_phids) {
$this->bloggerPHIDs = $blogger_phids;
return $this;
}
public function withBlogPHIDs(array $blog_phids) {
$this->blogPHIDs = $blog_phids;
return $this;
}
public function withPhameTitles(array $phame_titles) {
$this->phameTitles = $phame_titles;
return $this;
}
public function withVisibility($visibility) {
$this->visibility = $visibility;
return $this;
}
public function withPublishedAfter($time) {
$this->publishedAfter = $time;
return $this;
}
protected function loadPage() {
$table = new PhamePost();
$conn_r = $table->establishConnection('r');
$where_clause = $this->buildWhereClause($conn_r);
$order_clause = $this->buildOrderClause($conn_r);
$limit_clause = $this->buildLimitClause($conn_r);
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T p %Q %Q %Q',
$table->getTableName(),
$where_clause,
$order_clause,
$limit_clause);
$posts = $table->loadAllFromArray($data);
if ($posts) {
// We require these to do visibility checks, so load them unconditionally.
$blog_phids = mpull($posts, 'getBlogPHID');
$blogs = id(new PhameBlogQuery())
->setViewer($this->getViewer())
->withPHIDs($blog_phids)
->execute();
$blogs = mpull($blogs, null, 'getPHID');
foreach ($posts as $post) {
if (isset($blogs[$post->getBlogPHID()])) {
$post->setBlog($blogs[$post->getBlogPHID()]);
}
}
}
return $posts;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'p.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'p.phid IN (%Ls)',
$this->phids);
}
if ($this->bloggerPHIDs) {
$where[] = qsprintf(
$conn_r,
'p.bloggerPHID IN (%Ls)',
$this->bloggerPHIDs);
}
if ($this->phameTitles) {
$where[] = qsprintf(
$conn_r,
'p.phameTitle IN (%Ls)',
$this->phameTitles);
}
if ($this->visibility !== null) {
$where[] = qsprintf(
$conn_r,
'p.visibility = %d',
$this->visibility);
}
if ($this->publishedAfter !== null) {
$where[] = qsprintf(
$conn_r,
'p.datePublished > %d',
$this->publishedAfter);
}
if ($this->blogPHIDs) {
$where[] = qsprintf(
$conn_r,
'p.blogPHID in (%Ls)',
$this->blogPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
// TODO: Does setting this break public blogs?
return null;
}
}
diff --git a/src/applications/phlux/query/PhluxVariableQuery.php b/src/applications/phlux/query/PhluxVariableQuery.php
index 3439ee1d8b..82072485d4 100644
--- a/src/applications/phlux/query/PhluxVariableQuery.php
+++ b/src/applications/phlux/query/PhluxVariableQuery.php
@@ -1,95 +1,95 @@
<?php
final class PhluxVariableQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $keys;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withKeys(array $keys) {
$this->keys = $keys;
return $this;
}
protected function loadPage() {
$table = new PhluxVariable();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($rows);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->keys !== null) {
$where[] = qsprintf(
$conn_r,
'variableKey IN (%Ls)',
$this->keys);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function getDefaultOrderVector() {
return array('key');
}
public function getOrderableColumns() {
return array(
'key' => array(
'column' => 'variableKey',
'type' => 'string',
'reverse' => true,
'unique' => true,
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
$object = $this->loadCursorObject($cursor);
return array(
'key' => $object->getVariableKey(),
);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhluxApplication';
}
}
diff --git a/src/applications/pholio/query/PholioImageQuery.php b/src/applications/pholio/query/PholioImageQuery.php
index dd5fb23f3c..2d5057ccdc 100644
--- a/src/applications/pholio/query/PholioImageQuery.php
+++ b/src/applications/pholio/query/PholioImageQuery.php
@@ -1,165 +1,165 @@
<?php
final class PholioImageQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $mockIDs;
private $obsolete;
private $needInlineComments;
private $mockCache = array();
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withMockIDs(array $mock_ids) {
$this->mockIDs = $mock_ids;
return $this;
}
public function withObsolete($obsolete) {
$this->obsolete = $obsolete;
return $this;
}
public function needInlineComments($need_inline_comments) {
$this->needInlineComments = $need_inline_comments;
return $this;
}
public function setMockCache($mock_cache) {
$this->mockCache = $mock_cache;
return $this;
}
public function getMockCache() {
return $this->mockCache;
}
protected function loadPage() {
$table = new PholioImage();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$images = $table->loadAllFromArray($data);
return $images;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->mockIDs) {
$where[] = qsprintf(
$conn_r,
'mockID IN (%Ld)',
$this->mockIDs);
}
if ($this->obsolete !== null) {
$where[] = qsprintf(
$conn_r,
'isObsolete = %d',
$this->obsolete);
}
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $images) {
assert_instances_of($images, 'PholioImage');
if ($this->getMockCache()) {
$mocks = $this->getMockCache();
} else {
$mock_ids = mpull($images, 'getMockID');
// DO NOT set needImages to true; recursion results!
$mocks = id(new PholioMockQuery())
->setViewer($this->getViewer())
->withIDs($mock_ids)
->execute();
$mocks = mpull($mocks, null, 'getID');
}
foreach ($images as $index => $image) {
$mock = idx($mocks, $image->getMockID());
if ($mock) {
$image->attachMock($mock);
} else {
// mock is missing or we can't see it
unset($images[$index]);
}
}
return $images;
}
protected function didFilterPage(array $images) {
assert_instances_of($images, 'PholioImage');
$file_phids = mpull($images, 'getFilePHID');
$all_files = id(new PhabricatorFileQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($file_phids)
->execute();
$all_files = mpull($all_files, null, 'getPHID');
if ($this->needInlineComments) {
$all_inline_comments = id(new PholioTransactionComment())
->loadAllWhere('imageid IN (%Ld)',
mpull($images, 'getID'));
$all_inline_comments = mgroup($all_inline_comments, 'getImageID');
}
foreach ($images as $image) {
$file = idx($all_files, $image->getFilePHID());
if (!$file) {
$file = PhabricatorFile::loadBuiltin($this->getViewer(), 'missing.png');
}
$image->attachFile($file);
if ($this->needInlineComments) {
$inlines = idx($all_inline_comments, $image->getID(), array());
$image->attachInlineComments($inlines);
}
}
return $images;
}
public function getQueryApplicationClass() {
return 'PhabricatorPholioApplication';
}
}
diff --git a/src/applications/pholio/query/PholioMockQuery.php b/src/applications/pholio/query/PholioMockQuery.php
index d80bf57a28..2f6edd313f 100644
--- a/src/applications/pholio/query/PholioMockQuery.php
+++ b/src/applications/pholio/query/PholioMockQuery.php
@@ -1,181 +1,181 @@
<?php
final class PholioMockQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $statuses;
private $needCoverFiles;
private $needImages;
private $needInlineComments;
private $needTokenCounts;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function needCoverFiles($need_cover_files) {
$this->needCoverFiles = $need_cover_files;
return $this;
}
public function needImages($need_images) {
$this->needImages = $need_images;
return $this;
}
public function needInlineComments($need_inline_comments) {
$this->needInlineComments = $need_inline_comments;
return $this;
}
public function needTokenCounts($need) {
$this->needTokenCounts = $need;
return $this;
}
protected function loadPage() {
$table = new PholioMock();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$mocks = $table->loadAllFromArray($data);
if ($mocks && $this->needImages) {
self::loadImages($this->getViewer(), $mocks, $this->needInlineComments);
}
if ($mocks && $this->needCoverFiles) {
$this->loadCoverFiles($mocks);
}
if ($mocks && $this->needTokenCounts) {
$this->loadTokenCounts($mocks);
}
return $mocks;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID in (%Ls)',
$this->authorPHIDs);
}
if ($this->statuses) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ls)',
$this->statuses);
}
return $this->formatWhereClause($where);
}
public static function loadImages(
PhabricatorUser $viewer,
array $mocks,
$need_inline_comments) {
assert_instances_of($mocks, 'PholioMock');
$mock_map = mpull($mocks, null, 'getID');
$all_images = id(new PholioImageQuery())
->setViewer($viewer)
->setMockCache($mock_map)
->withMockIDs(array_keys($mock_map))
->needInlineComments($need_inline_comments)
->execute();
$image_groups = mgroup($all_images, 'getMockID');
foreach ($mocks as $mock) {
$mock_images = idx($image_groups, $mock->getID(), array());
$mock->attachAllImages($mock_images);
$active_images = mfilter($mock_images, 'getIsObsolete', true);
$mock->attachImages(msort($active_images, 'getSequence'));
}
}
private function loadCoverFiles(array $mocks) {
assert_instances_of($mocks, 'PholioMock');
$cover_file_phids = mpull($mocks, 'getCoverPHID');
$cover_files = id(new PhabricatorFileQuery())
->setViewer($this->getViewer())
->withPHIDs($cover_file_phids)
->execute();
$cover_files = mpull($cover_files, null, 'getPHID');
foreach ($mocks as $mock) {
$file = idx($cover_files, $mock->getCoverPHID());
if (!$file) {
$file = PhabricatorFile::loadBuiltin($this->getViewer(), 'missing.png');
}
$mock->attachCoverFile($file);
}
}
private function loadTokenCounts(array $mocks) {
assert_instances_of($mocks, 'PholioMock');
$phids = mpull($mocks, 'getPHID');
$counts = id(new PhabricatorTokenCountQuery())
->withObjectPHIDs($phids)
->execute();
foreach ($mocks as $mock) {
$mock->attachTokenCount(idx($counts, $mock->getPHID(), 0));
}
}
public function getQueryApplicationClass() {
return 'PhabricatorPholioApplication';
}
}
diff --git a/src/applications/phortune/query/PhortuneAccountQuery.php b/src/applications/phortune/query/PhortuneAccountQuery.php
index 676badcb0c..a567aa2d38 100644
--- a/src/applications/phortune/query/PhortuneAccountQuery.php
+++ b/src/applications/phortune/query/PhortuneAccountQuery.php
@@ -1,123 +1,123 @@
<?php
final class PhortuneAccountQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $memberPHIDs;
public static function loadAccountsForUser(
PhabricatorUser $user,
PhabricatorContentSource $content_source) {
$accounts = id(new PhortuneAccountQuery())
->setViewer($user)
->withMemberPHIDs(array($user->getPHID()))
->execute();
if (!$accounts) {
$accounts = array(
PhortuneAccount::createNewAccount($user, $content_source),
);
}
$accounts = mpull($accounts, null, 'getPHID');
return $accounts;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withMemberPHIDs(array $phids) {
$this->memberPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new PhortuneAccount();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT a.* FROM %T a %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $accounts) {
$query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($accounts, 'getPHID'))
->withEdgeTypes(array(PhortuneAccountHasMemberEdgeType::EDGECONST));
$query->execute();
foreach ($accounts as $account) {
$member_phids = $query->getDestinationPHIDs(array($account->getPHID()));
$member_phids = array_reverse($member_phids);
$account->attachMemberPHIDs($member_phids);
}
return $accounts;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
$where[] = $this->buildPagingClause($conn);
if ($this->ids) {
$where[] = qsprintf(
$conn,
'a.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn,
'a.phid IN (%Ls)',
$this->phids);
}
if ($this->memberPHIDs) {
$where[] = qsprintf(
$conn,
'm.dst IN (%Ls)',
$this->memberPHIDs);
}
return $this->formatWhereClause($where);
}
private function buildJoinClause(AphrontDatabaseConnection $conn) {
$joins = array();
if ($this->memberPHIDs) {
$joins[] = qsprintf(
$conn,
'LEFT JOIN %T m ON a.phid = m.src AND m.type = %d',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
PhortuneAccountHasMemberEdgeType::EDGECONST);
}
return implode(' ', $joins);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phortune/query/PhortuneCartQuery.php b/src/applications/phortune/query/PhortuneCartQuery.php
index 4897ad7f22..5009d3a685 100644
--- a/src/applications/phortune/query/PhortuneCartQuery.php
+++ b/src/applications/phortune/query/PhortuneCartQuery.php
@@ -1,223 +1,223 @@
<?php
final class PhortuneCartQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $accountPHIDs;
private $merchantPHIDs;
private $subscriptionPHIDs;
private $statuses;
private $invoices;
private $needPurchases;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAccountPHIDs(array $account_phids) {
$this->accountPHIDs = $account_phids;
return $this;
}
public function withMerchantPHIDs(array $merchant_phids) {
$this->merchantPHIDs = $merchant_phids;
return $this;
}
public function withSubscriptionPHIDs(array $subscription_phids) {
$this->subscriptionPHIDs = $subscription_phids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
/**
* Include or exclude carts which represent invoices with payments due.
*
* @param bool `true` to select invoices; `false` to exclude invoices.
* @return this
*/
public function withInvoices($invoices) {
$this->invoices = $invoices;
return $this;
}
public function needPurchases($need_purchases) {
$this->needPurchases = $need_purchases;
return $this;
}
protected function loadPage() {
$table = new PhortuneCart();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT cart.* FROM %T cart %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $carts) {
$accounts = id(new PhortuneAccountQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($carts, 'getAccountPHID'))
->execute();
$accounts = mpull($accounts, null, 'getPHID');
foreach ($carts as $key => $cart) {
$account = idx($accounts, $cart->getAccountPHID());
if (!$account) {
unset($carts[$key]);
continue;
}
$cart->attachAccount($account);
}
if (!$carts) {
return array();
}
$merchants = id(new PhortuneMerchantQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($carts, 'getMerchantPHID'))
->execute();
$merchants = mpull($merchants, null, 'getPHID');
foreach ($carts as $key => $cart) {
$merchant = idx($merchants, $cart->getMerchantPHID());
if (!$merchant) {
unset($carts[$key]);
continue;
}
$cart->attachMerchant($merchant);
}
if (!$carts) {
return array();
}
$implementations = array();
$cart_map = mgroup($carts, 'getCartClass');
foreach ($cart_map as $class => $class_carts) {
$implementations += newv($class, array())->loadImplementationsForCarts(
$this->getViewer(),
$class_carts);
}
foreach ($carts as $key => $cart) {
$implementation = idx($implementations, $key);
if (!$implementation) {
unset($carts[$key]);
continue;
}
$cart->attachImplementation($implementation);
}
return $carts;
}
protected function didFilterPage(array $carts) {
if ($this->needPurchases) {
$purchases = id(new PhortunePurchaseQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withCartPHIDs(mpull($carts, 'getPHID'))
->execute();
$purchases = mgroup($purchases, 'getCartPHID');
foreach ($carts as $cart) {
$cart->attachPurchases(idx($purchases, $cart->getPHID(), array()));
}
}
return $carts;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
$where[] = $this->buildPagingClause($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'cart.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'cart.phid IN (%Ls)',
$this->phids);
}
if ($this->accountPHIDs !== null) {
$where[] = qsprintf(
$conn,
'cart.accountPHID IN (%Ls)',
$this->accountPHIDs);
}
if ($this->merchantPHIDs !== null) {
$where[] = qsprintf(
$conn,
'cart.merchantPHID IN (%Ls)',
$this->merchantPHIDs);
}
if ($this->subscriptionPHIDs !== null) {
$where[] = qsprintf(
$conn,
'cart.subscriptionPHID IN (%Ls)',
$this->subscriptionPHIDs);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn,
'cart.status IN (%Ls)',
$this->statuses);
}
if ($this->invoices !== null) {
if ($this->invoices) {
$where[] = qsprintf(
$conn,
'cart.status = %s AND cart.isInvoice = 1',
PhortuneCart::STATUS_READY);
} else {
$where[] = qsprintf(
$conn,
'cart.status != %s OR cart.isInvoice = 0',
PhortuneCart::STATUS_READY);
}
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phortune/query/PhortuneChargeQuery.php b/src/applications/phortune/query/PhortuneChargeQuery.php
index aba655b4e4..6b11cbe95e 100644
--- a/src/applications/phortune/query/PhortuneChargeQuery.php
+++ b/src/applications/phortune/query/PhortuneChargeQuery.php
@@ -1,144 +1,144 @@
<?php
final class PhortuneChargeQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $accountPHIDs;
private $cartPHIDs;
private $statuses;
private $needCarts;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAccountPHIDs(array $account_phids) {
$this->accountPHIDs = $account_phids;
return $this;
}
public function withCartPHIDs(array $cart_phids) {
$this->cartPHIDs = $cart_phids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function needCarts($need_carts) {
$this->needCarts = $need_carts;
return $this;
}
protected function loadPage() {
$table = new PhortuneCharge();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT charge.* FROM %T charge %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $charges) {
$accounts = id(new PhortuneAccountQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs(mpull($charges, 'getAccountPHID'))
->execute();
$accounts = mpull($accounts, null, 'getPHID');
foreach ($charges as $key => $charge) {
$account = idx($accounts, $charge->getAccountPHID());
if (!$account) {
unset($charges[$key]);
continue;
}
$charge->attachAccount($account);
}
return $charges;
}
protected function didFilterPage(array $charges) {
if ($this->needCarts) {
$carts = id(new PhortuneCartQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs(mpull($charges, 'getCartPHID'))
->execute();
$carts = mpull($carts, null, 'getPHID');
foreach ($charges as $charge) {
$cart = idx($carts, $charge->getCartPHID());
$charge->attachCart($cart);
}
}
return $charges;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
$where[] = $this->buildPagingClause($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'charge.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'charge.phid IN (%Ls)',
$this->phids);
}
if ($this->accountPHIDs !== null) {
$where[] = qsprintf(
$conn,
'charge.accountPHID IN (%Ls)',
$this->accountPHIDs);
}
if ($this->cartPHIDs !== null) {
$where[] = qsprintf(
$conn,
'charge.cartPHID IN (%Ls)',
$this->cartPHIDs);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn,
'charge.status IN (%Ls)',
$this->statuses);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phortune/query/PhortuneMerchantQuery.php b/src/applications/phortune/query/PhortuneMerchantQuery.php
index 1632797421..41a6f1004d 100644
--- a/src/applications/phortune/query/PhortuneMerchantQuery.php
+++ b/src/applications/phortune/query/PhortuneMerchantQuery.php
@@ -1,103 +1,103 @@
<?php
final class PhortuneMerchantQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $memberPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withMemberPHIDs(array $member_phids) {
$this->memberPHIDs = $member_phids;
return $this;
}
protected function loadPage() {
$table = new PhortuneMerchant();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT m.* FROM %T m %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $merchants) {
$query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($merchants, 'getPHID'))
->withEdgeTypes(array(PhortuneMerchantHasMemberEdgeType::EDGECONST));
$query->execute();
foreach ($merchants as $merchant) {
$member_phids = $query->getDestinationPHIDs(array($merchant->getPHID()));
$member_phids = array_reverse($member_phids);
$merchant->attachMemberPHIDs($member_phids);
}
return $merchants;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->memberPHIDs !== null) {
$where[] = qsprintf(
$conn,
'e.dst IN (%Ls)',
$this->memberPHIDs);
}
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
}
private function buildJoinClause(AphrontDatabaseConnection $conn) {
$joins = array();
if ($this->memberPHIDs !== null) {
$joins[] = qsprintf(
$conn,
'LEFT JOIN %T e ON m.phid = e.src AND e.type = %d',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
PhortuneMerchantHasMemberEdgeType::EDGECONST);
}
return implode(' ', $joins);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phortune/query/PhortunePaymentMethodQuery.php b/src/applications/phortune/query/PhortunePaymentMethodQuery.php
index c6b1fd878a..07d49a5909 100644
--- a/src/applications/phortune/query/PhortunePaymentMethodQuery.php
+++ b/src/applications/phortune/query/PhortunePaymentMethodQuery.php
@@ -1,156 +1,156 @@
<?php
final class PhortunePaymentMethodQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $accountPHIDs;
private $merchantPHIDs;
private $statuses;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAccountPHIDs(array $phids) {
$this->accountPHIDs = $phids;
return $this;
}
public function withMerchantPHIDs(array $phids) {
$this->merchantPHIDs = $phids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
protected function loadPage() {
$table = new PhortunePaymentMethod();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $methods) {
$accounts = id(new PhortuneAccountQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($methods, 'getAccountPHID'))
->execute();
$accounts = mpull($accounts, null, 'getPHID');
foreach ($methods as $key => $method) {
$account = idx($accounts, $method->getAccountPHID());
if (!$account) {
unset($methods[$key]);
continue;
}
$method->attachAccount($account);
}
if (!$methods) {
return $methods;
}
$merchants = id(new PhortuneMerchantQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($methods, 'getMerchantPHID'))
->execute();
$merchants = mpull($merchants, null, 'getPHID');
foreach ($methods as $key => $method) {
$merchant = idx($merchants, $method->getMerchantPHID());
if (!$merchant) {
unset($methods[$key]);
continue;
}
$method->attachMerchant($merchant);
}
if (!$methods) {
return $methods;
}
$provider_configs = id(new PhortunePaymentProviderConfigQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($methods, 'getProviderPHID'))
->execute();
$provider_configs = mpull($provider_configs, null, 'getPHID');
foreach ($methods as $key => $method) {
$provider_config = idx($provider_configs, $method->getProviderPHID());
if (!$provider_config) {
unset($methods[$key]);
continue;
}
$method->attachProviderConfig($provider_config);
}
return $methods;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->accountPHIDs !== null) {
$where[] = qsprintf(
$conn,
'accountPHID IN (%Ls)',
$this->accountPHIDs);
}
if ($this->merchantPHIDs !== null) {
$where[] = qsprintf(
$conn,
'merchantPHID IN (%Ls)',
$this->merchantPHIDs);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn,
'status IN (%Ls)',
$this->statuses);
}
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phortune/query/PhortunePaymentProviderConfigQuery.php b/src/applications/phortune/query/PhortunePaymentProviderConfigQuery.php
index 748ff7cb64..d80b0e90d0 100644
--- a/src/applications/phortune/query/PhortunePaymentProviderConfigQuery.php
+++ b/src/applications/phortune/query/PhortunePaymentProviderConfigQuery.php
@@ -1,95 +1,95 @@
<?php
final class PhortunePaymentProviderConfigQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $merchantPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withMerchantPHIDs(array $phids) {
$this->merchantPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new PhortunePaymentProviderConfig();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $provider_configs) {
$merchant_phids = mpull($provider_configs, 'getMerchantPHID');
$merchants = id(new PhortuneMerchantQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($merchant_phids)
->execute();
$merchants = mpull($merchants, null, 'getPHID');
foreach ($provider_configs as $key => $config) {
$merchant = idx($merchants, $config->getMerchantPHID());
if (!$merchant) {
$this->didRejectResult($config);
unset($provider_configs[$key]);
continue;
}
$config->attachMerchant($merchant);
}
return $provider_configs;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->merchantPHIDs !== null) {
$where[] = qsprintf(
$conn,
'merchantPHID IN (%Ls)',
$this->merchantPHIDs);
}
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phortune/query/PhortuneProductQuery.php b/src/applications/phortune/query/PhortuneProductQuery.php
index ae824ab914..99ba535585 100644
--- a/src/applications/phortune/query/PhortuneProductQuery.php
+++ b/src/applications/phortune/query/PhortuneProductQuery.php
@@ -1,120 +1,120 @@
<?php
final class PhortuneProductQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $refMap;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withClassAndRef($class, $ref) {
$this->refMap = array($class => array($ref));
return $this;
}
protected function loadPage() {
$table = new PhortuneProduct();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
$page = $table->loadAllFromArray($rows);
// NOTE: We're loading product implementations here, but also creating any
// products which do not yet exist.
$class_map = mgroup($page, 'getProductClass');
if ($this->refMap) {
$class_map += array_fill_keys(array_keys($this->refMap), array());
}
foreach ($class_map as $class => $products) {
$refs = mpull($products, null, 'getProductRef');
if (isset($this->refMap[$class])) {
$refs += array_fill_keys($this->refMap[$class], null);
}
$implementations = newv($class, array())->loadImplementationsForRefs(
$this->getViewer(),
array_keys($refs));
$implementations = mpull($implementations, null, 'getRef');
foreach ($implementations as $ref => $implementation) {
$product = idx($refs, $ref);
if ($product === null) {
// If this product does not exist yet, create it and add it to the
// result page.
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$product = PhortuneProduct::initializeNewProduct()
->setProductClass($class)
->setProductRef($ref)
->save();
unset($unguarded);
$page[] = $product;
}
$product->attachImplementation($implementation);
}
}
return $page;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->refMap !== null) {
$sql = array();
foreach ($this->refMap as $class => $refs) {
foreach ($refs as $ref) {
$sql[] = qsprintf(
$conn,
'(productClassKey = %s AND productRefKey = %s)',
PhabricatorHash::digestForIndex($class),
PhabricatorHash::digestForIndex($ref));
}
}
$where[] = implode(' OR ', $sql);
}
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phortune/query/PhortunePurchaseQuery.php b/src/applications/phortune/query/PhortunePurchaseQuery.php
index 70aff445a0..6e9e599240 100644
--- a/src/applications/phortune/query/PhortunePurchaseQuery.php
+++ b/src/applications/phortune/query/PhortunePurchaseQuery.php
@@ -1,110 +1,110 @@
<?php
final class PhortunePurchaseQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $cartPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCartPHIDs(array $cart_phids) {
$this->cartPHIDs = $cart_phids;
return $this;
}
protected function loadPage() {
$table = new PhortunePurchase();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT purchase.* FROM %T purchase %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $purchases) {
$carts = id(new PhortuneCartQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs(mpull($purchases, 'getCartPHID'))
->execute();
$carts = mpull($carts, null, 'getPHID');
foreach ($purchases as $key => $purchase) {
$cart = idx($carts, $purchase->getCartPHID());
if (!$cart) {
unset($purchases[$key]);
continue;
}
$purchase->attachCart($cart);
}
$products = id(new PhortuneProductQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs(mpull($purchases, 'getProductPHID'))
->execute();
$products = mpull($products, null, 'getPHID');
foreach ($purchases as $key => $purchase) {
$product = idx($products, $purchase->getProductPHID());
if (!$product) {
unset($purchases[$key]);
continue;
}
$purchase->attachProduct($product);
}
return $purchases;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
$where[] = $this->buildPagingClause($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'purchase.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'purchase.phid IN (%Ls)',
$this->phids);
}
if ($this->cartPHIDs !== null) {
$where[] = qsprintf(
$conn,
'purchase.cartPHID IN (%Ls)',
$this->cartPHIDs);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phortune/query/PhortuneSubscriptionQuery.php b/src/applications/phortune/query/PhortuneSubscriptionQuery.php
index ba6d7acc73..e8b39c0fee 100644
--- a/src/applications/phortune/query/PhortuneSubscriptionQuery.php
+++ b/src/applications/phortune/query/PhortuneSubscriptionQuery.php
@@ -1,192 +1,192 @@
<?php
final class PhortuneSubscriptionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $accountPHIDs;
private $merchantPHIDs;
private $statuses;
private $needTriggers;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAccountPHIDs(array $account_phids) {
$this->accountPHIDs = $account_phids;
return $this;
}
public function withMerchantPHIDs(array $merchant_phids) {
$this->merchantPHIDs = $merchant_phids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function needTriggers($need_triggers) {
$this->needTriggers = $need_triggers;
return $this;
}
protected function loadPage() {
$table = new PhortuneSubscription();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT subscription.* FROM %T subscription %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $subscriptions) {
$accounts = id(new PhortuneAccountQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($subscriptions, 'getAccountPHID'))
->execute();
$accounts = mpull($accounts, null, 'getPHID');
foreach ($subscriptions as $key => $subscription) {
$account = idx($accounts, $subscription->getAccountPHID());
if (!$account) {
unset($subscriptions[$key]);
continue;
}
$subscription->attachAccount($account);
}
if (!$subscriptions) {
return $subscriptions;
}
$merchants = id(new PhortuneMerchantQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($subscriptions, 'getMerchantPHID'))
->execute();
$merchants = mpull($merchants, null, 'getPHID');
foreach ($subscriptions as $key => $subscription) {
$merchant = idx($merchants, $subscription->getMerchantPHID());
if (!$merchant) {
unset($subscriptions[$key]);
continue;
}
$subscription->attachMerchant($merchant);
}
if (!$subscriptions) {
return $subscriptions;
}
$implementations = array();
$subscription_map = mgroup($subscriptions, 'getSubscriptionClass');
foreach ($subscription_map as $class => $class_subscriptions) {
$sub = newv($class, array());
$impl_objects = $sub->loadImplementationsForRefs(
$this->getViewer(),
mpull($class_subscriptions, 'getSubscriptionRef'));
$implementations += mpull($impl_objects, null, 'getRef');
}
foreach ($subscriptions as $key => $subscription) {
$ref = $subscription->getSubscriptionRef();
$implementation = idx($implementations, $ref);
if (!$implementation) {
unset($subscriptions[$key]);
continue;
}
$subscription->attachImplementation($implementation);
}
if (!$subscriptions) {
return $subscriptions;
}
if ($this->needTriggers) {
$trigger_phids = mpull($subscriptions, 'getTriggerPHID');
$triggers = id(new PhabricatorWorkerTriggerQuery())
->setViewer($this->getViewer())
->withPHIDs($trigger_phids)
->needEvents(true)
->execute();
$triggers = mpull($triggers, null, 'getPHID');
foreach ($subscriptions as $key => $subscription) {
$trigger = idx($triggers, $subscription->getTriggerPHID());
if (!$trigger) {
unset($subscriptions[$key]);
continue;
}
$subscription->attachTrigger($trigger);
}
}
return $subscriptions;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
$where[] = $this->buildPagingClause($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'subscription.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'subscription.phid IN (%Ls)',
$this->phids);
}
if ($this->accountPHIDs !== null) {
$where[] = qsprintf(
$conn,
'subscription.accountPHID IN (%Ls)',
$this->accountPHIDs);
}
if ($this->merchantPHIDs !== null) {
$where[] = qsprintf(
$conn,
'subscription.merchantPHID IN (%Ls)',
$this->merchantPHIDs);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn,
'subscription.status IN (%Ls)',
$this->statuses);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
}
diff --git a/src/applications/phragment/query/PhragmentFragmentQuery.php b/src/applications/phragment/query/PhragmentFragmentQuery.php
index 173acfb1ce..d6dc67609d 100644
--- a/src/applications/phragment/query/PhragmentFragmentQuery.php
+++ b/src/applications/phragment/query/PhragmentFragmentQuery.php
@@ -1,130 +1,130 @@
<?php
final class PhragmentFragmentQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $paths;
private $leadingPath;
private $depths;
private $needLatestVersion;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withPaths(array $paths) {
$this->paths = $paths;
return $this;
}
public function withLeadingPath($path) {
$this->leadingPath = $path;
return $this;
}
public function withDepths($depths) {
$this->depths = $depths;
return $this;
}
public function needLatestVersion($need_latest_version) {
$this->needLatestVersion = $need_latest_version;
return $this;
}
protected function loadPage() {
$table = new PhragmentFragment();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->paths) {
$where[] = qsprintf(
$conn_r,
'path IN (%Ls)',
$this->paths);
}
if ($this->leadingPath) {
$where[] = qsprintf(
$conn_r,
'path LIKE %>',
$this->leadingPath);
}
if ($this->depths) {
$where[] = qsprintf(
$conn_r,
'depth IN (%Ld)',
$this->depths);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function didFilterPage(array $page) {
if ($this->needLatestVersion) {
$versions = array();
$version_phids = array_filter(mpull($page, 'getLatestVersionPHID'));
if ($version_phids) {
$versions = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($version_phids)
->setParentQuery($this)
->execute();
$versions = mpull($versions, null, 'getPHID');
}
foreach ($page as $key => $fragment) {
$version_phid = $fragment->getLatestVersionPHID();
if (empty($versions[$version_phid])) {
continue;
}
$fragment->attachLatestVersion($versions[$version_phid]);
}
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorPhragmentApplication';
}
}
diff --git a/src/applications/phragment/query/PhragmentFragmentVersionQuery.php b/src/applications/phragment/query/PhragmentFragmentVersionQuery.php
index 4acbd0f636..a874a8be1a 100644
--- a/src/applications/phragment/query/PhragmentFragmentVersionQuery.php
+++ b/src/applications/phragment/query/PhragmentFragmentVersionQuery.php
@@ -1,123 +1,123 @@
<?php
final class PhragmentFragmentVersionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $fragmentPHIDs;
private $sequences;
private $sequenceBefore;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withFragmentPHIDs(array $fragment_phids) {
$this->fragmentPHIDs = $fragment_phids;
return $this;
}
public function withSequences(array $sequences) {
$this->sequences = $sequences;
return $this;
}
public function withSequenceBefore($current) {
$this->sequenceBefore = $current;
return $this;
}
protected function loadPage() {
$table = new PhragmentFragmentVersion();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->fragmentPHIDs) {
$where[] = qsprintf(
$conn_r,
'fragmentPHID IN (%Ls)',
$this->fragmentPHIDs);
}
if ($this->sequences) {
$where[] = qsprintf(
$conn_r,
'sequence IN (%Ld)',
$this->sequences);
}
if ($this->sequenceBefore !== null) {
$where[] = qsprintf(
$conn_r,
'sequence < %d',
$this->sequenceBefore);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $page) {
$fragments = array();
$fragment_phids = array_filter(mpull($page, 'getFragmentPHID'));
if ($fragment_phids) {
$fragments = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($fragment_phids)
->setParentQuery($this)
->execute();
$fragments = mpull($fragments, null, 'getPHID');
}
foreach ($page as $key => $version) {
$fragment_phid = $version->getFragmentPHID();
if (empty($fragments[$fragment_phid])) {
unset($page[$key]);
continue;
}
$version->attachFragment($fragments[$fragment_phid]);
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorPhragmentApplication';
}
}
diff --git a/src/applications/phragment/query/PhragmentSnapshotChildQuery.php b/src/applications/phragment/query/PhragmentSnapshotChildQuery.php
index 8f81beeabe..032fb0c49c 100644
--- a/src/applications/phragment/query/PhragmentSnapshotChildQuery.php
+++ b/src/applications/phragment/query/PhragmentSnapshotChildQuery.php
@@ -1,174 +1,174 @@
<?php
final class PhragmentSnapshotChildQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $snapshotPHIDs;
private $fragmentPHIDs;
private $fragmentVersionPHIDs;
private $needFragments;
private $needFragmentVersions;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withSnapshotPHIDs(array $snapshot_phids) {
$this->snapshotPHIDs = $snapshot_phids;
return $this;
}
public function withFragmentPHIDs(array $fragment_phids) {
$this->fragmentPHIDs = $fragment_phids;
return $this;
}
public function withFragmentVersionPHIDs(array $fragment_version_phids) {
$this->fragmentVersionPHIDs = $fragment_version_phids;
return $this;
}
public function needFragments($need_fragments) {
$this->needFragments = $need_fragments;
return $this;
}
public function needFragmentVersions($need_fragment_versions) {
$this->needFragmentVersions = $need_fragment_versions;
return $this;
}
protected function loadPage() {
$table = new PhragmentSnapshotChild();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->snapshotPHIDs) {
$where[] = qsprintf(
$conn_r,
'snapshotPHID IN (%Ls)',
$this->snapshotPHIDs);
}
if ($this->fragmentPHIDs) {
$where[] = qsprintf(
$conn_r,
'fragmentPHID IN (%Ls)',
$this->fragmentPHIDs);
}
if ($this->fragmentVersionPHIDs) {
$where[] = qsprintf(
$conn_r,
'fragmentVersionPHID IN (%Ls)',
$this->fragmentVersionPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $page) {
$snapshots = array();
$snapshot_phids = array_filter(mpull($page, 'getSnapshotPHID'));
if ($snapshot_phids) {
$snapshots = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($snapshot_phids)
->setParentQuery($this)
->execute();
$snapshots = mpull($snapshots, null, 'getPHID');
}
foreach ($page as $key => $child) {
$snapshot_phid = $child->getSnapshotPHID();
if (empty($snapshots[$snapshot_phid])) {
unset($page[$key]);
continue;
}
$child->attachSnapshot($snapshots[$snapshot_phid]);
}
return $page;
}
protected function didFilterPage(array $page) {
if ($this->needFragments) {
$fragments = array();
$fragment_phids = array_filter(mpull($page, 'getFragmentPHID'));
if ($fragment_phids) {
$fragments = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($fragment_phids)
->setParentQuery($this)
->execute();
$fragments = mpull($fragments, null, 'getPHID');
}
foreach ($page as $key => $child) {
$fragment_phid = $child->getFragmentPHID();
if (empty($fragments[$fragment_phid])) {
unset($page[$key]);
continue;
}
$child->attachFragment($fragments[$fragment_phid]);
}
}
if ($this->needFragmentVersions) {
$fragment_versions = array();
$fragment_version_phids = array_filter(mpull(
$page,
'getFragmentVersionPHID'));
if ($fragment_version_phids) {
$fragment_versions = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($fragment_version_phids)
->setParentQuery($this)
->execute();
$fragment_versions = mpull($fragment_versions, null, 'getPHID');
}
foreach ($page as $key => $child) {
$fragment_version_phid = $child->getFragmentVersionPHID();
if (empty($fragment_versions[$fragment_version_phid])) {
continue;
}
$child->attachFragmentVersion(
$fragment_versions[$fragment_version_phid]);
}
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorPhragmentApplication';
}
}
diff --git a/src/applications/phragment/query/PhragmentSnapshotQuery.php b/src/applications/phragment/query/PhragmentSnapshotQuery.php
index 81c73441d2..d6f9d3422f 100644
--- a/src/applications/phragment/query/PhragmentSnapshotQuery.php
+++ b/src/applications/phragment/query/PhragmentSnapshotQuery.php
@@ -1,111 +1,111 @@
<?php
final class PhragmentSnapshotQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $primaryFragmentPHIDs;
private $names;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withPrimaryFragmentPHIDs(array $primary_fragment_phids) {
$this->primaryFragmentPHIDs = $primary_fragment_phids;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
protected function loadPage() {
$table = new PhragmentSnapshot();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->primaryFragmentPHIDs) {
$where[] = qsprintf(
$conn_r,
'primaryFragmentPHID IN (%Ls)',
$this->primaryFragmentPHIDs);
}
if ($this->names) {
$where[] = qsprintf(
$conn_r,
'name IN (%Ls)',
$this->names);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $page) {
$fragments = array();
$fragment_phids = array_filter(mpull($page, 'getPrimaryFragmentPHID'));
if ($fragment_phids) {
$fragments = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($fragment_phids)
->setParentQuery($this)
->execute();
$fragments = mpull($fragments, null, 'getPHID');
}
foreach ($page as $key => $snapshot) {
$fragment_phid = $snapshot->getPrimaryFragmentPHID();
if (empty($fragments[$fragment_phid])) {
unset($page[$key]);
continue;
}
$snapshot->attachPrimaryFragment($fragments[$fragment_phid]);
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorPhragmentApplication';
}
}
diff --git a/src/applications/phrequent/query/PhrequentUserTimeQuery.php b/src/applications/phrequent/query/PhrequentUserTimeQuery.php
index b6e0c85f48..61fa978165 100644
--- a/src/applications/phrequent/query/PhrequentUserTimeQuery.php
+++ b/src/applications/phrequent/query/PhrequentUserTimeQuery.php
@@ -1,333 +1,333 @@
<?php
final class PhrequentUserTimeQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
const ORDER_ID_ASC = 0;
const ORDER_ID_DESC = 1;
const ORDER_STARTED_ASC = 2;
const ORDER_STARTED_DESC = 3;
const ORDER_ENDED_ASC = 4;
const ORDER_ENDED_DESC = 5;
const ENDED_YES = 0;
const ENDED_NO = 1;
const ENDED_ALL = 2;
private $ids;
private $userPHIDs;
private $objectPHIDs;
private $ended = self::ENDED_ALL;
private $needPreemptingEvents;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withUserPHIDs(array $user_phids) {
$this->userPHIDs = $user_phids;
return $this;
}
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
public function withEnded($ended) {
$this->ended = $ended;
return $this;
}
public function setOrder($order) {
switch ($order) {
case self::ORDER_ID_ASC:
$this->setOrderVector(array('-id'));
break;
case self::ORDER_ID_DESC:
$this->setOrderVector(array('id'));
break;
case self::ORDER_STARTED_ASC:
$this->setOrderVector(array('-start', '-id'));
break;
case self::ORDER_STARTED_DESC:
$this->setOrderVector(array('start', 'id'));
break;
case self::ORDER_ENDED_ASC:
$this->setOrderVector(array('-end', '-id'));
break;
case self::ORDER_ENDED_DESC:
$this->setOrderVector(array('end', 'id'));
break;
default:
throw new Exception(pht('Unknown order "%s".', $order));
}
return $this;
}
public function needPreemptingEvents($need_events) {
$this->needPreemptingEvents = $need_events;
return $this;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->userPHIDs !== null) {
$where[] = qsprintf(
$conn,
'userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
switch ($this->ended) {
case self::ENDED_ALL:
break;
case self::ENDED_YES:
$where[] = qsprintf(
$conn,
'dateEnded IS NOT NULL');
break;
case self::ENDED_NO:
$where[] = qsprintf(
$conn,
'dateEnded IS NULL');
break;
default:
throw new Exception("Unknown ended '{$this->ended}'!");
}
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
}
public function getOrderableColumns() {
return parent::getOrderableColumns() + array(
'start' => array(
'column' => 'dateStarted',
'type' => 'int',
),
'end' => array(
'column' => 'dateEnded',
'type' => 'int',
'null' => 'head',
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
$usertime = $this->loadCursorObject($cursor);
return array(
'id' => $usertime->getID(),
'start' => $usertime->getDateStarted(),
'end' => $usertime->getDateEnded(),
);
}
protected function loadPage() {
$usertime = new PhrequentUserTime();
$conn = $usertime->establishConnection('r');
$data = queryfx_all(
$conn,
'SELECT usertime.* FROM %T usertime %Q %Q %Q',
$usertime->getTableName(),
$this->buildWhereClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
return $usertime->loadAllFromArray($data);
}
protected function didFilterPage(array $page) {
if ($this->needPreemptingEvents) {
$usertime = new PhrequentUserTime();
$conn_r = $usertime->establishConnection('r');
$preempt = array();
foreach ($page as $event) {
$preempt[] = qsprintf(
$conn_r,
'(userPHID = %s AND
(dateStarted BETWEEN %d AND %d) AND
(dateEnded IS NULL OR dateEnded > %d))',
$event->getUserPHID(),
$event->getDateStarted(),
nonempty($event->getDateEnded(), PhabricatorTime::getNow()),
$event->getDateStarted());
}
$preempting_events = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE %Q ORDER BY dateStarted ASC, id ASC',
$usertime->getTableName(),
implode(' OR ', $preempt));
$preempting_events = $usertime->loadAllFromArray($preempting_events);
$preempting_events = mgroup($preempting_events, 'getUserPHID');
foreach ($page as $event) {
$e_start = $event->getDateStarted();
$e_end = $event->getDateEnded();
$select = array();
$user_events = idx($preempting_events, $event->getUserPHID(), array());
foreach ($user_events as $u_event) {
if ($u_event->getID() == $event->getID()) {
// Don't allow an event to preempt itself.
continue;
}
$u_start = $u_event->getDateStarted();
$u_end = $u_event->getDateEnded();
if ($u_start < $e_start) {
// This event started before our event started, so it's not
// preempting us.
continue;
}
if ($u_start == $e_start) {
if ($u_event->getID() < $event->getID()) {
// This event started at the same time as our event started,
// but has a lower ID, so it's not preempting us.
continue;
}
}
if (($e_end !== null) && ($u_start > $e_end)) {
// Our event has ended, and this event started after it ended.
continue;
}
if (($u_end !== null) && ($u_end < $e_start)) {
// This event ended before our event began.
continue;
}
$select[] = $u_event;
}
$event->attachPreemptingEvents($select);
}
}
return $page;
}
/* -( Helper Functions ) --------------------------------------------------- */
public static function getEndedSearchOptions() {
return array(
self::ENDED_ALL => pht('All'),
self::ENDED_NO => pht('No'),
self::ENDED_YES => pht('Yes'),
);
}
public static function getOrderSearchOptions() {
return array(
self::ORDER_STARTED_ASC => pht('by furthest start date'),
self::ORDER_STARTED_DESC => pht('by nearest start date'),
self::ORDER_ENDED_ASC => pht('by furthest end date'),
self::ORDER_ENDED_DESC => pht('by nearest end date'),
);
}
public static function getUserTotalObjectsTracked(
PhabricatorUser $user,
$limit = PHP_INT_MAX) {
$usertime_dao = new PhrequentUserTime();
$conn = $usertime_dao->establishConnection('r');
$count = queryfx_one(
$conn,
'SELECT COUNT(usertime.id) N FROM %T usertime '.
'WHERE usertime.userPHID = %s '.
'AND usertime.dateEnded IS NULL '.
'LIMIT %d',
$usertime_dao->getTableName(),
$user->getPHID(),
$limit);
return $count['N'];
}
public static function isUserTrackingObject(
PhabricatorUser $user,
$phid) {
$usertime_dao = new PhrequentUserTime();
$conn = $usertime_dao->establishConnection('r');
$count = queryfx_one(
$conn,
'SELECT COUNT(usertime.id) N FROM %T usertime '.
'WHERE usertime.userPHID = %s '.
'AND usertime.objectPHID = %s '.
'AND usertime.dateEnded IS NULL',
$usertime_dao->getTableName(),
$user->getPHID(),
$phid);
return $count['N'] > 0;
}
public static function getUserTimeSpentOnObject(
PhabricatorUser $user,
$phid) {
$usertime_dao = new PhrequentUserTime();
$conn = $usertime_dao->establishConnection('r');
// First calculate all the time spent where the
// usertime blocks have ended.
$sum_ended = queryfx_one(
$conn,
'SELECT SUM(usertime.dateEnded - usertime.dateStarted) N '.
'FROM %T usertime '.
'WHERE usertime.userPHID = %s '.
'AND usertime.objectPHID = %s '.
'AND usertime.dateEnded IS NOT NULL',
$usertime_dao->getTableName(),
$user->getPHID(),
$phid);
// Now calculate the time spent where the usertime
// blocks have not yet ended.
$sum_not_ended = queryfx_one(
$conn,
'SELECT SUM(UNIX_TIMESTAMP() - usertime.dateStarted) N '.
'FROM %T usertime '.
'WHERE usertime.userPHID = %s '.
'AND usertime.objectPHID = %s '.
'AND usertime.dateEnded IS NULL',
$usertime_dao->getTableName(),
$user->getPHID(),
$phid);
return $sum_ended['N'] + $sum_not_ended['N'];
}
public function getQueryApplicationClass() {
return 'PhabricatorPhrequentApplication';
}
}
diff --git a/src/applications/ponder/query/PonderAnswerQuery.php b/src/applications/ponder/query/PonderAnswerQuery.php
index 1b5c66a10c..0fe61bc9e1 100644
--- a/src/applications/ponder/query/PonderAnswerQuery.php
+++ b/src/applications/ponder/query/PonderAnswerQuery.php
@@ -1,125 +1,125 @@
<?php
final class PonderAnswerQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $questionIDs;
private $needViewerVotes;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
public function withQuestionIDs(array $ids) {
$this->questionIDs = $ids;
return $this;
}
public function needViewerVotes($need_viewer_votes) {
$this->needViewerVotes = $need_viewer_votes;
return $this;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function loadPage() {
$answer = new PonderAnswer();
$conn_r = $answer->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT a.* FROM %T a %Q %Q %Q',
$answer->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $answer->loadAllFromArray($data);
}
protected function willFilterPage(array $answers) {
$questions = id(new PonderQuestionQuery())
->setViewer($this->getViewer())
->withIDs(mpull($answers, 'getQuestionID'))
->execute();
foreach ($answers as $key => $answer) {
$question = idx($questions, $answer->getQuestionID());
if (!$question) {
unset($answers[$key]);
continue;
}
$answer->attachQuestion($question);
}
if ($this->needViewerVotes) {
$viewer_phid = $this->getViewer()->getPHID();
$etype = PonderAnswerHasVotingUserEdgeType::EDGECONST;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($answers, 'getPHID'))
->withDestinationPHIDs(array($viewer_phid))
->withEdgeTypes(array($etype))
->needEdgeData(true)
->execute();
foreach ($answers as $answer) {
$user_edge = idx(
$edges[$answer->getPHID()][$etype],
$viewer_phid,
array());
$answer->attachUserVote($viewer_phid, idx($user_edge, 'data', 0));
}
}
return $answers;
}
public function getQueryApplicationClass() {
return 'PhabricatorPonderApplication';
}
}
diff --git a/src/applications/ponder/query/PonderQuestionQuery.php b/src/applications/ponder/query/PonderQuestionQuery.php
index 9cb8c81d40..51081b3203 100644
--- a/src/applications/ponder/query/PonderQuestionQuery.php
+++ b/src/applications/ponder/query/PonderQuestionQuery.php
@@ -1,182 +1,182 @@
<?php
final class PonderQuestionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $answererPHIDs;
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
const STATUS_CLOSED = 'status-closed';
private $needAnswers;
private $needViewerVotes;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withAnswererPHIDs(array $phids) {
$this->answererPHIDs = $phids;
return $this;
}
public function needAnswers($need_answers) {
$this->needAnswers = $need_answers;
return $this;
}
public function needViewerVotes($need_viewer_votes) {
$this->needViewerVotes = $need_viewer_votes;
return $this;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'q.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'q.phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'q.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->status) {
switch ($this->status) {
case self::STATUS_ANY:
break;
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'q.status = %d',
PonderQuestionStatus::STATUS_OPEN);
break;
case self::STATUS_CLOSED:
$where[] = qsprintf(
$conn_r,
'q.status = %d',
PonderQuestionStatus::STATUS_CLOSED);
break;
default:
throw new Exception("Unknown status query '{$this->status}'!");
}
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function loadPage() {
$question = new PonderQuestion();
$conn_r = $question->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT q.* FROM %T q %Q %Q %Q %Q',
$question->getTableName(),
$this->buildJoinsClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $question->loadAllFromArray($data);
}
protected function willFilterPage(array $questions) {
if ($this->needAnswers) {
$aquery = id(new PonderAnswerQuery())
->setViewer($this->getViewer())
->setOrderVector(array('-id'))
->withQuestionIDs(mpull($questions, 'getID'));
if ($this->needViewerVotes) {
$aquery->needViewerVotes($this->needViewerVotes);
}
$answers = $aquery->execute();
$answers = mgroup($answers, 'getQuestionID');
foreach ($questions as $question) {
$question_answers = idx($answers, $question->getID(), array());
$question->attachAnswers(mpull($question_answers, null, 'getPHID'));
}
}
if ($this->needViewerVotes) {
$viewer_phid = $this->getViewer()->getPHID();
$etype = PonderQuestionHasVotingUserEdgeType::EDGECONST;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($questions, 'getPHID'))
->withDestinationPHIDs(array($viewer_phid))
->withEdgeTypes(array($etype))
->needEdgeData(true)
->execute();
foreach ($questions as $question) {
$user_edge = idx(
$edges[$question->getPHID()][$etype],
$viewer_phid,
array());
$question->attachUserVote($viewer_phid, idx($user_edge, 'data', 0));
}
}
return $questions;
}
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
if ($this->answererPHIDs) {
$answer_table = new PonderAnswer();
$joins[] = qsprintf(
$conn_r,
'JOIN %T a ON a.questionID = q.id AND a.authorPHID IN (%Ls)',
$answer_table->getTableName(),
$this->answererPHIDs);
}
return implode(' ', $joins);
}
public function getQueryApplicationClass() {
return 'PhabricatorPonderApplication';
}
}
diff --git a/src/applications/project/query/PhabricatorProjectColumnPositionQuery.php b/src/applications/project/query/PhabricatorProjectColumnPositionQuery.php
index 87bd87ffd3..3348b4054d 100644
--- a/src/applications/project/query/PhabricatorProjectColumnPositionQuery.php
+++ b/src/applications/project/query/PhabricatorProjectColumnPositionQuery.php
@@ -1,306 +1,306 @@
<?php
final class PhabricatorProjectColumnPositionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $boardPHIDs;
private $objectPHIDs;
private $columns;
private $needColumns;
private $skipImplicitCreate;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withBoardPHIDs(array $board_phids) {
$this->boardPHIDs = $board_phids;
return $this;
}
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
/**
* Find objects in specific columns.
*
* NOTE: Using this method activates logic which constructs virtual
* column positions for objects not in any column, if you pass a default
* column. Normally these results are not returned.
*
* @param list<PhabricatorProjectColumn> Columns to look for objects in.
* @return this
*/
public function withColumns(array $columns) {
assert_instances_of($columns, 'PhabricatorProjectColumn');
$this->columns = $columns;
return $this;
}
public function needColumns($need_columns) {
$this->needColumns = true;
return $this;
}
/**
* Skip implicit creation of column positions which are implied but do not
* yet exist.
*
* This is primarily useful internally.
*
* @param bool True to skip implicit creation of column positions.
* @return this
*/
public function setSkipImplicitCreate($skip) {
$this->skipImplicitCreate = $skip;
return $this;
}
// NOTE: For now, boards are always attached to projects. However, they might
// not be in the future. This generalization just anticipates a future where
// we let other types of objects (like users) have boards, or let boards
// contain other types of objects.
private function newPositionObject() {
return new PhabricatorProjectColumnPosition();
}
private function newColumnQuery() {
return new PhabricatorProjectColumnQuery();
}
private function getBoardMembershipEdgeTypes() {
return array(
PhabricatorProjectProjectHasObjectEdgeType::EDGECONST,
);
}
private function getBoardMembershipPHIDTypes() {
return array(
ManiphestTaskPHIDType::TYPECONST,
);
}
protected function loadPage() {
$table = $this->newPositionObject();
$conn_r = $table->establishConnection('r');
// We're going to find results by combining two queries: one query finds
// objects on a board column, while the other query finds objects not on
// any board column and virtually puts them on the default column.
$unions = array();
// First, find all the stuff that's actually on a column.
$unions[] = qsprintf(
$conn_r,
'SELECT * FROM %T %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r));
// If we have a default column, find all the stuff that's not in any
// column and put it in the default column.
$must_type_filter = false;
if ($this->columns && !$this->skipImplicitCreate) {
$default_map = array();
foreach ($this->columns as $column) {
if ($column->isDefaultColumn()) {
$default_map[$column->getProjectPHID()] = $column->getPHID();
}
}
if ($default_map) {
$where = array();
// Find the edges attached to the boards we have default columns for.
$where[] = qsprintf(
$conn_r,
'e.src IN (%Ls)',
array_keys($default_map));
// Find only edges which describe a board relationship.
$where[] = qsprintf(
$conn_r,
'e.type IN (%Ld)',
$this->getBoardMembershipEdgeTypes());
if ($this->boardPHIDs !== null) {
// This should normally be redundant, but construct it anyway if
// the caller has told us to.
$where[] = qsprintf(
$conn_r,
'e.src IN (%Ls)',
$this->boardPHIDs);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'e.dst IN (%Ls)',
$this->objectPHIDs);
}
$where[] = qsprintf(
$conn_r,
'p.id IS NULL');
$where = $this->formatWhereClause($where);
$unions[] = qsprintf(
$conn_r,
'SELECT NULL id, e.src boardPHID, NULL columnPHID, e.dst objectPHID,
0 sequence
FROM %T e LEFT JOIN %T p
ON e.src = p.boardPHID AND e.dst = p.objectPHID
%Q',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
$table->getTableName(),
$where);
$must_type_filter = true;
}
}
$data = queryfx_all(
$conn_r,
'%Q %Q %Q',
implode(' UNION ALL ', $unions),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
// If we've picked up objects not in any column, we need to filter out any
// matched objects which have the wrong edge type.
if ($must_type_filter) {
$allowed_types = array_fuse($this->getBoardMembershipPHIDTypes());
foreach ($data as $id => $row) {
if ($row['columnPHID'] === null) {
$object_phid = $row['objectPHID'];
if (empty($allowed_types[phid_get_type($object_phid)])) {
unset($data[$id]);
}
}
}
}
$positions = $table->loadAllFromArray($data);
// Find the implied positions which don't exist yet. If there are any,
// we're going to create them.
$create = array();
foreach ($positions as $position) {
if ($position->getColumnPHID() === null) {
$column_phid = idx($default_map, $position->getBoardPHID());
$position->setColumnPHID($column_phid);
$create[] = $position;
}
}
if ($create) {
// If we're adding several objects to a column, insert the column
// position objects in object ID order. This means that newly added
// objects float to the top, and when a group of newly added objects
// float up at the same time, the most recently created ones end up
// highest in the list.
$objects = id(new PhabricatorObjectQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs(mpull($create, 'getObjectPHID'))
->execute();
$objects = mpull($objects, null, 'getPHID');
$objects = msort($objects, 'getID');
$create = mgroup($create, 'getObjectPHID');
$create = array_select_keys($create, array_keys($objects)) + $create;
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
foreach ($create as $object_phid => $create_positions) {
foreach ($create_positions as $create_position) {
$create_position->save();
}
}
unset($unguarded);
}
return $positions;
}
protected function willFilterPage(array $page) {
if ($this->needColumns) {
$column_phids = mpull($page, 'getColumnPHID');
$columns = $this->newColumnQuery()
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($column_phids)
->execute();
$columns = mpull($columns, null, 'getPHID');
foreach ($page as $key => $position) {
$column = idx($columns, $position->getColumnPHID());
if (!$column) {
unset($page[$key]);
continue;
}
$position->attachColumn($column);
}
}
return $page;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->boardPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'boardPHID IN (%Ls)',
$this->boardPHIDs);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->columns !== null) {
$where[] = qsprintf(
$conn_r,
'columnPHID IN (%Ls)',
mpull($this->columns, 'getPHID'));
}
// NOTE: Explicitly not building the paging clause here, since it won't
// work with the UNION.
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorProjectApplication';
}
}
diff --git a/src/applications/project/query/PhabricatorProjectColumnQuery.php b/src/applications/project/query/PhabricatorProjectColumnQuery.php
index d369161fe3..c486968070 100644
--- a/src/applications/project/query/PhabricatorProjectColumnQuery.php
+++ b/src/applications/project/query/PhabricatorProjectColumnQuery.php
@@ -1,112 +1,112 @@
<?php
final class PhabricatorProjectColumnQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $projectPHIDs;
private $statuses;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withProjectPHIDs(array $project_phids) {
$this->projectPHIDs = $project_phids;
return $this;
}
public function withStatuses(array $status) {
$this->statuses = $status;
return $this;
}
protected function loadPage() {
$table = new PhabricatorProjectColumn();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $page) {
$projects = array();
$project_phids = array_filter(mpull($page, 'getProjectPHID'));
if ($project_phids) {
$projects = id(new PhabricatorProjectQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($project_phids)
->execute();
$projects = mpull($projects, null, 'getPHID');
}
foreach ($page as $key => $column) {
$phid = $column->getProjectPHID();
$project = idx($projects, $phid);
if (!$project) {
unset($page[$key]);
continue;
}
$column->attachProject($project);
}
return $page;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->projectPHIDs) {
$where[] = qsprintf(
$conn_r,
'projectPHID IN (%Ls)',
$this->projectPHIDs);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ld)',
$this->statuses);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorProjectApplication';
}
}
diff --git a/src/applications/project/query/PhabricatorProjectQuery.php b/src/applications/project/query/PhabricatorProjectQuery.php
index 4b6ad566a7..f743be7295 100644
--- a/src/applications/project/query/PhabricatorProjectQuery.php
+++ b/src/applications/project/query/PhabricatorProjectQuery.php
@@ -1,393 +1,393 @@
<?php
final class PhabricatorProjectQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $memberPHIDs;
private $slugs;
private $phrictionSlugs;
private $names;
private $nameTokens;
private $icons;
private $colors;
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
const STATUS_CLOSED = 'status-closed';
const STATUS_ACTIVE = 'status-active';
const STATUS_ARCHIVED = 'status-archived';
private $needSlugs;
private $needMembers;
private $needWatchers;
private $needImages;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withMemberPHIDs(array $member_phids) {
$this->memberPHIDs = $member_phids;
return $this;
}
public function withSlugs(array $slugs) {
$this->slugs = $slugs;
return $this;
}
public function withPhrictionSlugs(array $slugs) {
$this->phrictionSlugs = $slugs;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function withNameTokens(array $tokens) {
$this->nameTokens = array_values($tokens);
return $this;
}
public function withIcons(array $icons) {
$this->icons = $icons;
return $this;
}
public function withColors(array $colors) {
$this->colors = $colors;
return $this;
}
public function needMembers($need_members) {
$this->needMembers = $need_members;
return $this;
}
public function needWatchers($need_watchers) {
$this->needWatchers = $need_watchers;
return $this;
}
public function needImages($need_images) {
$this->needImages = $need_images;
return $this;
}
public function needSlugs($need_slugs) {
$this->needSlugs = $need_slugs;
return $this;
}
protected function getDefaultOrderVector() {
return array('name');
}
public function getOrderableColumns() {
return array(
'name' => array(
'table' => $this->getPrimaryTableAlias(),
'column' => 'name',
'reverse' => true,
'type' => 'string',
'unique' => true,
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
$project = $this->loadCursorObject($cursor);
return array(
'name' => $project->getName(),
);
}
protected function loadPage() {
$table = new PhabricatorProject();
$conn_r = $table->establishConnection('r');
// NOTE: Because visibility checks for projects depend on whether or not
// the user is a project member, we always load their membership. If we're
// loading all members anyway we can piggyback on that; otherwise we
// do an explicit join.
$select_clause = '';
if (!$this->needMembers) {
$select_clause = ', vm.dst viewerIsMember';
}
$data = queryfx_all(
$conn_r,
'SELECT p.* %Q FROM %T p %Q %Q %Q %Q %Q',
$select_clause,
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$projects = $table->loadAllFromArray($data);
if ($projects) {
$viewer_phid = $this->getViewer()->getPHID();
$project_phids = mpull($projects, 'getPHID');
$member_type = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST;
$watcher_type = PhabricatorObjectHasWatcherEdgeType::EDGECONST;
$need_edge_types = array();
if ($this->needMembers) {
$need_edge_types[] = $member_type;
} else {
foreach ($data as $row) {
$projects[$row['id']]->setIsUserMember(
$viewer_phid,
($row['viewerIsMember'] !== null));
}
}
if ($this->needWatchers) {
$need_edge_types[] = $watcher_type;
}
if ($need_edge_types) {
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs($project_phids)
->withEdgeTypes($need_edge_types)
->execute();
if ($this->needMembers) {
foreach ($projects as $project) {
$phid = $project->getPHID();
$project->attachMemberPHIDs(
array_keys($edges[$phid][$member_type]));
$project->setIsUserMember(
$viewer_phid,
isset($edges[$phid][$member_type][$viewer_phid]));
}
}
if ($this->needWatchers) {
foreach ($projects as $project) {
$phid = $project->getPHID();
$project->attachWatcherPHIDs(
array_keys($edges[$phid][$watcher_type]));
$project->setIsUserWatcher(
$viewer_phid,
isset($edges[$phid][$watcher_type][$viewer_phid]));
}
}
}
}
return $projects;
}
protected function didFilterPage(array $projects) {
if ($this->needImages) {
$default = null;
$file_phids = mpull($projects, 'getProfileImagePHID');
$files = id(new PhabricatorFileQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
foreach ($projects as $project) {
$file = idx($files, $project->getProfileImagePHID());
if (!$file) {
if (!$default) {
$default = PhabricatorFile::loadBuiltin(
$this->getViewer(),
'project.png');
}
$file = $default;
}
$project->attachProfileImageFile($file);
}
}
if ($this->needSlugs) {
$slugs = id(new PhabricatorProjectSlug())
->loadAllWhere(
'projectPHID IN (%Ls)',
mpull($projects, 'getPHID'));
$slugs = mgroup($slugs, 'getProjectPHID');
foreach ($projects as $project) {
$project_slugs = idx($slugs, $project->getPHID(), array());
$project->attachSlugs($project_slugs);
}
}
return $projects;
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->status != self::STATUS_ANY) {
switch ($this->status) {
case self::STATUS_OPEN:
case self::STATUS_ACTIVE:
$filter = array(
PhabricatorProjectStatus::STATUS_ACTIVE,
);
break;
case self::STATUS_CLOSED:
case self::STATUS_ARCHIVED:
$filter = array(
PhabricatorProjectStatus::STATUS_ARCHIVED,
);
break;
default:
throw new Exception(
"Unknown project status '{$this->status}'!");
}
$where[] = qsprintf(
$conn_r,
'status IN (%Ld)',
$filter);
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->memberPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'e.dst IN (%Ls)',
$this->memberPHIDs);
}
if ($this->slugs !== null) {
$where[] = qsprintf(
$conn_r,
'slug.slug IN (%Ls)',
$this->slugs);
}
if ($this->phrictionSlugs !== null) {
$where[] = qsprintf(
$conn_r,
'phrictionSlug IN (%Ls)',
$this->phrictionSlugs);
}
if ($this->names !== null) {
$where[] = qsprintf(
$conn_r,
'name IN (%Ls)',
$this->names);
}
if ($this->icons !== null) {
$where[] = qsprintf(
$conn_r,
'icon IN (%Ls)',
$this->icons);
}
if ($this->colors !== null) {
$where[] = qsprintf(
$conn_r,
'color IN (%Ls)',
$this->colors);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function buildGroupClause($conn_r) {
if ($this->memberPHIDs || $this->nameTokens) {
return 'GROUP BY p.id';
} else {
return $this->buildApplicationSearchGroupClause($conn_r);
}
}
private function buildJoinClause($conn_r) {
$joins = array();
if (!$this->needMembers !== null) {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T vm ON vm.src = p.phid AND vm.type = %d AND vm.dst = %s',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
PhabricatorProjectProjectHasMemberEdgeType::EDGECONST,
$this->getViewer()->getPHID());
}
if ($this->memberPHIDs !== null) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T e ON e.src = p.phid AND e.type = %d',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
PhabricatorProjectProjectHasMemberEdgeType::EDGECONST);
}
if ($this->slugs !== null) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T slug on slug.projectPHID = p.phid',
id(new PhabricatorProjectSlug())->getTableName());
}
if ($this->nameTokens !== null) {
foreach ($this->nameTokens as $key => $token) {
$token_table = 'token_'.$key;
$joins[] = qsprintf(
$conn_r,
'JOIN %T %T ON %T.projectID = p.id AND %T.token LIKE %>',
PhabricatorProject::TABLE_DATASOURCE_TOKEN,
$token_table,
$token_table,
$token_table,
$token);
}
}
$joins[] = $this->buildApplicationSearchJoinClause($conn_r);
return implode(' ', $joins);
}
public function getQueryApplicationClass() {
return 'PhabricatorProjectApplication';
}
protected function getPrimaryTableAlias() {
return 'p';
}
}
diff --git a/src/applications/releeph/query/ReleephBranchQuery.php b/src/applications/releeph/query/ReleephBranchQuery.php
index 43a600fa2d..201c2653d0 100644
--- a/src/applications/releeph/query/ReleephBranchQuery.php
+++ b/src/applications/releeph/query/ReleephBranchQuery.php
@@ -1,152 +1,152 @@
<?php
final class ReleephBranchQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $productPHIDs;
private $productIDs;
const STATUS_ALL = 'status-all';
const STATUS_OPEN = 'status-open';
private $status = self::STATUS_ALL;
private $needCutPointCommits;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function needCutPointCommits($need_commits) {
$this->needCutPointCommits = $need_commits;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withProductPHIDs($product_phids) {
$this->productPHIDs = $product_phids;
return $this;
}
protected function loadPage() {
$table = new ReleephBranch();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willExecute() {
if ($this->productPHIDs !== null) {
$products = id(new ReleephProductQuery())
->setViewer($this->getViewer())
->withPHIDs($this->productPHIDs)
->execute();
if (!$products) {
throw new PhabricatorEmptyQueryException();
}
$this->productIDs = mpull($products, 'getID');
}
}
protected function willFilterPage(array $branches) {
$project_ids = mpull($branches, 'getReleephProjectID');
$projects = id(new ReleephProductQuery())
->withIDs($project_ids)
->setViewer($this->getViewer())
->execute();
foreach ($branches as $key => $branch) {
$project_id = $project_ids[$key];
if (isset($projects[$project_id])) {
$branch->attachProject($projects[$project_id]);
} else {
unset($branches[$key]);
}
}
if ($this->needCutPointCommits) {
$commit_phids = mpull($branches, 'getCutPointCommitPHID');
$commits = id(new DiffusionCommitQuery())
->setViewer($this->getViewer())
->withPHIDs($commit_phids)
->execute();
$commits = mpull($commits, null, 'getPHID');
foreach ($branches as $branch) {
$commit = idx($commits, $branch->getCutPointCommitPHID());
$branch->attachCutPointCommit($commit);
}
}
return $branches;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->productIDs !== null) {
$where[] = qsprintf(
$conn_r,
'releephProjectID IN (%Ld)',
$this->productIDs);
}
$status = $this->status;
switch ($status) {
case self::STATUS_ALL:
break;
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'isActive = 1');
break;
default:
throw new Exception("Unknown status constant '{$status}'!");
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorReleephApplication';
}
}
diff --git a/src/applications/releeph/query/ReleephProductQuery.php b/src/applications/releeph/query/ReleephProductQuery.php
index 2562004a06..6fe2b90db3 100644
--- a/src/applications/releeph/query/ReleephProductQuery.php
+++ b/src/applications/releeph/query/ReleephProductQuery.php
@@ -1,174 +1,174 @@
<?php
final class ReleephProductQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $active;
private $ids;
private $phids;
private $repositoryPHIDs;
private $needArcanistProjects;
const ORDER_ID = 'order-id';
const ORDER_NAME = 'order-name';
public function withActive($active) {
$this->active = $active;
return $this;
}
public function setOrder($order) {
switch ($order) {
case self::ORDER_ID:
$this->setOrderVector(array('id'));
break;
case self::ORDER_NAME:
$this->setOrderVector(array('name'));
break;
default:
throw new Exception(pht('Order "%s" not supported.', $order));
}
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
public function needArcanistProjects($need) {
$this->needArcanistProjects = $need;
return $this;
}
protected function loadPage() {
$table = new ReleephProject();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($rows);
}
protected function willFilterPage(array $projects) {
assert_instances_of($projects, 'ReleephProject');
$repository_phids = mpull($projects, 'getRepositoryPHID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
foreach ($projects as $key => $project) {
$repo = idx($repositories, $project->getRepositoryPHID());
if (!$repo) {
unset($projects[$key]);
continue;
}
$project->attachRepository($repo);
}
return $projects;
}
protected function didFilterPage(array $products) {
if ($this->needArcanistProjects) {
$project_ids = array_filter(mpull($products, 'getArcanistProjectID'));
if ($project_ids) {
$projects = id(new PhabricatorRepositoryArcanistProject())
->loadAllWhere('id IN (%Ld)', $project_ids);
$projects = mpull($projects, null, 'getID');
} else {
$projects = array();
}
foreach ($products as $product) {
$project_id = $product->getArcanistProjectID();
$project = idx($projects, $project_id);
$product->attachArcanistProject($project);
}
}
return $products;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->active !== null) {
$where[] = qsprintf(
$conn_r,
'isActive = %d',
(int)$this->active);
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ls)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getOrderableColumns() {
return parent::getOrderableColumns() + array(
'name' => array(
'column' => 'name',
'unique' => true,
'reverse' => true,
'type' => 'string',
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
$product = $this->loadCursorObject($cursor);
return array(
'id' => $product->getID(),
'name' => $product->getName(),
);
}
public function getQueryApplicationClass() {
return 'PhabricatorReleephApplication';
}
}
diff --git a/src/applications/releeph/query/ReleephRequestQuery.php b/src/applications/releeph/query/ReleephRequestQuery.php
index 84d35d288a..1a5965ad43 100644
--- a/src/applications/releeph/query/ReleephRequestQuery.php
+++ b/src/applications/releeph/query/ReleephRequestQuery.php
@@ -1,247 +1,247 @@
<?php
final class ReleephRequestQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $requestedCommitPHIDs;
private $ids;
private $phids;
private $severities;
private $requestorPHIDs;
private $branchIDs;
private $requestedObjectPHIDs;
const STATUS_ALL = 'status-all';
const STATUS_OPEN = 'status-open';
const STATUS_REQUESTED = 'status-requested';
const STATUS_NEEDS_PULL = 'status-needs-pull';
const STATUS_REJECTED = 'status-rejected';
const STATUS_ABANDONED = 'status-abandoned';
const STATUS_PULLED = 'status-pulled';
const STATUS_NEEDS_REVERT = 'status-needs-revert';
const STATUS_REVERTED = 'status-reverted';
private $status = self::STATUS_ALL;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBranchIDs(array $branch_ids) {
$this->branchIDs = $branch_ids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withRequestedCommitPHIDs(array $requested_commit_phids) {
$this->requestedCommitPHIDs = $requested_commit_phids;
return $this;
}
public function withRequestorPHIDs(array $phids) {
$this->requestorPHIDs = $phids;
return $this;
}
public function withSeverities(array $severities) {
$this->severities = $severities;
return $this;
}
public function withRequestedObjectPHIDs(array $phids) {
$this->requestedObjectPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new ReleephRequest();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $requests) {
// Load requested objects: you must be able to see an object to see
// requests for it.
$object_phids = mpull($requests, 'getRequestedObjectPHID');
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($object_phids)
->execute();
foreach ($requests as $key => $request) {
$object_phid = $request->getRequestedObjectPHID();
$object = idx($objects, $object_phid);
if (!$object) {
unset($requests[$key]);
continue;
}
$request->attachRequestedObject($object);
}
if ($this->severities) {
$severities = array_fuse($this->severities);
foreach ($requests as $key => $request) {
// NOTE: Facebook uses a custom field here.
if (ReleephDefaultFieldSelector::isFacebook()) {
$severity = $request->getDetail('severity');
} else {
$severity = $request->getDetail('releeph:severity');
}
if (empty($severities[$severity])) {
unset($requests[$key]);
}
}
}
$branch_ids = array_unique(mpull($requests, 'getBranchID'));
$branches = id(new ReleephBranchQuery())
->withIDs($branch_ids)
->setViewer($this->getViewer())
->execute();
$branches = mpull($branches, null, 'getID');
foreach ($requests as $key => $request) {
$branch = idx($branches, $request->getBranchID());
if (!$branch) {
unset($requests[$key]);
continue;
}
$request->attachBranch($branch);
}
// TODO: These should be serviced by the query, but are not currently
// denormalized anywhere. For now, filter them here instead. Note that
// we must perform this filtering *after* querying and attaching branches,
// because request status depends on the product.
$keep_status = array_fuse($this->getKeepStatusConstants());
if ($keep_status) {
foreach ($requests as $key => $request) {
if (empty($keep_status[$request->getStatus()])) {
unset($requests[$key]);
}
}
}
return $requests;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->branchIDs !== null) {
$where[] = qsprintf(
$conn_r,
'branchID IN (%Ld)',
$this->branchIDs);
}
if ($this->requestedCommitPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'requestCommitPHID IN (%Ls)',
$this->requestedCommitPHIDs);
}
if ($this->requestorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'requestUserPHID IN (%Ls)',
$this->requestorPHIDs);
}
if ($this->requestedObjectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'requestedObjectPHID IN (%Ls)',
$this->requestedObjectPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function getKeepStatusConstants() {
switch ($this->status) {
case self::STATUS_ALL:
return array();
case self::STATUS_OPEN:
return array(
ReleephRequestStatus::STATUS_REQUESTED,
ReleephRequestStatus::STATUS_NEEDS_PICK,
ReleephRequestStatus::STATUS_NEEDS_REVERT,
);
case self::STATUS_REQUESTED:
return array(
ReleephRequestStatus::STATUS_REQUESTED,
);
case self::STATUS_NEEDS_PULL:
return array(
ReleephRequestStatus::STATUS_NEEDS_PICK,
);
case self::STATUS_REJECTED:
return array(
ReleephRequestStatus::STATUS_REJECTED,
);
case self::STATUS_ABANDONED:
return array(
ReleephRequestStatus::STATUS_ABANDONED,
);
case self::STATUS_PULLED:
return array(
ReleephRequestStatus::STATUS_PICKED,
);
case self::STATUS_NEEDS_REVERT:
return array(
ReleephRequestStatus::NEEDS_REVERT,
);
case self::STATUS_REVERTED:
return array(
ReleephRequestStatus::REVERTED,
);
default:
throw new Exception("Unknown status '{$this->status}'!");
}
}
public function getQueryApplicationClass() {
return 'PhabricatorReleephApplication';
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php b/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
index 5cbc730075..901f58cbdf 100644
--- a/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
@@ -1,87 +1,87 @@
<?php
final class PhabricatorRepositoryArcanistProjectQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $needRepositories;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function needRepositories($need_repositories) {
$this->needRepositories = $need_repositories;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryArcanistProject();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $projects) {
assert_instances_of($projects, 'PhabricatorRepositoryArcanistProject');
if ($this->needRepositories) {
$repository_ids = mpull($projects, 'getRepositoryID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIDs($repository_ids)
->execute();
foreach ($projects as $project) {
$repo = idx($repositories, $project->getRepositoryID());
$project->attachRepository($repo);
}
}
return $projects;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
// TODO: Diffusion? Differential?
return null;
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php b/src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php
index f6e7d22950..84c5ef74ce 100644
--- a/src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php
@@ -1,99 +1,99 @@
<?php
final class PhabricatorRepositoryMirrorQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $repositoryPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryMirror();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $mirrors) {
assert_instances_of($mirrors, 'PhabricatorRepositoryMirror');
$repository_phids = mpull($mirrors, 'getRepositoryPHID');
if ($repository_phids) {
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
} else {
$repositories = array();
}
foreach ($mirrors as $key => $mirror) {
$phid = $mirror->getRepositoryPHID();
if (empty($repositories[$phid])) {
unset($mirrors[$key]);
continue;
}
$mirror->attachRepository($repositories[$phid]);
}
return $mirrors;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryPushEventQuery.php b/src/applications/repository/query/PhabricatorRepositoryPushEventQuery.php
index 14b4e4d596..a3bed7abd3 100644
--- a/src/applications/repository/query/PhabricatorRepositoryPushEventQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryPushEventQuery.php
@@ -1,131 +1,131 @@
<?php
final class PhabricatorRepositoryPushEventQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $repositoryPHIDs;
private $pusherPHIDs;
private $needLogs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
public function withPusherPHIDs(array $pusher_phids) {
$this->pusherPHIDs = $pusher_phids;
return $this;
}
public function needLogs($need_logs) {
$this->needLogs = $need_logs;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryPushEvent();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $events) {
$repository_phids = mpull($events, 'getRepositoryPHID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
foreach ($events as $key => $event) {
$phid = $event->getRepositoryPHID();
if (empty($repositories[$phid])) {
unset($events[$key]);
continue;
}
$event->attachRepository($repositories[$phid]);
}
return $events;
}
protected function didFilterPage(array $events) {
$phids = mpull($events, 'getPHID');
if ($this->needLogs) {
$logs = id(new PhabricatorRepositoryPushLogQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPushEventPHIDs($phids)
->execute();
$logs = mgroup($logs, 'getPushEventPHID');
foreach ($events as $key => $event) {
$event_logs = idx($logs, $event->getPHID(), array());
$event->attachLogs($event_logs);
}
}
return $events;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->pusherPHIDs) {
$where[] = qsprintf(
$conn_r,
'pusherPHID in (%Ls)',
$this->pusherPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php b/src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php
index 7812f77abd..94a0b6922e 100644
--- a/src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php
@@ -1,146 +1,146 @@
<?php
final class PhabricatorRepositoryPushLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $repositoryPHIDs;
private $pusherPHIDs;
private $refTypes;
private $newRefs;
private $pushEventPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
public function withPusherPHIDs(array $pusher_phids) {
$this->pusherPHIDs = $pusher_phids;
return $this;
}
public function withRefTypes(array $ref_types) {
$this->refTypes = $ref_types;
return $this;
}
public function withNewRefs(array $new_refs) {
$this->newRefs = $new_refs;
return $this;
}
public function withPushEventPHIDs(array $phids) {
$this->pushEventPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryPushLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $logs) {
$event_phids = mpull($logs, 'getPushEventPHID');
$events = id(new PhabricatorObjectQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($event_phids)
->execute();
$events = mpull($events, null, 'getPHID');
foreach ($logs as $key => $log) {
$event = idx($events, $log->getPushEventPHID());
if (!$event) {
unset($logs[$key]);
continue;
}
$log->attachPushEvent($event);
}
return $logs;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->pusherPHIDs) {
$where[] = qsprintf(
$conn_r,
'pusherPHID in (%Ls)',
$this->pusherPHIDs);
}
if ($this->pushEventPHIDs) {
$where[] = qsprintf(
$conn_r,
'pushEventPHID in (%Ls)',
$this->pushEventPHIDs);
}
if ($this->refTypes) {
$where[] = qsprintf(
$conn_r,
'refType IN (%Ls)',
$this->refTypes);
}
if ($this->newRefs) {
$where[] = qsprintf(
$conn_r,
'refNew IN (%Ls)',
$this->newRefs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryQuery.php b/src/applications/repository/query/PhabricatorRepositoryQuery.php
index 1b4e90fb22..d9ea26433f 100644
--- a/src/applications/repository/query/PhabricatorRepositoryQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryQuery.php
@@ -1,552 +1,552 @@
<?php
final class PhabricatorRepositoryQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $callsigns;
private $types;
private $uuids;
private $nameContains;
private $remoteURIs;
private $anyProjectPHIDs;
private $datasourceQuery;
private $numericIdentifiers;
private $callsignIdentifiers;
private $phidIdentifiers;
private $identifierMap;
const STATUS_OPEN = 'status-open';
const STATUS_CLOSED = 'status-closed';
const STATUS_ALL = 'status-all';
private $status = self::STATUS_ALL;
const HOSTED_PHABRICATOR = 'hosted-phab';
const HOSTED_REMOTE = 'hosted-remote';
const HOSTED_ALL = 'hosted-all';
private $hosted = self::HOSTED_ALL;
private $needMostRecentCommits;
private $needCommitCounts;
private $needProjectPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCallsigns(array $callsigns) {
$this->callsigns = $callsigns;
return $this;
}
public function withIdentifiers(array $identifiers) {
$ids = array(); $callsigns = array(); $phids = array();
foreach ($identifiers as $identifier) {
if (ctype_digit($identifier)) {
$ids[$identifier] = $identifier;
} else {
$repository_type = PhabricatorRepositoryRepositoryPHIDType::TYPECONST;
if (phid_get_type($identifier) === $repository_type) {
$phids[$identifier] = $identifier;
} else {
$callsigns[$identifier] = $identifier;
}
}
}
$this->numericIdentifiers = $ids;
$this->callsignIdentifiers = $callsigns;
$this->phidIdentifiers = $phids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withHosted($hosted) {
$this->hosted = $hosted;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
public function withUUIDs(array $uuids) {
$this->uuids = $uuids;
return $this;
}
public function withNameContains($contains) {
$this->nameContains = $contains;
return $this;
}
public function withRemoteURIs(array $uris) {
$this->remoteURIs = $uris;
return $this;
}
public function withAnyProjects(array $projects) {
$this->anyProjectPHIDs = $projects;
return $this;
}
public function withDatasourceQuery($query) {
$this->datasourceQuery = $query;
return $this;
}
public function needCommitCounts($need_counts) {
$this->needCommitCounts = $need_counts;
return $this;
}
public function needMostRecentCommits($need_commits) {
$this->needMostRecentCommits = $need_commits;
return $this;
}
public function needProjectPHIDs($need_phids) {
$this->needProjectPHIDs = $need_phids;
return $this;
}
public function getBuiltinOrders() {
return array(
'committed' => array(
'vector' => array('committed', 'id'),
'name' => pht('Most Recent Commit'),
),
'name' => array(
'vector' => array('name', 'id'),
'name' => pht('Name'),
),
'callsign' => array(
'vector' => array('callsign'),
'name' => pht('Callsign'),
),
'size' => array(
'vector' => array('size', 'id'),
'name' => pht('Size'),
),
) + parent::getBuiltinOrders();
}
public function getIdentifierMap() {
if ($this->identifierMap === null) {
throw new Exception(
'You must execute() the query before accessing the identifier map.');
}
return $this->identifierMap;
}
protected function willExecute() {
$this->identifierMap = array();
}
protected function loadPage() {
$table = new PhabricatorRepository();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T r %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinsClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$repositories = $table->loadAllFromArray($data);
if ($this->needCommitCounts) {
$sizes = ipull($data, 'size', 'id');
foreach ($repositories as $id => $repository) {
$repository->attachCommitCount(nonempty($sizes[$id], 0));
}
}
if ($this->needMostRecentCommits) {
$commit_ids = ipull($data, 'lastCommitID', 'id');
$commit_ids = array_filter($commit_ids);
if ($commit_ids) {
$commits = id(new DiffusionCommitQuery())
->setViewer($this->getViewer())
->withIDs($commit_ids)
->execute();
} else {
$commits = array();
}
foreach ($repositories as $id => $repository) {
$commit = null;
if (idx($commit_ids, $id)) {
$commit = idx($commits, $commit_ids[$id]);
}
$repository->attachMostRecentCommit($commit);
}
}
return $repositories;
}
protected function willFilterPage(array $repositories) {
assert_instances_of($repositories, 'PhabricatorRepository');
// TODO: Denormalize repository status into the PhabricatorRepository
// table so we can do this filtering in the database.
foreach ($repositories as $key => $repo) {
$status = $this->status;
switch ($status) {
case self::STATUS_OPEN:
if (!$repo->isTracked()) {
unset($repositories[$key]);
}
break;
case self::STATUS_CLOSED:
if ($repo->isTracked()) {
unset($repositories[$key]);
}
break;
case self::STATUS_ALL:
break;
default:
throw new Exception("Unknown status '{$status}'!");
}
// TODO: This should also be denormalized.
$hosted = $this->hosted;
switch ($hosted) {
case self::HOSTED_PHABRICATOR:
if (!$repo->isHosted()) {
unset($repositories[$key]);
}
break;
case self::HOSTED_REMOTE:
if ($repo->isHosted()) {
unset($repositories[$key]);
}
break;
case self::HOSTED_ALL:
break;
default:
throw new Exception("Uknown hosted failed '${hosted}'!");
}
}
// TODO: Denormalize this, too.
if ($this->remoteURIs) {
$try_uris = $this->getNormalizedPaths();
$try_uris = array_fuse($try_uris);
foreach ($repositories as $key => $repository) {
if (!isset($try_uris[$repository->getNormalizedPath()])) {
unset($repositories[$key]);
}
}
}
// Build the identifierMap
if ($this->numericIdentifiers) {
foreach ($this->numericIdentifiers as $id) {
if (isset($repositories[$id])) {
$this->identifierMap[$id] = $repositories[$id];
}
}
}
if ($this->callsignIdentifiers) {
$repository_callsigns = mpull($repositories, null, 'getCallsign');
foreach ($this->callsignIdentifiers as $callsign) {
if (isset($repository_callsigns[$callsign])) {
$this->identifierMap[$callsign] = $repository_callsigns[$callsign];
}
}
}
if ($this->phidIdentifiers) {
$repository_phids = mpull($repositories, null, 'getPHID');
foreach ($this->phidIdentifiers as $phid) {
if (isset($repository_phids[$phid])) {
$this->identifierMap[$phid] = $repository_phids[$phid];
}
}
}
return $repositories;
}
protected function didFilterPage(array $repositories) {
if ($this->needProjectPHIDs) {
$type_project = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
$edge_query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($repositories, 'getPHID'))
->withEdgeTypes(array($type_project));
$edge_query->execute();
foreach ($repositories as $repository) {
$project_phids = $edge_query->getDestinationPHIDs(
array(
$repository->getPHID(),
));
$repository->attachProjectPHIDs($project_phids);
}
}
return $repositories;
}
protected function getPrimaryTableAlias() {
return 'r';
}
public function getOrderableColumns() {
return parent::getOrderableColumns() + array(
'committed' => array(
'table' => 's',
'column' => 'epoch',
'type' => 'int',
'null' => 'tail',
),
'callsign' => array(
'table' => 'r',
'column' => 'callsign',
'type' => 'string',
'unique' => true,
'reverse' => true,
),
'name' => array(
'table' => 'r',
'column' => 'name',
'type' => 'string',
'reverse' => true,
),
'size' => array(
'table' => 's',
'column' => 'size',
'type' => 'int',
'null' => 'tail',
),
);
}
protected function willExecuteCursorQuery(
PhabricatorCursorPagedPolicyAwareQuery $query) {
$vector = $this->getOrderVector();
if ($vector->containsKey('committed')) {
$query->needMostRecentCommits(true);
}
if ($vector->containsKey('size')) {
$query->needCommitCounts(true);
}
}
protected function getPagingValueMap($cursor, array $keys) {
$repository = $this->loadCursorObject($cursor);
$map = array(
'id' => $repository->getID(),
'callsign' => $repository->getCallsign(),
'name' => $repository->getName(),
);
foreach ($keys as $key) {
switch ($key) {
case 'committed':
$commit = $repository->getMostRecentCommit();
if ($commit) {
$map[$key] = $commit->getEpoch();
} else {
$map[$key] = null;
}
break;
case 'size':
$count = $repository->getCommitCount();
if ($count) {
$map[$key] = $count;
} else {
$map[$key] = null;
}
break;
}
}
return $map;
}
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
$join_summary_table = $this->needCommitCounts ||
$this->needMostRecentCommits;
$vector = $this->getOrderVector();
if ($vector->containsKey('committed') ||
$vector->containsKey('size')) {
$join_summary_table = true;
}
if ($join_summary_table) {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T s ON r.id = s.repositoryID',
PhabricatorRepository::TABLE_SUMMARY);
}
if ($this->anyProjectPHIDs) {
$joins[] = qsprintf(
$conn_r,
'JOIN edge e ON e.src = r.phid');
}
return implode(' ', $joins);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'r.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'r.phid IN (%Ls)',
$this->phids);
}
if ($this->callsigns) {
$where[] = qsprintf(
$conn_r,
'r.callsign IN (%Ls)',
$this->callsigns);
}
if ($this->numericIdentifiers ||
$this->callsignIdentifiers ||
$this->phidIdentifiers) {
$identifier_clause = array();
if ($this->numericIdentifiers) {
$identifier_clause[] = qsprintf(
$conn_r,
'r.id IN (%Ld)',
$this->numericIdentifiers);
}
if ($this->callsignIdentifiers) {
$identifier_clause[] = qsprintf(
$conn_r,
'r.callsign IN (%Ls)',
$this->callsignIdentifiers);
}
if ($this->phidIdentifiers) {
$identifier_clause[] = qsprintf(
$conn_r,
'r.phid IN (%Ls)',
$this->phidIdentifiers);
}
$where = array('('.implode(' OR ', $identifier_clause).')');
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'r.versionControlSystem IN (%Ls)',
$this->types);
}
if ($this->uuids) {
$where[] = qsprintf(
$conn_r,
'r.uuid IN (%Ls)',
$this->uuids);
}
if (strlen($this->nameContains)) {
$where[] = qsprintf(
$conn_r,
'name LIKE %~',
$this->nameContains);
}
if ($this->anyProjectPHIDs) {
$where[] = qsprintf(
$conn_r,
'e.dst IN (%Ls)',
$this->anyProjectPHIDs);
}
if (strlen($this->datasourceQuery)) {
// This handles having "rP" match callsigns starting with "P...".
$query = trim($this->datasourceQuery);
if (preg_match('/^r/', $query)) {
$callsign = substr($query, 1);
} else {
$callsign = $query;
}
$where[] = qsprintf(
$conn_r,
'r.name LIKE %> OR r.callsign LIKE %>',
$query,
$callsign);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
private function getNormalizedPaths() {
$normalized_uris = array();
// Since we don't know which type of repository this URI is in the general
// case, just generate all the normalizations. We could refine this in some
// cases: if the query specifies VCS types, or the URI is a git-style URI
// or an `svn+ssh` URI, we could deduce how to normalize it. However, this
// would be more complicated and it's not clear if it matters in practice.
foreach ($this->remoteURIs as $uri) {
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_GIT,
$uri);
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_SVN,
$uri);
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_MERCURIAL,
$uri);
}
return array_unique(mpull($normalized_uris, 'getNormalizedPath'));
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryRefCursorQuery.php b/src/applications/repository/query/PhabricatorRepositoryRefCursorQuery.php
index b75a8aa31e..c4c48c713c 100644
--- a/src/applications/repository/query/PhabricatorRepositoryRefCursorQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryRefCursorQuery.php
@@ -1,100 +1,100 @@
<?php
final class PhabricatorRepositoryRefCursorQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $repositoryPHIDs;
private $refTypes;
private $refNames;
public function withRepositoryPHIDs(array $phids) {
$this->repositoryPHIDs = $phids;
return $this;
}
public function withRefTypes(array $types) {
$this->refTypes = $types;
return $this;
}
public function withRefNames(array $names) {
$this->refNames = $names;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryRefCursor();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T r %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $refs) {
$repository_phids = mpull($refs, 'getRepositoryPHID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
foreach ($refs as $key => $ref) {
$repository = idx($repositories, $ref->getRepositoryPHID());
if (!$repository) {
unset($refs[$key]);
continue;
}
$ref->attachRepository($repository);
}
return $refs;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->repositoryPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->refTypes !== null) {
$where[] = qsprintf(
$conn_r,
'refType IN (%Ls)',
$this->refTypes);
}
if ($this->refNames !== null) {
$name_hashes = array();
foreach ($this->refNames as $name) {
$name_hashes[] = PhabricatorHash::digestForIndex($name);
}
$where[] = qsprintf(
$conn_r,
'refNameHash IN (%Ls)',
$name_hashes);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/search/query/PhabricatorNamedQueryQuery.php b/src/applications/search/query/PhabricatorNamedQueryQuery.php
index 413811771d..ce54ae9a84 100644
--- a/src/applications/search/query/PhabricatorNamedQueryQuery.php
+++ b/src/applications/search/query/PhabricatorNamedQueryQuery.php
@@ -1,86 +1,86 @@
<?php
final class PhabricatorNamedQueryQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $engineClassNames;
private $userPHIDs;
private $queryKeys;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withUserPHIDs(array $user_phids) {
$this->userPHIDs = $user_phids;
return $this;
}
public function withEngineClassNames(array $engine_class_names) {
$this->engineClassNames = $engine_class_names;
return $this;
}
public function withQueryKeys(array $query_keys) {
$this->queryKeys = $query_keys;
return $this;
}
protected function loadPage() {
$table = new PhabricatorNamedQuery();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->engineClassNames) {
$where[] = qsprintf(
$conn_r,
'engineClassName IN (%Ls)',
$this->engineClassNames);
}
if ($this->userPHIDs) {
$where[] = qsprintf(
$conn_r,
'userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->queryKeys) {
$where[] = qsprintf(
$conn_r,
'queryKey IN (%Ls)',
$this->queryKeys);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorSearchApplication';
}
}
diff --git a/src/applications/search/query/PhabricatorSavedQueryQuery.php b/src/applications/search/query/PhabricatorSavedQueryQuery.php
index 168342fdf2..623b001662 100644
--- a/src/applications/search/query/PhabricatorSavedQueryQuery.php
+++ b/src/applications/search/query/PhabricatorSavedQueryQuery.php
@@ -1,73 +1,73 @@
<?php
final class PhabricatorSavedQueryQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $engineClassNames;
private $queryKeys;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withEngineClassNames(array $engine_class_names) {
$this->engineClassNames = $engine_class_names;
return $this;
}
public function withQueryKeys(array $query_keys) {
$this->queryKeys = $query_keys;
return $this;
}
protected function loadPage() {
$table = new PhabricatorSavedQuery();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->engineClassNames !== null) {
$where[] = qsprintf(
$conn_r,
'engineClassName IN (%Ls)',
$this->engineClassNames);
}
if ($this->queryKeys !== null) {
$where[] = qsprintf(
$conn_r,
'queryKey IN (%Ls)',
$this->queryKeys);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorSearchApplication';
}
}
diff --git a/src/applications/slowvote/query/PhabricatorSlowvoteQuery.php b/src/applications/slowvote/query/PhabricatorSlowvoteQuery.php
index d17672b5e3..b7449d06a9 100644
--- a/src/applications/slowvote/query/PhabricatorSlowvoteQuery.php
+++ b/src/applications/slowvote/query/PhabricatorSlowvoteQuery.php
@@ -1,185 +1,185 @@
<?php
final class PhabricatorSlowvoteQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $withVotesByViewer;
private $isClosed;
private $needOptions;
private $needChoices;
private $needViewerChoices;
public function withIDs($ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs($phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs($author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withVotesByViewer($with_vote) {
$this->withVotesByViewer = $with_vote;
return $this;
}
public function withIsClosed($with_closed) {
$this->isClosed = $with_closed;
return $this;
}
public function needOptions($need_options) {
$this->needOptions = $need_options;
return $this;
}
public function needChoices($need_choices) {
$this->needChoices = $need_choices;
return $this;
}
public function needViewerChoices($need_viewer_choices) {
$this->needViewerChoices = $need_viewer_choices;
return $this;
}
protected function loadPage() {
$table = new PhabricatorSlowvotePoll();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT p.* FROM %T p %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinsClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $polls) {
assert_instances_of($polls, 'PhabricatorSlowvotePoll');
$ids = mpull($polls, 'getID');
$viewer = $this->getViewer();
if ($this->needOptions) {
$options = id(new PhabricatorSlowvoteOption())->loadAllWhere(
'pollID IN (%Ld)',
$ids);
$options = mgroup($options, 'getPollID');
foreach ($polls as $poll) {
$poll->attachOptions(idx($options, $poll->getID(), array()));
}
}
if ($this->needChoices) {
$choices = id(new PhabricatorSlowvoteChoice())->loadAllWhere(
'pollID IN (%Ld)',
$ids);
$choices = mgroup($choices, 'getPollID');
foreach ($polls as $poll) {
$poll->attachChoices(idx($choices, $poll->getID(), array()));
}
// If we need the viewer's choices, we can just fill them from the data
// we already loaded.
if ($this->needViewerChoices) {
foreach ($polls as $poll) {
$poll->attachViewerChoices(
$viewer,
idx(
mgroup($poll->getChoices(), 'getAuthorPHID'),
$viewer->getPHID(),
array()));
}
}
} else if ($this->needViewerChoices) {
$choices = id(new PhabricatorSlowvoteChoice())->loadAllWhere(
'pollID IN (%Ld) AND authorPHID = %s',
$ids,
$viewer->getPHID());
$choices = mgroup($choices, 'getPollID');
foreach ($polls as $poll) {
$poll->attachViewerChoices(
$viewer,
idx($choices, $poll->getID(), array()));
}
}
return $polls;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'p.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'p.phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'p.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->isClosed !== null) {
$where[] = qsprintf(
$conn_r,
'p.isClosed = %d',
(int)$this->isClosed);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
if ($this->withVotesByViewer) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T vv ON vv.pollID = p.id AND vv.authorPHID = %s',
id(new PhabricatorSlowvoteChoice())->getTableName(),
$this->getViewer()->getPHID());
}
return implode(' ', $joins);
}
protected function getPrimaryTableAlias() {
return 'p';
}
public function getQueryApplicationClass() {
return 'PhabricatorSlowvoteApplication';
}
}
diff --git a/src/applications/tokens/query/PhabricatorTokenCountQuery.php b/src/applications/tokens/query/PhabricatorTokenCountQuery.php
index cc333109a2..d942f22ce4 100644
--- a/src/applications/tokens/query/PhabricatorTokenCountQuery.php
+++ b/src/applications/tokens/query/PhabricatorTokenCountQuery.php
@@ -1,40 +1,40 @@
<?php
final class PhabricatorTokenCountQuery
extends PhabricatorOffsetPagedQuery {
private $objectPHIDs;
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
final public function execute() {
$table = new PhabricatorTokenCount();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT objectPHID, tokenCount FROM %T %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildLimitClause($conn_r));
return ipull($rows, 'tokenCount', 'objectPHID');
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->objectPHIDs) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/tokens/query/PhabricatorTokenGivenQuery.php b/src/applications/tokens/query/PhabricatorTokenGivenQuery.php
index 896b4532c9..c16eaa2168 100644
--- a/src/applications/tokens/query/PhabricatorTokenGivenQuery.php
+++ b/src/applications/tokens/query/PhabricatorTokenGivenQuery.php
@@ -1,96 +1,96 @@
<?php
final class PhabricatorTokenGivenQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $authorPHIDs;
private $objectPHIDs;
private $tokenPHIDs;
public function withTokenPHIDs(array $token_phids) {
$this->tokenPHIDs = $token_phids;
return $this;
}
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorTokenGiven();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($rows);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->objectPHIDs) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->tokenPHIDs) {
$where[] = qsprintf(
$conn_r,
'tokenPHID IN (%Ls)',
$this->tokenPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $results) {
$object_phids = array_filter(mpull($results, 'getObjectPHID'));
if (!$object_phids) {
return array();
}
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($object_phids)
->execute();
foreach ($results as $key => $result) {
$phid = $result->getObjectPHID();
if (empty($objects[$phid])) {
unset($results[$key]);
} else {
$result->attachObject($objects[$phid]);
}
}
return $results;
}
public function getQueryApplicationClass() {
return 'PhabricatorTokensApplication';
}
}
diff --git a/src/applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php b/src/applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php
index cd61c0fd30..f79de81ba3 100644
--- a/src/applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php
+++ b/src/applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php
@@ -1,125 +1,125 @@
<?php
abstract class PhabricatorApplicationTransactionCommentQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $authorPHIDs;
private $phids;
private $transactionPHIDs;
private $isDeleted;
private $hasTransaction;
abstract protected function getTemplate();
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withTransactionPHIDs(array $transaction_phids) {
$this->transactionPHIDs = $transaction_phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
public function withIsDeleted($deleted) {
$this->isDeleted = $deleted;
return $this;
}
public function withHasTransaction($has_transaction) {
$this->hasTransaction = $has_transaction;
return $this;
}
protected function loadPage() {
$table = $this->getTemplate();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T xcomment %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
return $this->formatWhereClause($this->buildWhereClauseComponents($conn_r));
}
protected function buildWhereClauseComponents(
AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'xcomment.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'xcomment.phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'xcomment.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->transactionPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'xcomment.transactionPHID IN (%Ls)',
$this->transactionPHIDs);
}
if ($this->isDeleted !== null) {
$where[] = qsprintf(
$conn_r,
'xcomment.isDeleted = %d',
(int)$this->isDeleted);
}
if ($this->hasTransaction !== null) {
if ($this->hasTransaction) {
$where[] = qsprintf(
$conn_r,
'xcomment.transactionPHID IS NOT NULL');
} else {
$where[] = qsprintf(
$conn_r,
'xcomment.transactionPHID IS NULL');
}
}
return $where;
}
public function getQueryApplicationClass() {
// TODO: Figure out the app via the template?
return null;
}
}
diff --git a/src/applications/transactions/query/PhabricatorApplicationTransactionQuery.php b/src/applications/transactions/query/PhabricatorApplicationTransactionQuery.php
index 5da8411277..ac6f713eeb 100644
--- a/src/applications/transactions/query/PhabricatorApplicationTransactionQuery.php
+++ b/src/applications/transactions/query/PhabricatorApplicationTransactionQuery.php
@@ -1,191 +1,191 @@
<?php
abstract class PhabricatorApplicationTransactionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids;
private $objectPHIDs;
private $authorPHIDs;
private $transactionTypes;
private $needComments = true;
private $needHandles = true;
abstract public function getTemplateApplicationTransaction();
protected function buildMoreWhereClauses(AphrontDatabaseConnection $conn_r) {
return array();
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withTransactionTypes(array $transaction_types) {
$this->transactionTypes = $transaction_types;
return $this;
}
public function needComments($need) {
$this->needComments = $need;
return $this;
}
public function needHandles($need) {
$this->needHandles = $need;
return $this;
}
protected function loadPage() {
$table = $this->getTemplateApplicationTransaction();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T x %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$xactions = $table->loadAllFromArray($data);
foreach ($xactions as $xaction) {
$xaction->attachViewer($this->getViewer());
}
if ($this->needComments) {
$comment_phids = array_filter(mpull($xactions, 'getCommentPHID'));
$comments = array();
if ($comment_phids) {
$comments =
id(new PhabricatorApplicationTransactionTemplatedCommentQuery())
->setTemplate($table->getApplicationTransactionCommentObject())
->setViewer($this->getViewer())
->withPHIDs($comment_phids)
->execute();
$comments = mpull($comments, null, 'getPHID');
}
foreach ($xactions as $xaction) {
if ($xaction->getCommentPHID()) {
$comment = idx($comments, $xaction->getCommentPHID());
if ($comment) {
$xaction->attachComment($comment);
}
}
}
} else {
foreach ($xactions as $xaction) {
$xaction->setCommentNotLoaded(true);
}
}
return $xactions;
}
protected function willFilterPage(array $xactions) {
$object_phids = array_keys(mpull($xactions, null, 'getObjectPHID'));
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($object_phids)
->execute();
foreach ($xactions as $key => $xaction) {
$object_phid = $xaction->getObjectPHID();
if (empty($objects[$object_phid])) {
unset($xactions[$key]);
continue;
}
$xaction->attachObject($objects[$object_phid]);
}
// NOTE: We have to do this after loading objects, because the objects
// may help determine which handles are required (for example, in the case
// of custom fields).
if ($this->needHandles) {
$phids = array();
foreach ($xactions as $xaction) {
$phids[$xaction->getPHID()] = $xaction->getRequiredHandlePHIDs();
}
$handles = array();
$merged = array_mergev($phids);
if ($merged) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs($merged)
->execute();
}
foreach ($xactions as $xaction) {
$xaction->setHandles(
array_select_keys(
$handles,
$phids[$xaction->getPHID()]));
}
}
return $xactions;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->objectPHIDs) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->transactionTypes) {
$where[] = qsprintf(
$conn_r,
'transactionType IN (%Ls)',
$this->transactionTypes);
}
foreach ($this->buildMoreWhereClauses($conn_r) as $clause) {
$where[] = $clause;
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
// TODO: Sort this out?
return null;
}
}
diff --git a/src/infrastructure/daemon/workers/query/PhabricatorWorkerArchiveTaskQuery.php b/src/infrastructure/daemon/workers/query/PhabricatorWorkerArchiveTaskQuery.php
index eb46857a4f..7dfafa16cc 100644
--- a/src/infrastructure/daemon/workers/query/PhabricatorWorkerArchiveTaskQuery.php
+++ b/src/infrastructure/daemon/workers/query/PhabricatorWorkerArchiveTaskQuery.php
@@ -1,94 +1,94 @@
<?php
final class PhabricatorWorkerArchiveTaskQuery
extends PhabricatorQuery {
private $ids;
private $dateModifiedSince;
private $dateCreatedBefore;
private $objectPHIDs;
private $limit;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withDateModifiedSince($timestamp) {
$this->dateModifiedSince = $timestamp;
return $this;
}
public function withDateCreatedBefore($timestamp) {
$this->dateCreatedBefore = $timestamp;
return $this;
}
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
public function execute() {
$task_table = new PhabricatorWorkerArchiveTask();
$conn_r = $task_table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q ORDER BY id DESC %Q',
$task_table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildLimitClause($conn_r));
return $task_table->loadAllFromArray($rows);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id in (%Ld)',
$this->ids);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->dateModifiedSince) {
$where[] = qsprintf(
$conn_r,
'dateModified > %d',
$this->dateModifiedSince);
}
if ($this->dateCreatedBefore) {
$where[] = qsprintf(
$conn_r,
'dateCreated < %d',
$this->dateCreatedBefore);
}
return $this->formatWhereClause($where);
}
private function buildLimitClause(AphrontDatabaseConnection $conn_r) {
$clause = '';
if ($this->limit) {
$clause = qsprintf($conn_r, 'LIMIT %d', $this->limit);
}
return $clause;
}
}
diff --git a/src/infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php b/src/infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php
index 456a042776..07c3460494 100644
--- a/src/infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php
+++ b/src/infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php
@@ -1,332 +1,335 @@
<?php
/**
* Select and lease tasks from the worker task queue.
*/
final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
const PHASE_LEASED = 'leased';
const PHASE_UNLEASED = 'unleased';
const PHASE_EXPIRED = 'expired';
private $ids;
private $objectPHIDs;
private $limit;
private $skipLease;
private $leased = false;
public static function getDefaultWaitBeforeRetry() {
return phutil_units('5 minutes in seconds');
}
public static function getDefaultLeaseDuration() {
return phutil_units('2 hours in seconds');
}
/**
* Set this flag to select tasks from the top of the queue without leasing
* them.
*
* This can be used to show which tasks are coming up next without altering
* the queue's behavior.
*
* @param bool True to skip the lease acquisition step.
*/
public function setSkipLease($skip) {
$this->skipLease = $skip;
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
/**
* Select only leased tasks, only unleased tasks, or both types of task.
*
* By default, queries select only unleased tasks (equivalent to passing
* `false` to this method). You can pass `true` to select only leased tasks,
* or `null` to ignore the lease status of tasks.
*
* If your result set potentially includes leased tasks, you must disable
* leasing using @{method:setSkipLease}. These options are intended for use
* when displaying task status information.
*
* @param mixed `true` to select only leased tasks, `false` to select only
* unleased tasks (default), or `null` to select both.
* @return this
*/
public function withLeasedTasks($leased) {
$this->leased = $leased;
return $this;
}
public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
public function execute() {
if (!$this->limit) {
throw new Exception(
pht('You must setLimit() when leasing tasks.'));
}
if ($this->leased !== false) {
if (!$this->skipLease) {
throw new Exception(
pht(
'If you potentially select leased tasks using withLeasedTasks(), '.
'you MUST disable lease acquisition by calling setSkipLease().'));
}
}
$task_table = new PhabricatorWorkerActiveTask();
$taskdata_table = new PhabricatorWorkerTaskData();
$lease_ownership_name = $this->getLeaseOwnershipName();
$conn_w = $task_table->establishConnection('w');
// Try to satisfy the request from new, unleased tasks first. If we don't
// find enough tasks, try tasks with expired leases (i.e., tasks which have
// previously failed).
// If we're selecting leased tasks, look for them first.
$phases = array();
if ($this->leased !== false) {
$phases[] = self::PHASE_LEASED;
}
if ($this->leased !== true) {
$phases[] = self::PHASE_UNLEASED;
$phases[] = self::PHASE_EXPIRED;
}
$limit = $this->limit;
$leased = 0;
$task_ids = array();
foreach ($phases as $phase) {
// NOTE: If we issue `UPDATE ... WHERE ... ORDER BY id ASC`, the query
// goes very, very slowly. The `ORDER BY` triggers this, although we get
// the same apparent results without it. Without the ORDER BY, binary
// read slaves complain that the query isn't repeatable. To avoid both
// problems, do a SELECT and then an UPDATE.
$rows = queryfx_all(
$conn_w,
'SELECT id, leaseOwner FROM %T %Q %Q %Q',
$task_table->getTableName(),
- $this->buildWhereClause($conn_w, $phase),
+ $this->buildCustomWhereClause($conn_w, $phase),
$this->buildOrderClause($conn_w, $phase),
$this->buildLimitClause($conn_w, $limit - $leased));
// NOTE: Sometimes, we'll race with another worker and they'll grab
// this task before we do. We could reduce how often this happens by
// selecting more tasks than we need, then shuffling them and trying
// to lock only the number we're actually after. However, the amount
// of time workers spend here should be very small relative to their
// total runtime, so keep it simple for the moment.
if ($rows) {
if ($this->skipLease) {
$leased += count($rows);
$task_ids += array_fuse(ipull($rows, 'id'));
} else {
queryfx(
$conn_w,
'UPDATE %T task
SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + %d
%Q',
$task_table->getTableName(),
$lease_ownership_name,
self::getDefaultLeaseDuration(),
$this->buildUpdateWhereClause($conn_w, $phase, $rows));
$leased += $conn_w->getAffectedRows();
}
if ($leased == $limit) {
break;
}
}
}
if (!$leased) {
return array();
}
if ($this->skipLease) {
$selection_condition = qsprintf(
$conn_w,
'task.id IN (%Ld)',
$task_ids);
} else {
$selection_condition = qsprintf(
$conn_w,
'task.leaseOwner = %s AND leaseExpires > UNIX_TIMESTAMP()',
$lease_ownership_name);
}
$data = queryfx_all(
$conn_w,
'SELECT task.*, taskdata.data _taskData, UNIX_TIMESTAMP() _serverTime
FROM %T task LEFT JOIN %T taskdata
ON taskdata.id = task.dataID
WHERE %Q %Q %Q',
$task_table->getTableName(),
$taskdata_table->getTableName(),
$selection_condition,
$this->buildOrderClause($conn_w, $phase),
$this->buildLimitClause($conn_w, $limit));
$tasks = $task_table->loadAllFromArray($data);
$tasks = mpull($tasks, null, 'getID');
foreach ($data as $row) {
$tasks[$row['id']]->setServerTime($row['_serverTime']);
if ($row['_taskData']) {
$task_data = json_decode($row['_taskData'], true);
} else {
$task_data = null;
}
$tasks[$row['id']]->setData($task_data);
}
if ($this->skipLease) {
// Reorder rows into the original phase order if this is a status query.
$tasks = array_select_keys($tasks, $task_ids);
}
return $tasks;
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_w, $phase) {
+ protected function buildCustomWhereClause(
+ AphrontDatabaseConnection $conn_w,
+ $phase) {
+
$where = array();
switch ($phase) {
case self::PHASE_LEASED:
$where[] = 'leaseOwner IS NOT NULL';
$where[] = 'leaseExpires >= UNIX_TIMESTAMP()';
break;
case self::PHASE_UNLEASED:
$where[] = 'leaseOwner IS NULL';
break;
case self::PHASE_EXPIRED:
$where[] = 'leaseExpires < UNIX_TIMESTAMP()';
break;
default:
throw new Exception("Unknown phase '{$phase}'!");
}
if ($this->ids !== null) {
$where[] = qsprintf($conn_w, 'id IN (%Ld)', $this->ids);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf($conn_w, 'objectPHID IN (%Ls)', $this->objectPHIDs);
}
return $this->formatWhereClause($where);
}
private function buildUpdateWhereClause(
AphrontDatabaseConnection $conn_w,
$phase,
array $rows) {
$where = array();
// NOTE: This is basically working around the MySQL behavior that
// `IN (NULL)` doesn't match NULL.
switch ($phase) {
case self::PHASE_LEASED:
throw new Exception(
pht(
'Trying to lease tasks selected in the leased phase! This is '.
'intended to be imposssible.'));
case self::PHASE_UNLEASED:
$where[] = qsprintf($conn_w, 'leaseOwner IS NULL');
$where[] = qsprintf($conn_w, 'id IN (%Ld)', ipull($rows, 'id'));
break;
case self::PHASE_EXPIRED:
$in = array();
foreach ($rows as $row) {
$in[] = qsprintf(
$conn_w,
'(id = %d AND leaseOwner = %s)',
$row['id'],
$row['leaseOwner']);
}
$where[] = qsprintf($conn_w, '(%Q)', implode(' OR ', $in));
break;
default:
throw new Exception("Unknown phase '{$phase}'!");
}
return $this->formatWhereClause($where);
}
private function buildOrderClause(AphrontDatabaseConnection $conn_w, $phase) {
switch ($phase) {
case self::PHASE_LEASED:
// Ideally we'd probably order these by lease acquisition time, but
// we don't have that handy and this is a good approximation.
return qsprintf($conn_w, 'ORDER BY priority ASC, id ASC');
case self::PHASE_UNLEASED:
// When selecting new tasks, we want to consume them in order of
// increasing priority (and then FIFO).
return qsprintf($conn_w, 'ORDER BY priority ASC, id ASC');
case self::PHASE_EXPIRED:
// When selecting failed tasks, we want to consume them in roughly
// FIFO order of their failures, which is not necessarily their original
// queue order.
// Particularly, this is important for tasks which use soft failures to
// indicate that they are waiting on other tasks to complete: we need to
// push them to the end of the queue after they fail, at least on
// average, so we don't deadlock retrying the same blocked task over
// and over again.
return qsprintf($conn_w, 'ORDER BY leaseExpires ASC');
default:
throw new Exception(pht('Unknown phase "%s"!', $phase));
}
}
private function buildLimitClause(AphrontDatabaseConnection $conn_w, $limit) {
return qsprintf($conn_w, 'LIMIT %d', $limit);
}
private function getLeaseOwnershipName() {
static $sequence = 0;
// TODO: If the host name is very long, this can overflow the 64-character
// column, so we pick just the first part of the host name. It might be
// useful to just use a random hash as the identifier instead and put the
// pid / time / host (which are somewhat useful diagnostically) elsewhere.
// Likely, we could store a daemon ID instead and use that to identify
// when and where code executed. See T6742.
$host = php_uname('n');
$host = id(new PhutilUTF8StringTruncator())
->setMaximumBytes(32)
->setTerminator('...')
->truncateString($host);
$parts = array(
getmypid(),
time(),
$host,
++$sequence,
);
return implode(':', $parts);
}
}
diff --git a/src/infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php b/src/infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php
index 679a5236a7..eb9441aa8f 100644
--- a/src/infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php
+++ b/src/infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php
@@ -1,233 +1,233 @@
<?php
final class PhabricatorWorkerTriggerQuery
extends PhabricatorPolicyAwareQuery {
// NOTE: This is a PolicyAware query so it can work with other infrastructure
// like handles; triggers themselves are low-level and do not have
// meaninguful policies.
const ORDER_ID = 'id';
const ORDER_EXECUTION = 'execution';
const ORDER_VERSION = 'version';
private $ids;
private $phids;
private $versionMin;
private $versionMax;
private $nextEpochMin;
private $nextEpochMax;
private $needEvents;
private $order = self::ORDER_ID;
public function getQueryApplicationClass() {
return null;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withVersionBetween($min, $max) {
$this->versionMin = $min;
$this->versionMax = $max;
return $this;
}
public function withNextEventBetween($min, $max) {
$this->nextEpochMin = $min;
$this->nextEpochMax = $max;
return $this;
}
public function needEvents($need_events) {
$this->needEvents = $need_events;
return $this;
}
/**
* Set the result order.
*
* Note that using `ORDER_EXECUTION` will also filter results to include only
* triggers which have been scheduled to execute. You should not use this
* ordering when querying for specific triggers, e.g. by ID or PHID.
*
* @param const Result order.
* @return this
*/
public function setOrder($order) {
$this->order = $order;
return $this;
}
protected function nextPage(array $page) {
// NOTE: We don't implement paging because we don't currently ever need
// it and paging ORDER_EXCUTION is a hassle.
throw new PhutilMethodNotImplementedException();
}
protected function loadPage() {
$task_table = new PhabricatorWorkerTrigger();
$conn_r = $task_table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT t.* FROM %T t %Q %Q %Q %Q',
$task_table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$triggers = $task_table->loadAllFromArray($rows);
if ($triggers) {
if ($this->needEvents) {
$ids = mpull($triggers, 'getID');
$events = id(new PhabricatorWorkerTriggerEvent())->loadAllWhere(
'triggerID IN (%Ld)',
$ids);
$events = mpull($events, null, 'getTriggerID');
foreach ($triggers as $key => $trigger) {
$event = idx($events, $trigger->getID());
$trigger->attachEvent($event);
}
}
foreach ($triggers as $key => $trigger) {
$clock_class = $trigger->getClockClass();
if (!is_subclass_of($clock_class, 'PhabricatorTriggerClock')) {
unset($triggers[$key]);
continue;
}
try {
$argv = array($trigger->getClockProperties());
$clock = newv($clock_class, $argv);
} catch (Exception $ex) {
unset($triggers[$key]);
continue;
}
$trigger->attachClock($clock);
}
foreach ($triggers as $key => $trigger) {
$action_class = $trigger->getActionClass();
if (!is_subclass_of($action_class, 'PhabricatorTriggerAction')) {
unset($triggers[$key]);
continue;
}
try {
$argv = array($trigger->getActionProperties());
$action = newv($action_class, $argv);
} catch (Exception $ex) {
unset($triggers[$key]);
continue;
}
$trigger->attachAction($action);
}
}
return $triggers;
}
private function buildJoinClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
if (($this->nextEpochMin !== null) ||
($this->nextEpochMax !== null) ||
($this->order == PhabricatorWorkerTriggerQuery::ORDER_EXECUTION)) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T e ON e.triggerID = t.id',
id(new PhabricatorWorkerTriggerEvent())->getTableName());
}
return implode(' ', $joins);
}
- private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
't.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
't.phid IN (%Ls)',
$this->phids);
}
if ($this->versionMin !== null) {
$where[] = qsprintf(
$conn_r,
't.triggerVersion >= %d',
$this->versionMin);
}
if ($this->versionMax !== null) {
$where[] = qsprintf(
$conn_r,
't.triggerVersion <= %d',
$this->versionMax);
}
if ($this->nextEpochMin !== null) {
$where[] = qsprintf(
$conn_r,
'e.nextEventEpoch >= %d',
$this->nextEpochMin);
}
if ($this->nextEpochMax !== null) {
$where[] = qsprintf(
$conn_r,
'e.nextEventEpoch <= %d',
$this->nextEpochMax);
}
return $this->formatWhereClause($where);
}
private function buildOrderClause(AphrontDatabaseConnection $conn_r) {
switch ($this->order) {
case self::ORDER_ID:
return qsprintf(
$conn_r,
'ORDER BY id DESC');
case self::ORDER_EXECUTION:
return qsprintf(
$conn_r,
'ORDER BY e.nextEventEpoch ASC, e.id ASC');
case self::ORDER_VERSION:
return qsprintf(
$conn_r,
'ORDER BY t.triggerVersion ASC');
default:
throw new Exception(
pht(
'Unsupported order "%s".',
$this->order));
}
}
}
diff --git a/src/infrastructure/edges/query/PhabricatorEdgeQuery.php b/src/infrastructure/edges/query/PhabricatorEdgeQuery.php
index 17f1660b33..3ea7eb998e 100644
--- a/src/infrastructure/edges/query/PhabricatorEdgeQuery.php
+++ b/src/infrastructure/edges/query/PhabricatorEdgeQuery.php
@@ -1,332 +1,332 @@
<?php
/**
* Load object edges created by @{class:PhabricatorEdgeEditor}.
*
* name=Querying Edges
* $src = $earth_phid;
* $type = PhabricatorEdgeConfig::TYPE_BODY_HAS_SATELLITE;
*
* // Load the earth's satellites.
* $satellite_edges = id(new PhabricatorEdgeQuery())
* ->withSourcePHIDs(array($src))
* ->withEdgeTypes(array($type))
* ->execute();
*
* For more information on edges, see @{article:Using Edges}.
*
* @task config Configuring the Query
* @task exec Executing the Query
* @task internal Internal
*/
final class PhabricatorEdgeQuery extends PhabricatorQuery {
private $sourcePHIDs;
private $destPHIDs;
private $edgeTypes;
private $resultSet;
const ORDER_OLDEST_FIRST = 'order:oldest';
const ORDER_NEWEST_FIRST = 'order:newest';
private $order = self::ORDER_NEWEST_FIRST;
private $needEdgeData;
/* -( Configuring the Query )---------------------------------------------- */
/**
* Find edges originating at one or more source PHIDs. You MUST provide this
* to execute an edge query.
*
* @param list List of source PHIDs.
* @return this
*
* @task config
*/
public function withSourcePHIDs(array $source_phids) {
$this->sourcePHIDs = $source_phids;
return $this;
}
/**
* Find edges terminating at one or more destination PHIDs.
*
* @param list List of destination PHIDs.
* @return this
*
*/
public function withDestinationPHIDs(array $dest_phids) {
$this->destPHIDs = $dest_phids;
return $this;
}
/**
* Find edges of specific types.
*
* @param list List of PhabricatorEdgeConfig type constants.
* @return this
*
* @task config
*/
public function withEdgeTypes(array $types) {
$this->edgeTypes = $types;
return $this;
}
/**
* Configure the order edge results are returned in.
*
* @param const Order constant.
* @return this
*
* @task config
*/
public function setOrder($order) {
$this->order = $order;
return $this;
}
/**
* When loading edges, also load edge data.
*
* @param bool True to load edge data.
* @return this
*
* @task config
*/
public function needEdgeData($need) {
$this->needEdgeData = $need;
return $this;
}
/* -( Executing the Query )------------------------------------------------ */
/**
* Convenience method for loading destination PHIDs with one source and one
* edge type. Equivalent to building a full query, but simplifies a common
* use case.
*
* @param phid Source PHID.
* @param const Edge type.
* @return list<phid> List of destination PHIDs.
*/
public static function loadDestinationPHIDs($src_phid, $edge_type) {
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array($src_phid))
->withEdgeTypes(array($edge_type))
->execute();
return array_keys($edges[$src_phid][$edge_type]);
}
/**
* Convenience method for loading a single edge's metadata for
* a given source, destination, and edge type. Returns null
* if the edge does not exist or does not have metadata. Builds
* and immediately executes a full query.
*
* @param phid Source PHID.
* @param const Edge type.
* @param phid Destination PHID.
* @return wild Edge annotation (or null).
*/
public static function loadSingleEdgeData($src_phid, $edge_type, $dest_phid) {
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array($src_phid))
->withEdgeTypes(array($edge_type))
->withDestinationPHIDs(array($dest_phid))
->needEdgeData(true)
->execute();
if (isset($edges[$src_phid][$edge_type][$dest_phid]['data'])) {
return $edges[$src_phid][$edge_type][$dest_phid]['data'];
}
return null;
}
/**
* Load specified edges.
*
* @task exec
*/
public function execute() {
if (!$this->sourcePHIDs) {
throw new Exception(
'You must use withSourcePHIDs() to query edges.');
}
$sources = phid_group_by_type($this->sourcePHIDs);
$result = array();
// When a query specifies types, make sure we return data for all queried
// types.
if ($this->edgeTypes) {
foreach ($this->sourcePHIDs as $phid) {
foreach ($this->edgeTypes as $type) {
$result[$phid][$type] = array();
}
}
}
foreach ($sources as $type => $phids) {
$conn_r = PhabricatorEdgeConfig::establishConnection($type, 'r');
$where = $this->buildWhereClause($conn_r);
$order = $this->buildOrderClause($conn_r);
$edges = queryfx_all(
$conn_r,
'SELECT edge.* FROM %T edge %Q %Q',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
$where,
$order);
if ($this->needEdgeData) {
$data_ids = array_filter(ipull($edges, 'dataID'));
$data_map = array();
if ($data_ids) {
$data_rows = queryfx_all(
$conn_r,
'SELECT edgedata.* FROM %T edgedata WHERE id IN (%Ld)',
PhabricatorEdgeConfig::TABLE_NAME_EDGEDATA,
$data_ids);
foreach ($data_rows as $row) {
$data_map[$row['id']] = idx(
json_decode($row['data'], true),
'data');
}
}
foreach ($edges as $key => $edge) {
$edges[$key]['data'] = idx($data_map, $edge['dataID'], array());
}
}
foreach ($edges as $edge) {
$result[$edge['src']][$edge['type']][$edge['dst']] = $edge;
}
}
$this->resultSet = $result;
return $result;
}
/**
* Convenience function for selecting edge destination PHIDs after calling
* execute().
*
* Returns a flat list of PHIDs matching the provided source PHID and type
* filters. By default, the filters are empty so all PHIDs will be returned.
* For example, if you're doing a batch query from several sources, you might
* write code like this:
*
* $query = new PhabricatorEdgeQuery();
* $query->setViewer($viewer);
* $query->withSourcePHIDs(mpull($objects, 'getPHID'));
* $query->withEdgeTypes(array($some_type));
* $query->execute();
*
* // Gets all of the destinations.
* $all_phids = $query->getDestinationPHIDs();
* $handles = id(new PhabricatorHandleQuery())
* ->setViewer($viewer)
* ->withPHIDs($all_phids)
* ->execute();
*
* foreach ($objects as $object) {
* // Get all of the destinations for the given object.
* $dst_phids = $query->getDestinationPHIDs(array($object->getPHID()));
* $object->attachHandles(array_select_keys($handles, $dst_phids));
* }
*
* @param list? List of PHIDs to select, or empty to select all.
* @param list? List of edge types to select, or empty to select all.
* @return list<phid> List of matching destination PHIDs.
*/
public function getDestinationPHIDs(
array $src_phids = array(),
array $types = array()) {
if ($this->resultSet === null) {
throw new Exception(
'You must execute() a query before you you can getDestinationPHIDs().');
}
$result_phids = array();
$set = $this->resultSet;
if ($src_phids) {
$set = array_select_keys($set, $src_phids);
}
foreach ($set as $src => $edges_by_type) {
if ($types) {
$edges_by_type = array_select_keys($edges_by_type, $types);
}
foreach ($edges_by_type as $edges) {
foreach ($edges as $edge_phid => $edge) {
$result_phids[$edge_phid] = true;
}
}
}
return array_keys($result_phids);
}
/* -( Internals )---------------------------------------------------------- */
/**
* @task internal
*/
- private function buildWhereClause($conn_r) {
+ protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->sourcePHIDs) {
$where[] = qsprintf(
$conn_r,
'edge.src IN (%Ls)',
$this->sourcePHIDs);
}
if ($this->edgeTypes) {
$where[] = qsprintf(
$conn_r,
'edge.type IN (%Ls)',
$this->edgeTypes);
}
if ($this->destPHIDs) {
// potentially complain if $this->edgeType was not set
$where[] = qsprintf(
$conn_r,
'edge.dst IN (%Ls)',
$this->destPHIDs);
}
return $this->formatWhereClause($where);
}
/**
* @task internal
*/
private function buildOrderClause($conn_r) {
if ($this->order == self::ORDER_NEWEST_FIRST) {
return 'ORDER BY edge.dateCreated DESC, edge.seq DESC';
} else {
return 'ORDER BY edge.dateCreated ASC, edge.seq ASC';
}
}
}
diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
index 7e7bfc2d35..d532d1cf0f 100644
--- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
+++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
@@ -1,1108 +1,1148 @@
<?php
/**
* A query class which uses cursor-based paging. This paging is much more
* performant than offset-based paging in the presence of policy filtering.
*
+ * @task clauses Building Query Clauses
* @task appsearch Integration with ApplicationSearch
+ * @task customfield Integration with CustomField
* @task paging Paging
* @task order Result Ordering
*/
abstract class PhabricatorCursorPagedPolicyAwareQuery
extends PhabricatorPolicyAwareQuery {
private $afterID;
private $beforeID;
private $applicationSearchConstraints = array();
protected $applicationSearchOrders = array();
private $internalPaging;
private $orderVector;
private $builtinOrder;
protected function getPageCursors(array $page) {
return array(
$this->getResultCursor(head($page)),
$this->getResultCursor(last($page)),
);
}
protected function getResultCursor($object) {
if (!is_object($object)) {
throw new Exception(
pht(
'Expected object, got "%s".',
gettype($object)));
}
return $object->getID();
}
protected function nextPage(array $page) {
// See getPagingViewer() for a description of this flag.
$this->internalPaging = true;
if ($this->beforeID !== null) {
$page = array_reverse($page, $preserve_keys = true);
list($before, $after) = $this->getPageCursors($page);
$this->beforeID = $before;
} else {
list($before, $after) = $this->getPageCursors($page);
$this->afterID = $after;
}
}
final public function setAfterID($object_id) {
$this->afterID = $object_id;
return $this;
}
final protected function getAfterID() {
return $this->afterID;
}
final public function setBeforeID($object_id) {
$this->beforeID = $object_id;
return $this;
}
final protected function getBeforeID() {
return $this->beforeID;
}
/**
* Get the viewer for making cursor paging queries.
*
* NOTE: You should ONLY use this viewer to load cursor objects while
* building paging queries.
*
* Cursor paging can happen in two ways. First, the user can request a page
* like `/stuff/?after=33`, which explicitly causes paging. Otherwise, we
* can fall back to implicit paging if we filter some results out of a
* result list because the user can't see them and need to go fetch some more
* results to generate a large enough result list.
*
* In the first case, want to use the viewer's policies to load the object.
* This prevents an attacker from figuring out information about an object
* they can't see by executing queries like `/stuff/?after=33&order=name`,
* which would otherwise give them a hint about the name of the object.
* Generally, if a user can't see an object, they can't use it to page.
*
* In the second case, we need to load the object whether the user can see
* it or not, because we need to examine new results. For example, if a user
* loads `/stuff/` and we run a query for the first 100 items that they can
* see, but the first 100 rows in the database aren't visible, we need to
* be able to issue a query for the next 100 results. If we can't load the
* cursor object, we'll fail or issue the same query over and over again.
* So, generally, internal paging must bypass policy controls.
*
* This method returns the appropriate viewer, based on the context in which
* the paging is occuring.
*
* @return PhabricatorUser Viewer for executing paging queries.
*/
final protected function getPagingViewer() {
if ($this->internalPaging) {
return PhabricatorUser::getOmnipotentUser();
} else {
return $this->getViewer();
}
}
final protected function buildLimitClause(AphrontDatabaseConnection $conn_r) {
if ($this->getRawResultLimit()) {
return qsprintf($conn_r, 'LIMIT %d', $this->getRawResultLimit());
} else {
return '';
}
}
final protected function didLoadResults(array $results) {
if ($this->beforeID) {
$results = array_reverse($results, $preserve_keys = true);
}
return $results;
}
final public function executeWithCursorPager(AphrontCursorPagerView $pager) {
$limit = $pager->getPageSize();
$this->setLimit($limit + 1);
if ($pager->getAfterID()) {
$this->setAfterID($pager->getAfterID());
} else if ($pager->getBeforeID()) {
$this->setBeforeID($pager->getBeforeID());
}
$results = $this->execute();
$count = count($results);
$sliced_results = $pager->sliceResults($results);
if ($sliced_results) {
list($before, $after) = $this->getPageCursors($sliced_results);
if ($pager->getBeforeID() || ($count > $limit)) {
$pager->setNextPageID($after);
}
if ($pager->getAfterID() ||
($pager->getBeforeID() && ($count > $limit))) {
$pager->setPrevPageID($before);
}
}
return $sliced_results;
}
/**
* Return the alias this query uses to identify the primary table.
*
* Some automatic query constructions may need to be qualified with a table
* alias if the query performs joins which make column names ambiguous. If
* this is the case, return the alias for the primary table the query
* uses; generally the object table which has `id` and `phid` columns.
*
* @return string Alias for the primary table.
*/
protected function getPrimaryTableAlias() {
return null;
}
protected function newResultObject() {
return null;
}
+/* -( Building Query Clauses )--------------------------------------------- */
+
+
+ /**
+ * @task clauses
+ */
+ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
+ throw new PhutilMethodNotImplementedException();
+ }
+
+
/* -( Paging )------------------------------------------------------------- */
+ /**
+ * @task paging
+ */
protected function buildPagingClause(AphrontDatabaseConnection $conn) {
$orderable = $this->getOrderableColumns();
$vector = $this->getOrderVector();
if ($this->beforeID !== null) {
$cursor = $this->beforeID;
$reversed = true;
} else if ($this->afterID !== null) {
$cursor = $this->afterID;
$reversed = false;
} else {
// No paging is being applied to this query so we do not need to
// construct a paging clause.
return '';
}
$keys = array();
foreach ($vector as $order) {
$keys[] = $order->getOrderKey();
}
$value_map = $this->getPagingValueMap($cursor, $keys);
$columns = array();
foreach ($vector as $order) {
$key = $order->getOrderKey();
if (!array_key_exists($key, $value_map)) {
throw new Exception(
pht(
'Query "%s" failed to return a value from getPagingValueMap() '.
'for column "%s".',
get_class($this),
$key));
}
$column = $orderable[$key];
$column['value'] = $value_map[$key];
$columns[] = $column;
}
return $this->buildPagingClauseFromMultipleColumns(
$conn,
$columns,
array(
'reversed' => $reversed,
));
}
+
+ /**
+ * @task paging
+ */
protected function getPagingValueMap($cursor, array $keys) {
- // TODO: This is a hack to make this work with existing classes for now.
return array(
'id' => $cursor,
);
}
+
+ /**
+ * @task paging
+ */
protected function loadCursorObject($cursor) {
$query = newv(get_class($this), array())
->setViewer($this->getPagingViewer())
->withIDs(array((int)$cursor));
$this->willExecuteCursorQuery($query);
$object = $query->executeOne();
if (!$object) {
throw new Exception(
pht(
'Cursor "%s" does not identify a valid object.',
$cursor));
}
return $object;
}
+
+ /**
+ * @task paging
+ */
protected function willExecuteCursorQuery(
PhabricatorCursorPagedPolicyAwareQuery $query) {
return;
}
/**
* Simplifies the task of constructing a paging clause across multiple
* columns. In the general case, this looks like:
*
* A > a OR (A = a AND B > b) OR (A = a AND B = b AND C > c)
*
* To build a clause, specify the name, type, and value of each column
* to include:
*
* $this->buildPagingClauseFromMultipleColumns(
* $conn_r,
* array(
* array(
* 'table' => 't',
* 'column' => 'title',
* 'type' => 'string',
* 'value' => $cursor->getTitle(),
* 'reverse' => true,
* ),
* array(
* 'table' => 't',
* 'column' => 'id',
* 'type' => 'int',
* 'value' => $cursor->getID(),
* ),
* ),
* array(
* 'reversed' => $is_reversed,
* ));
*
* This method will then return a composable clause for inclusion in WHERE.
*
* @param AphrontDatabaseConnection Connection query will execute on.
* @param list<map> Column description dictionaries.
* @param map Additional constuction options.
* @return string Query clause.
+ * @task paging
*/
final protected function buildPagingClauseFromMultipleColumns(
AphrontDatabaseConnection $conn,
array $columns,
array $options) {
foreach ($columns as $column) {
PhutilTypeSpec::checkMap(
$column,
array(
'table' => 'optional string|null',
'column' => 'string',
'value' => 'wild',
'type' => 'string',
'reverse' => 'optional bool',
'unique' => 'optional bool',
'null' => 'optional string|null',
));
}
PhutilTypeSpec::checkMap(
$options,
array(
'reversed' => 'optional bool',
));
$is_query_reversed = idx($options, 'reversed', false);
$clauses = array();
$accumulated = array();
$last_key = last_key($columns);
foreach ($columns as $key => $column) {
$type = $column['type'];
$null = idx($column, 'null');
if ($column['value'] === null) {
if ($null) {
$value = null;
} else {
throw new Exception(
pht(
'Column "%s" has null value, but does not specify a null '.
'behavior.',
$key));
}
} else {
switch ($type) {
case 'int':
$value = qsprintf($conn, '%d', $column['value']);
break;
case 'float':
$value = qsprintf($conn, '%f', $column['value']);
break;
case 'string':
$value = qsprintf($conn, '%s', $column['value']);
break;
default:
throw new Exception(
pht(
'Column "%s" has unknown column type "%s".',
$column['column'],
$type));
}
}
$is_column_reversed = idx($column, 'reverse', false);
$reverse = ($is_query_reversed xor $is_column_reversed);
$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);
}
$parts = array();
if ($null) {
$can_page_if_null = ($null === 'head');
$can_page_if_nonnull = ($null === 'tail');
if ($reverse) {
$can_page_if_null = !$can_page_if_null;
$can_page_if_nonnull = !$can_page_if_nonnull;
}
$subclause = null;
if ($can_page_if_null && $value === null) {
$parts[] = qsprintf(
$conn,
'(%Q IS NOT NULL)',
$field);
} else if ($can_page_if_nonnull && $value !== null) {
$parts[] = qsprintf(
$conn,
'(%Q IS NULL)',
$field);
}
}
if ($value !== null) {
$parts[] = qsprintf(
$conn,
'%Q %Q %Q',
$field,
$reverse ? '>' : '<',
$value);
}
if ($parts) {
if (count($parts) > 1) {
$clause[] = '('.implode(') OR (', $parts).')';
} else {
$clause[] = head($parts);
}
}
if ($clause) {
if (count($clause) > 1) {
$clauses[] = '('.implode(') AND (', $clause).')';
} else {
$clauses[] = head($clause);
}
}
if ($value === null) {
$accumulated[] = qsprintf(
$conn,
'%Q IS NULL',
$field);
} else {
$accumulated[] = qsprintf(
$conn,
'%Q = %Q',
$field,
$value);
}
}
return '('.implode(') OR (', $clauses).')';
}
/* -( Result Ordering )---------------------------------------------------- */
/**
* Select a result ordering.
*
* This is a high-level method which selects an ordering from a predefined
* list of builtin orders, as provided by @{method:getBuiltinOrders}. These
* options are user-facing and not exhaustive, but are generally convenient
* and meaningful.
*
* You can also use @{method:setOrderVector} to specify a low-level ordering
* across individual orderable columns. This offers greater control but is
* also more involved.
*
* @param string Key of a builtin order supported by this query.
* @return this
* @task order
*/
public function setOrder($order) {
$orders = $this->getBuiltinOrders();
if (empty($orders[$order])) {
throw new Exception(
pht(
'Query "%s" does not support a builtin order "%s". Supported orders '.
'are: %s.',
get_class($this),
$order,
implode(', ', array_keys($orders))));
}
$this->builtinOrder = $order;
$this->orderVector = null;
return $this;
}
/**
* Get builtin orders for this class.
*
* In application UIs, we want to be able to present users with a small
* selection of meaningful order options (like "Order by Title") rather than
* an exhaustive set of column ordering options.
*
* Meaningful user-facing orders are often really orders across multiple
* columns: for example, a "title" ordering is usually implemented as a
* "title, id" ordering under the hood.
*
* Builtin orders provide a mapping from convenient, understandable
* user-facing orders to implementations.
*
* A builtin order should provide these keys:
*
* - `vector` (`list<string>`): The actual order vector to use.
* - `name` (`string`): Human-readable order name.
*
* @return map<string, wild> Map from builtin order keys to specification.
* @task order
*/
public function getBuiltinOrders() {
$orders = array(
'newest' => array(
'vector' => array('id'),
'name' => pht('Creation (Newest First)'),
'aliases' => array('created'),
),
'oldest' => array(
'vector' => array('-id'),
'name' => pht('Creation (Oldest First)'),
),
);
$object = $this->newResultObject();
if ($object instanceof PhabricatorCustomFieldInterface) {
$list = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_APPLICATIONSEARCH);
foreach ($list->getFields() as $field) {
$index = $field->buildOrderIndex();
if (!$index) {
continue;
}
$key = $field->getFieldKey();
$digest = $field->getFieldIndex();
$full_key = 'custom:'.$key;
$orders[$full_key] = array(
'vector' => array($full_key, 'id'),
'name' => $field->getFieldName(),
);
}
}
return $orders;
}
/**
* Set a low-level column ordering.
*
* This is a low-level method which offers granular control over column
* ordering. In most cases, applications can more easily use
* @{method:setOrder} to choose a high-level builtin order.
*
* To set an order vector, specify a list of order keys as provided by
* @{method:getOrderableColumns}.
*
* @param PhabricatorQueryOrderVector|list<string> List of order keys.
* @return this
* @task order
*/
public function setOrderVector($vector) {
$vector = PhabricatorQueryOrderVector::newFromVector($vector);
$orderable = $this->getOrderableColumns();
// Make sure that all the components identify valid columns.
$unique = array();
foreach ($vector as $order) {
$key = $order->getOrderKey();
if (empty($orderable[$key])) {
$valid = implode(', ', array_keys($orderable));
throw new Exception(
pht(
'This query ("%s") does not support sorting by order key "%s". '.
'Supported orders are: %s.',
get_class($this),
$key,
$valid));
}
$unique[$key] = idx($orderable[$key], 'unique', false);
}
// Make sure that the last column is unique so that this is a strong
// ordering which can be used for paging.
$last = last($unique);
if ($last !== true) {
throw new Exception(
pht(
'Order vector "%s" is invalid: the last column in an order must '.
'be a column with unique values, but "%s" is not unique.',
$vector->getAsString(),
last_key($unique)));
}
// Make sure that other columns are not unique; an ordering like "id, name"
// does not make sense because only "id" can ever have an effect.
array_pop($unique);
foreach ($unique as $key => $is_unique) {
if ($is_unique) {
throw new Exception(
pht(
'Order vector "%s" is invalid: only the last column in an order '.
'may be unique, but "%s" is a unique column and not the last '.
'column in the order.',
$vector->getAsString(),
$key));
}
}
$this->orderVector = $vector;
return $this;
}
/**
* Get the effective order vector.
*
* @return PhabricatorQueryOrderVector Effective vector.
* @task order
*/
protected function getOrderVector() {
if (!$this->orderVector) {
if ($this->builtinOrder !== null) {
$builtin_order = idx($this->getBuiltinOrders(), $this->builtinOrder);
$vector = $builtin_order['vector'];
} else {
$vector = $this->getDefaultOrderVector();
}
$vector = PhabricatorQueryOrderVector::newFromVector($vector);
// We call setOrderVector() here to apply checks to the default vector.
// This catches any errors in the implementation.
$this->setOrderVector($vector);
}
return $this->orderVector;
}
/**
* @task order
*/
protected function getDefaultOrderVector() {
return array('id');
}
/**
* @task order
*/
public function getOrderableColumns() {
$columns = array(
'id' => array(
'table' => $this->getPrimaryTableAlias(),
'column' => 'id',
'reverse' => false,
'type' => 'int',
'unique' => true,
),
);
$object = $this->newResultObject();
if ($object instanceof PhabricatorCustomFieldInterface) {
$list = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_APPLICATIONSEARCH);
foreach ($list->getFields() as $field) {
$index = $field->buildOrderIndex();
if (!$index) {
continue;
}
$key = $field->getFieldKey();
$digest = $field->getFieldIndex();
$full_key = 'custom:'.$key;
$columns[$full_key] = array(
'table' => 'appsearch_order_'.$digest,
'column' => 'indexValue',
'type' => $index->getIndexValueType(),
'null' => 'tail',
);
}
}
return $columns;
}
/**
* @task order
*/
final protected function buildOrderClause(AphrontDatabaseConnection $conn) {
$orderable = $this->getOrderableColumns();
$vector = $this->getOrderVector();
$parts = array();
foreach ($vector as $order) {
$part = $orderable[$order->getOrderKey()];
if ($order->getIsReversed()) {
$part['reverse'] = !idx($part, 'reverse', false);
}
$parts[] = $part;
}
return $this->formatOrderClause($conn, $parts);
}
/**
* @task order
*/
protected function formatOrderClause(
AphrontDatabaseConnection $conn,
array $parts) {
$is_query_reversed = false;
if ($this->getBeforeID()) {
$is_query_reversed = !$is_query_reversed;
}
$sql = array();
foreach ($parts as $key => $part) {
$is_column_reversed = !empty($part['reverse']);
$descending = true;
if ($is_query_reversed) {
$descending = !$descending;
}
if ($is_column_reversed) {
$descending = !$descending;
}
$table = idx($part, 'table');
$column = $part['column'];
if ($table !== null) {
$field = qsprintf($conn, '%T.%T', $table, $column);
} else {
$field = qsprintf($conn, '%T', $column);
}
$null = idx($part, 'null');
if ($null) {
switch ($null) {
case 'head':
$null_field = qsprintf($conn, '(%Q IS NULL)', $field);
break;
case 'tail':
$null_field = qsprintf($conn, '(%Q IS NOT NULL)', $field);
break;
default:
throw new Exception(
pht(
'NULL value "%s" is invalid. Valid values are "head" and '.
'"tail".',
$null));
}
if ($descending) {
$sql[] = qsprintf($conn, '%Q DESC', $null_field);
} else {
$sql[] = qsprintf($conn, '%Q ASC', $null_field);
}
}
if ($descending) {
$sql[] = qsprintf($conn, '%Q DESC', $field);
} else {
$sql[] = qsprintf($conn, '%Q ASC', $field);
}
}
return qsprintf($conn, 'ORDER BY %Q', implode(', ', $sql));
}
/* -( Application Search )------------------------------------------------- */
/**
* Constrain the query with an ApplicationSearch index, requiring field values
* contain at least one of the values in a set.
*
* This constraint can build the most common types of queries, like:
*
* - Find users with shirt sizes "X" or "XL".
* - Find shoes with size "13".
*
* @param PhabricatorCustomFieldIndexStorage Table where the index is stored.
* @param string|list<string> One or more values to filter by.
* @return this
* @task appsearch
*/
public function withApplicationSearchContainsConstraint(
PhabricatorCustomFieldIndexStorage $index,
$value) {
$this->applicationSearchConstraints[] = array(
'type' => $index->getIndexValueType(),
'cond' => '=',
'table' => $index->getTableName(),
'index' => $index->getIndexKey(),
'value' => $value,
);
return $this;
}
/**
* Constrain the query with an ApplicationSearch index, requiring values
* exist in a given range.
*
* This constraint is useful for expressing date ranges:
*
* - Find events between July 1st and July 7th.
*
* The ends of the range are inclusive, so a `$min` of `3` and a `$max` of
* `5` will match fields with values `3`, `4`, or `5`. Providing `null` for
* either end of the range will leave that end of the constraint open.
*
* @param PhabricatorCustomFieldIndexStorage Table where the index is stored.
* @param int|null Minimum permissible value, inclusive.
* @param int|null Maximum permissible value, inclusive.
* @return this
* @task appsearch
*/
public function withApplicationSearchRangeConstraint(
PhabricatorCustomFieldIndexStorage $index,
$min,
$max) {
$index_type = $index->getIndexValueType();
if ($index_type != 'int') {
throw new Exception(
pht(
'Attempting to apply a range constraint to a field with index type '.
'"%s", expected type "%s".',
$index_type,
'int'));
}
$this->applicationSearchConstraints[] = array(
'type' => $index->getIndexValueType(),
'cond' => 'range',
'table' => $index->getTableName(),
'index' => $index->getIndexKey(),
'value' => array($min, $max),
);
return $this;
}
/**
* Order the results by an ApplicationSearch index.
*
* @param PhabricatorCustomField Field to which the index belongs.
* @param PhabricatorCustomFieldIndexStorage Table where the index is stored.
* @param bool True to sort ascending.
* @return this
* @task appsearch
*/
public function withApplicationSearchOrder(
PhabricatorCustomField $field,
PhabricatorCustomFieldIndexStorage $index,
$ascending) {
$this->applicationSearchOrders[] = array(
'key' => $field->getFieldKey(),
'type' => $index->getIndexValueType(),
'table' => $index->getTableName(),
'index' => $index->getIndexKey(),
'ascending' => $ascending,
);
return $this;
}
/**
* Get the name of the query's primary object PHID column, for constructing
* JOIN clauses. Normally (and by default) this is just `"phid"`, but it may
* be something more exotic.
*
* See @{method:getPrimaryTableAlias} if the column needs to be qualified with
* a table alias.
*
* @return string Column name.
* @task appsearch
*/
protected function getApplicationSearchObjectPHIDColumn() {
if ($this->getPrimaryTableAlias()) {
$prefix = $this->getPrimaryTableAlias().'.';
} else {
$prefix = '';
}
return $prefix.'phid';
}
/**
* Determine if the JOINs built by ApplicationSearch might cause each primary
* object to return multiple result rows. Generally, this means the query
* needs an extra GROUP BY clause.
*
* @return bool True if the query may return multiple rows for each object.
* @task appsearch
*/
protected function getApplicationSearchMayJoinMultipleRows() {
foreach ($this->applicationSearchConstraints as $constraint) {
$type = $constraint['type'];
$value = $constraint['value'];
$cond = $constraint['cond'];
switch ($cond) {
case '=':
switch ($type) {
case 'string':
case 'int':
if (count((array)$value) > 1) {
return true;
}
break;
default:
throw new Exception(pht('Unknown index type "%s"!', $type));
}
break;
case 'range':
// NOTE: It's possible to write a custom field where multiple rows
// match a range constraint, but we don't currently ship any in the
// upstream and I can't immediately come up with cases where this
// would make sense.
break;
default:
throw new Exception(pht('Unknown constraint condition "%s"!', $cond));
}
}
return false;
}
/**
* Construct a GROUP BY clause appropriate for ApplicationSearch constraints.
*
* @param AphrontDatabaseConnection Connection executing the query.
* @return string Group clause.
* @task appsearch
*/
protected function buildApplicationSearchGroupClause(
AphrontDatabaseConnection $conn_r) {
if ($this->getApplicationSearchMayJoinMultipleRows()) {
return qsprintf(
$conn_r,
'GROUP BY %Q',
$this->getApplicationSearchObjectPHIDColumn());
} else {
return '';
}
}
/**
* Construct a JOIN clause appropriate for applying ApplicationSearch
* constraints.
*
* @param AphrontDatabaseConnection Connection executing the query.
* @return string Join clause.
* @task appsearch
*/
protected function buildApplicationSearchJoinClause(
AphrontDatabaseConnection $conn_r) {
$joins = array();
foreach ($this->applicationSearchConstraints as $key => $constraint) {
$table = $constraint['table'];
$alias = 'appsearch_'.$key;
$index = $constraint['index'];
$cond = $constraint['cond'];
$phid_column = $this->getApplicationSearchObjectPHIDColumn();
switch ($cond) {
case '=':
$type = $constraint['type'];
switch ($type) {
case 'string':
$constraint_clause = qsprintf(
$conn_r,
'%T.indexValue IN (%Ls)',
$alias,
(array)$constraint['value']);
break;
case 'int':
$constraint_clause = qsprintf(
$conn_r,
'%T.indexValue IN (%Ld)',
$alias,
(array)$constraint['value']);
break;
default:
throw new Exception(pht('Unknown index type "%s"!', $type));
}
$joins[] = qsprintf(
$conn_r,
'JOIN %T %T ON %T.objectPHID = %Q
AND %T.indexKey = %s
AND (%Q)',
$table,
$alias,
$alias,
$phid_column,
$alias,
$index,
$constraint_clause);
break;
case 'range':
list($min, $max) = $constraint['value'];
if (($min === null) && ($max === null)) {
// If there's no actual range constraint, just move on.
break;
}
if ($min === null) {
$constraint_clause = qsprintf(
$conn_r,
'%T.indexValue <= %d',
$alias,
$max);
} else if ($max === null) {
$constraint_clause = qsprintf(
$conn_r,
'%T.indexValue >= %d',
$alias,
$min);
} else {
$constraint_clause = qsprintf(
$conn_r,
'%T.indexValue BETWEEN %d AND %d',
$alias,
$min,
$max);
}
$joins[] = qsprintf(
$conn_r,
'JOIN %T %T ON %T.objectPHID = %Q
AND %T.indexKey = %s
AND (%Q)',
$table,
$alias,
$alias,
$phid_column,
$alias,
$index,
$constraint_clause);
break;
default:
throw new Exception(pht('Unknown constraint condition "%s"!', $cond));
}
}
foreach ($this->applicationSearchOrders as $key => $order) {
$table = $order['table'];
$index = $order['index'];
$alias = 'appsearch_order_'.$index;
$phid_column = $this->getApplicationSearchObjectPHIDColumn();
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T %T ON %T.objectPHID = %Q
AND %T.indexKey = %s',
$table,
$alias,
$alias,
$phid_column,
$alias,
$index);
}
return implode(' ', $joins);
}
+
+/* -( Integration with CustomField )--------------------------------------- */
+
+
+ /**
+ * @task customfield
+ */
protected function getPagingValueMapForCustomFields(
PhabricatorCustomFieldInterface $object) {
// We have to get the current field values on the cursor object.
$fields = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_APPLICATIONSEARCH);
$fields->setViewer($this->getViewer());
$fields->readFieldsFromStorage($object);
$map = array();
foreach ($fields->getFields() as $field) {
$map['custom:'.$field->getFieldKey()] = $field->getValueForStorage();
}
return $map;
}
+
+ /**
+ * @task customfield
+ */
protected function isCustomFieldOrderKey($key) {
$prefix = 'custom:';
return !strncmp($key, $prefix, strlen($prefix));
}
+
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 7:57 PM (5 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
166322
Default Alt Text
(534 KB)

Event Timeline