@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at recaptime-dev/main 169 lines 3.5 kB view raw
1<?php 2 3final class PhabricatorFactChartFunction 4 extends PhabricatorChartFunction { 5 6 const FUNCTIONKEY = 'fact'; 7 8 private $fact; 9 private $map; 10 private $refs; 11 12 protected function newArguments() { 13 $key_argument = $this->newArgument() 14 ->setName('fact-key') 15 ->setType('fact-key'); 16 17 $parser = $this->getArgumentParser(); 18 $parser->parseArgument($key_argument); 19 20 $fact = $this->getArgument('fact-key'); 21 $this->fact = $fact; 22 23 return $fact->getFunctionArguments(); 24 } 25 26 public function loadData() { 27 $fact = $this->fact; 28 29 $key_id = id(new PhabricatorFactKeyDimension()) 30 ->newDimensionID($fact->getKey()); 31 if (!$key_id) { 32 $this->map = array(); 33 return; 34 } 35 36 $table = $fact->newDatapoint(); 37 $conn = $table->establishConnection('r'); 38 $table_name = $table->getTableName(); 39 40 $where = array(); 41 42 $where[] = qsprintf( 43 $conn, 44 'keyID = %d', 45 $key_id); 46 47 $parser = $this->getArgumentParser(); 48 49 $parts = $fact->buildWhereClauseParts($conn, $parser); 50 foreach ($parts as $part) { 51 $where[] = $part; 52 } 53 54 $data = queryfx_all( 55 $conn, 56 'SELECT id, value, epoch FROM %T WHERE %LA ORDER BY epoch ASC', 57 $table_name, 58 $where); 59 60 $map = array(); 61 $refs = array(); 62 if ($data) { 63 foreach ($data as $row) { 64 $ref = (string)$row['id']; 65 $value = (int)$row['value']; 66 $epoch = (int)$row['epoch']; 67 68 if (!isset($map[$epoch])) { 69 $map[$epoch] = 0; 70 } 71 72 $map[$epoch] += $value; 73 74 if (!isset($refs[$epoch])) { 75 $refs[$epoch] = array(); 76 } 77 78 $refs[$epoch][] = $ref; 79 } 80 } 81 82 $this->map = $map; 83 $this->refs = $refs; 84 } 85 86 public function getDomain() { 87 $min = head_key($this->map); 88 $max = last_key($this->map); 89 90 return new PhabricatorChartInterval($min, $max); 91 } 92 93 public function newInputValues(PhabricatorChartDataQuery $query) { 94 return array_keys($this->map); 95 } 96 97 public function evaluateFunction(array $xv) { 98 $map = $this->map; 99 100 $yv = array(); 101 102 foreach ($xv as $x) { 103 if (isset($map[$x])) { 104 $yv[] = $map[$x]; 105 } else { 106 $yv[] = null; 107 } 108 } 109 110 return $yv; 111 } 112 113 public function getDataRefs(array $xv) { 114 return array_select_keys($this->refs, $xv); 115 } 116 117 public function loadRefs(array $refs) { 118 $fact = $this->fact; 119 120 $datapoint_table = $fact->newDatapoint(); 121 $conn = $datapoint_table->establishConnection('r'); 122 123 $dimension_table = new PhabricatorFactObjectDimension(); 124 125 $where = array(); 126 127 $where[] = qsprintf( 128 $conn, 129 'p.id IN (%Ld)', 130 $refs); 131 132 133 $rows = queryfx_all( 134 $conn, 135 'SELECT 136 p.id id, 137 p.value, 138 od.objectPHID objectPHID, 139 dd.objectPHID dimensionPHID 140 FROM %R p 141 LEFT JOIN %R od ON od.id = p.objectID 142 LEFT JOIN %R dd ON dd.id = p.dimensionID 143 WHERE %LA', 144 $datapoint_table, 145 $dimension_table, 146 $dimension_table, 147 $where); 148 $rows = ipull($rows, null, 'id'); 149 150 $results = array(); 151 152 foreach ($refs as $ref) { 153 if (!isset($rows[$ref])) { 154 continue; 155 } 156 157 $row = $rows[$ref]; 158 159 $results[$ref] = array( 160 'objectPHID' => $row['objectPHID'], 161 'dimensionPHID' => $row['dimensionPHID'], 162 'value' => (float)$row['value'], 163 ); 164 } 165 166 return $results; 167 } 168 169}