Path: blob/master/src/applications/fact/query/PhabricatorFactDatapointQuery.php
12256 views
<?php12final class PhabricatorFactDatapointQuery extends Phobject {34private $facts;5private $objectPHIDs;6private $limit;78private $needVectors;910private $keyMap = array();11private $dimensionMap = array();1213public function withFacts(array $facts) {14$this->facts = $facts;15return $this;16}1718public function withObjectPHIDs(array $object_phids) {19$this->objectPHIDs = $object_phids;20return $this;21}2223public function setLimit($limit) {24$this->limit = $limit;25return $this;26}2728public function needVectors($need) {29$this->needVectors = $need;30return $this;31}3233public function execute() {34$facts = mpull($this->facts, null, 'getKey');35if (!$facts) {36throw new Exception(pht('Executing a fact query requires facts.'));37}3839$table_map = array();40foreach ($facts as $fact) {41$datapoint = $fact->newDatapoint();42$table = $datapoint->getTableName();4344if (!isset($table_map[$table])) {45$table_map[$table] = array(46'table' => $datapoint,47'facts' => array(),48);49}5051$table_map[$table]['facts'][] = $fact;52}5354$rows = array();55foreach ($table_map as $spec) {56$rows[] = $this->executeWithTable($spec);57}58$rows = array_mergev($rows);5960$key_unmap = array_flip($this->keyMap);61$dimension_unmap = array_flip($this->dimensionMap);6263$groups = array();64$need_phids = array();65foreach ($rows as $row) {66$groups[$row['keyID']][] = $row;6768$object_id = $row['objectID'];69if (!isset($dimension_unmap[$object_id])) {70$need_phids[$object_id] = $object_id;71}7273$dimension_id = $row['dimensionID'];74if ($dimension_id && !isset($dimension_unmap[$dimension_id])) {75$need_phids[$dimension_id] = $dimension_id;76}77}7879$dimension_unmap += id(new PhabricatorFactObjectDimension())80->newDimensionUnmap($need_phids);8182$results = array();83foreach ($groups as $key_id => $rows) {84$key = $key_unmap[$key_id];85$fact = $facts[$key];86$datapoint = $fact->newDatapoint();87foreach ($rows as $row) {88$dimension_id = $row['dimensionID'];89if ($dimension_id) {90if (!isset($dimension_unmap[$dimension_id])) {91continue;92} else {93$dimension_phid = $dimension_unmap[$dimension_id];94}95} else {96$dimension_phid = null;97}9899$object_id = $row['objectID'];100if (!isset($dimension_unmap[$object_id])) {101continue;102} else {103$object_phid = $dimension_unmap[$object_id];104}105106$result = array(107'key' => $key,108'objectPHID' => $object_phid,109'dimensionPHID' => $dimension_phid,110'value' => (int)$row['value'],111'epoch' => $row['epoch'],112);113114if ($this->needVectors) {115$result['vector'] = $datapoint->newRawVector($result);116}117118$results[] = $result;119}120}121122return $results;123}124125private function executeWithTable(array $spec) {126$table = $spec['table'];127$facts = $spec['facts'];128$conn = $table->establishConnection('r');129130$fact_keys = mpull($facts, 'getKey');131$this->keyMap = id(new PhabricatorFactKeyDimension())132->newDimensionMap($fact_keys);133134if (!$this->keyMap) {135return array();136}137138$where = array();139140$where[] = qsprintf(141$conn,142'keyID IN (%Ld)',143$this->keyMap);144145if ($this->objectPHIDs) {146$object_map = id(new PhabricatorFactObjectDimension())147->newDimensionMap($this->objectPHIDs);148if (!$object_map) {149return array();150}151152$this->dimensionMap = $object_map;153154$where[] = qsprintf(155$conn,156'objectID IN (%Ld)',157$this->dimensionMap);158}159160$where = qsprintf($conn, '%LA', $where);161162if ($this->limit) {163$limit = qsprintf(164$conn,165'LIMIT %d',166$this->limit);167} else {168$limit = qsprintf($conn, '');169}170171return queryfx_all(172$conn,173'SELECT keyID, objectID, dimensionID, value, epoch174FROM %T WHERE %Q %Q',175$table->getTableName(),176$where,177$limit);178}179180}181182183