Something went wrong. Try again.
@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
Something went wrong. Try again.
2.7 kB · 103 lines
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104<?php
/** * This class provides several approaches for querying data from the database: * * # Async queries: Used under MySQLi with MySQLnd. * # Parallel queries: Used under HPHP. * # Multi queries: Used under MySQLi or HPHP. * # Single queries: Used under MySQL. * * The class automatically decides which approach to use. Usage is like with * other futures: * * $futures = array(); * $futures[] = new QueryFuture($conn1, 'SELECT 1'); * $futures[] = new QueryFuture($conn1, 'DELETE FROM table'); * $futures[] = new QueryFuture($conn2, 'SELECT 2'); * * foreach (new FutureIterator($futures) as $future) { * try { * $result = $future->resolve(); * } catch (AphrontQueryException $ex) { * } * } * * `$result` contains a list of dicts for select queries or number of modified * rows for modification queries. */final class QueryFuture extends Future {
private static $futures = array();
private $conn; private $query; private $id; private $async; private $profilerCallID;
public function __construct( AphrontDatabaseConnection $conn, $pattern/* , ... */) {
$this->conn = $conn;
$args = func_get_args(); $args = array_slice($args, 2); $this->query = vqsprintf($conn, $pattern, $args);
self::$futures[] = $this; $this->id = last_key(self::$futures); }
public function isReady() { if ($this->canResolve()) { return true; }
if (!$this->async) { $profiler = PhutilServiceProfiler::getInstance(); $this->profilerCallID = $profiler->beginServiceCall( array( 'type' => 'query', 'query' => $this->query, 'async' => true, ));
$this->async = $this->conn->asyncQuery($this->query); return false; }
$conns = array(); $asyncs = array(); foreach (self::$futures as $id => $future) { if ($future->async) { $conns[$id] = $future->conn; $asyncs[$id] = $future->async; } }
$this->processResults($this->conn->resolveAsyncQueries($conns, $asyncs));
if ($this->canResolve()) { return true; } return false; }
private function processResults(array $results) { foreach ($results as $id => $result) { $future = self::$futures[$id]; if ($result instanceof Exception) { $future->exception = $result; } else { $future->result = $result; } unset(self::$futures[$id]); if ($future->profilerCallID) { $profiler = PhutilServiceProfiler::getInstance(); $profiler->endServiceCall($future->profilerCallID, array()); } } }}