/** * 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. This is mostly to make sure PhabricatorLiskDAO->attachEdges() // gets some data, so that getEdges() doesn't throw later. 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']); } } foreach ($edges as $edge) { $result[$edge['src']][$edge['type']][$edge['dst']] = $edge; } } return $result; }
/** * Remove queued edges. * * @task internal */ private function executeRemoves() { $rems = $this->remEdges; $rems = igroup($rems, 'src_type'); $deletes = array(); foreach ($rems as $src_type => $edges) { $conn_w = PhabricatorEdgeConfig::establishConnection($src_type, 'w'); $sql = array(); foreach ($edges as $edge) { $sql[] = qsprintf($conn_w, '(%s, %d, %s)', $edge['src'], $edge['type'], $edge['dst']); } $deletes[] = array($conn_w, $sql); } foreach ($deletes as $delete) { list($conn_w, $sql) = $delete; $conn_w->openTransaction(); $this->openTransactions[] = $conn_w; foreach (array_chunk($sql, 256) as $chunk) { queryfx($conn_w, 'DELETE FROM %T WHERE (src, type, dst) IN (%Q)', PhabricatorEdgeConfig::TABLE_NAME_EDGE, implode(', ', $chunk)); } } }