mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 16:52:41 +01:00
Modernize Drydock Query + Attach code
Summary: Ref T9253. Some of the Drydock code is pretty old. This applies standard modernizations to it: - Modernize Query classes to use stuff like `buildWhereClauseParts()` and `loadStandardPage()`. - Modernize all the getX() / attachX() stuff. In particular: - Require and attach implementations to Blueprints. - Require and attach Blueprints to Resources. - BlueprintImplementations are now always unique per-Blueprint so they can store/cache state if they want without running over one another. - BlueprintImplementations are now passed a `$blueprint`, like other similar APIs (this could go various ways but I generally like this as a balance of concerns). NOTE: This probably doesn't run on its own, I'm just trying to split the next diff (core allocator stuff) up a bit and these pieces are all pretty standard. Test Plan: - Not much; see next revision or two. - Clicked around Resource and Blueprint lists. Reviewers: chad, hach-que Reviewed By: chad, hach-que Maniphest Tasks: T9253 Differential Revision: https://secure.phabricator.com/D14113
This commit is contained in:
parent
635e9c6075
commit
5362d3366c
4 changed files with 104 additions and 58 deletions
|
@ -4,6 +4,7 @@ final class DrydockBlueprintQuery extends DrydockQuery {
|
||||||
|
|
||||||
private $ids;
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
|
private $blueprintClasses;
|
||||||
private $datasourceQuery;
|
private $datasourceQuery;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
|
@ -16,63 +17,89 @@ final class DrydockBlueprintQuery extends DrydockQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withBlueprintClasses(array $classes) {
|
||||||
|
$this->blueprintClasses = $classes;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function withDatasourceQuery($query) {
|
public function withDatasourceQuery($query) {
|
||||||
$this->datasourceQuery = $query;
|
$this->datasourceQuery = $query;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function newResultObject() {
|
||||||
|
return new DrydockBlueprint();
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new DrydockBlueprint();
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
$conn_r = $table->establishConnection('r');
|
}
|
||||||
|
|
||||||
$data = queryfx_all(
|
protected function willFilterPage(array $blueprints) {
|
||||||
$conn_r,
|
$impls = DrydockBlueprintImplementation::getAllBlueprintImplementations();
|
||||||
'SELECT blueprint.* FROM %T blueprint %Q %Q %Q',
|
foreach ($blueprints as $key => $blueprint) {
|
||||||
$table->getTableName(),
|
$impl = idx($impls, $blueprint->getClassName());
|
||||||
$this->buildWhereClause($conn_r),
|
if (!$impl) {
|
||||||
$this->buildOrderClause($conn_r),
|
$this->didRejectResult($blueprint);
|
||||||
$this->buildLimitClause($conn_r));
|
unset($blueprints[$key]);
|
||||||
|
continue;
|
||||||
$blueprints = $table->loadAllFromArray($data);
|
|
||||||
|
|
||||||
$implementations =
|
|
||||||
DrydockBlueprintImplementation::getAllBlueprintImplementations();
|
|
||||||
|
|
||||||
foreach ($blueprints as $blueprint) {
|
|
||||||
if (array_key_exists($blueprint->getClassName(), $implementations)) {
|
|
||||||
$blueprint->attachImplementation(
|
|
||||||
$implementations[$blueprint->getClassName()]);
|
|
||||||
}
|
}
|
||||||
|
$impl = clone $impl;
|
||||||
|
$blueprint->attachImplementation($impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $blueprints;
|
return $blueprints;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
$where = array();
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
if ($this->ids !== null) {
|
if ($this->ids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'id IN (%Ld)',
|
'id IN (%Ld)',
|
||||||
$this->ids);
|
$this->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->phids !== null) {
|
if ($this->phids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'phid IN (%Ls)',
|
'phid IN (%Ls)',
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->datasourceQuery !== null) {
|
if ($this->datasourceQuery !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'blueprintName LIKE %>',
|
'blueprintName LIKE %>',
|
||||||
$this->datasourceQuery);
|
$this->datasourceQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
if ($this->blueprintClasses !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'className IN (%Ls)',
|
||||||
|
$this->blueprintClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $where;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOrderableColumns() {
|
||||||
|
// TODO: Blueprints implement CustomFields, but can not be ordered by
|
||||||
|
// custom field classes because the custom fields are not global. There
|
||||||
|
// is no graceful way to handle this in ApplicationSearch at the moment.
|
||||||
|
// Just brute force around it until we can clean this up.
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'id' => array(
|
||||||
|
'table' => $this->getPrimaryTableAlias(),
|
||||||
|
'column' => 'id',
|
||||||
|
'reverse' => false,
|
||||||
|
'type' => 'int',
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,15 +28,15 @@ final class DrydockLeaseQuery extends DrydockQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function newResultObject() {
|
|
||||||
return new DrydockLease();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function withDatasourceQuery($query) {
|
public function withDatasourceQuery($query) {
|
||||||
$this->datasourceQuery = $query;
|
$this->datasourceQuery = $query;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function newResultObject() {
|
||||||
|
return new DrydockLease();
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
return $this->loadStandardPage($this->newResultObject());
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,71 +39,82 @@ final class DrydockResourceQuery extends DrydockQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function newResultObject() {
|
||||||
|
return new DrydockResource();
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new DrydockResource();
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
$conn_r = $table->establishConnection('r');
|
}
|
||||||
|
|
||||||
$data = queryfx_all(
|
protected function willFilterPage(array $resources) {
|
||||||
$conn_r,
|
$blueprint_phids = mpull($resources, 'getBlueprintPHID');
|
||||||
'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);
|
$blueprints = id(new DrydockBlueprintQuery())
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->withPHIDs($blueprint_phids)
|
||||||
|
->execute();
|
||||||
|
$blueprints = mpull($blueprints, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($resources as $key => $resource) {
|
||||||
|
$blueprint = idx($blueprints, $resource->getBlueprintPHID());
|
||||||
|
if (!$blueprint) {
|
||||||
|
$this->didRejectResult($resource);
|
||||||
|
unset($resources[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$resource->attachBlueprint($blueprint);
|
||||||
|
}
|
||||||
|
|
||||||
return $resources;
|
return $resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
$where = array();
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
if ($this->ids !== null) {
|
if ($this->ids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'id IN (%Ld)',
|
'id IN (%Ld)',
|
||||||
$this->ids);
|
$this->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->phids !== null) {
|
if ($this->phids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'phid IN (%Ls)',
|
'phid IN (%Ls)',
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->types !== null) {
|
if ($this->types !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'type IN (%Ls)',
|
'type IN (%Ls)',
|
||||||
$this->types);
|
$this->types);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->statuses !== null) {
|
if ($this->statuses !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'status IN (%Ls)',
|
'status IN (%Ls)',
|
||||||
$this->statuses);
|
$this->statuses);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->blueprintPHIDs !== null) {
|
if ($this->blueprintPHIDs !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'blueprintPHID IN (%Ls)',
|
'blueprintPHID IN (%Ls)',
|
||||||
$this->blueprintPHIDs);
|
$this->blueprintPHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->datasourceQuery !== null) {
|
if ($this->datasourceQuery !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'name LIKE %>',
|
'name LIKE %>',
|
||||||
$this->datasourceQuery);
|
$this->datasourceQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
return $where;
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ final class DrydockResource extends DrydockDAO
|
||||||
protected $capabilities = array();
|
protected $capabilities = array();
|
||||||
protected $ownerPHID;
|
protected $ownerPHID;
|
||||||
|
|
||||||
private $blueprint;
|
private $blueprint = self::ATTACHABLE;
|
||||||
|
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
|
@ -65,16 +65,24 @@ final class DrydockResource extends DrydockDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlueprint() {
|
public function getBlueprint() {
|
||||||
// TODO: Policy stuff.
|
return $this->assertAttached($this->blueprint);
|
||||||
if (empty($this->blueprint)) {
|
}
|
||||||
$blueprint = id(new DrydockBlueprint())
|
|
||||||
->loadOneWhere('phid = %s', $this->blueprintPHID);
|
public function attachBlueprint(DrydockBlueprint $blueprint) {
|
||||||
$this->blueprint = $blueprint->getImplementation();
|
$this->blueprint = $blueprint;
|
||||||
}
|
return $this;
|
||||||
return $this->blueprint;
|
}
|
||||||
|
|
||||||
|
public function canAllocateLease(DrydockLease $lease) {
|
||||||
|
return $this->getBlueprint()->canAllocateLeaseOnResource(
|
||||||
|
$this,
|
||||||
|
$lease);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function closeResource() {
|
public function closeResource() {
|
||||||
|
|
||||||
|
// TODO: This is super broken and will race other lease writers!
|
||||||
|
|
||||||
$this->openTransaction();
|
$this->openTransaction();
|
||||||
$statuses = array(
|
$statuses = array(
|
||||||
DrydockLeaseStatus::STATUS_PENDING,
|
DrydockLeaseStatus::STATUS_PENDING,
|
||||||
|
|
Loading…
Reference in a new issue