Path: blob/master/src/infrastructure/storage/connection/AphrontDatabaseConnection.php
12241 views
<?php12/**3* @task xaction Transaction Management4*/5abstract class AphrontDatabaseConnection6extends Phobject7implements PhutilQsprintfInterface {89private $transactionState;10private $readOnly;11private $queryTimeout;12private $locks = array();13private $lastActiveEpoch;14private $persistent;1516abstract public function getInsertID();17abstract public function getAffectedRows();18abstract public function selectAllResults();19abstract public function executeQuery(PhutilQueryString $query);20abstract public function executeRawQueries(array $raw_queries);21abstract public function close();22abstract public function openConnection();2324public function __destruct() {25// NOTE: This does not actually close persistent connections: PHP maintains26// them in the connection pool.27$this->close();28}2930final public function setLastActiveEpoch($epoch) {31$this->lastActiveEpoch = $epoch;32return $this;33}3435final public function getLastActiveEpoch() {36return $this->lastActiveEpoch;37}3839final public function setPersistent($persistent) {40$this->persistent = $persistent;41return $this;42}4344final public function getPersistent() {45return $this->persistent;46}4748public function queryData($pattern/* , $arg, $arg, ... */) {49$args = func_get_args();50array_unshift($args, $this);51return call_user_func_array('queryfx_all', $args);52}5354public function query($pattern/* , $arg, $arg, ... */) {55$args = func_get_args();56array_unshift($args, $this);57return call_user_func_array('queryfx', $args);58}596061public function supportsAsyncQueries() {62return false;63}6465public function supportsParallelQueries() {66return false;67}6869public function setReadOnly($read_only) {70$this->readOnly = $read_only;71return $this;72}7374public function getReadOnly() {75return $this->readOnly;76}7778public function setQueryTimeout($query_timeout) {79$this->queryTimeout = $query_timeout;80return $this;81}8283public function getQueryTimeout() {84return $this->queryTimeout;85}8687public function asyncQuery($raw_query) {88throw new Exception(pht('Async queries are not supported.'));89}9091public static function resolveAsyncQueries(array $conns, array $asyncs) {92throw new Exception(pht('Async queries are not supported.'));93}9495/**96* Is this connection idle and safe to close?97*98* A connection is "idle" if it can be safely closed without loss of state.99* Connections inside a transaction or holding locks are not idle, even100* though they may not actively be executing queries.101*102* @return bool True if the connection is idle and can be safely closed.103*/104public function isIdle() {105if ($this->isInsideTransaction()) {106return false;107}108109if ($this->isHoldingAnyLock()) {110return false;111}112113return true;114}115116117/* -( Global Locks )------------------------------------------------------- */118119120public function rememberLock($lock) {121if (isset($this->locks[$lock])) {122throw new Exception(123pht(124'Trying to remember lock "%s", but this lock has already been '.125'remembered.',126$lock));127}128129$this->locks[$lock] = true;130return $this;131}132133134public function forgetLock($lock) {135if (empty($this->locks[$lock])) {136throw new Exception(137pht(138'Trying to forget lock "%s", but this connection does not remember '.139'that lock.',140$lock));141}142143unset($this->locks[$lock]);144return $this;145}146147148public function forgetAllLocks() {149$this->locks = array();150return $this;151}152153154public function isHoldingAnyLock() {155return (bool)$this->locks;156}157158159/* -( Transaction Management )--------------------------------------------- */160161162/**163* Begin a transaction, or set a savepoint if the connection is already164* transactional.165*166* @return this167* @task xaction168*/169public function openTransaction() {170$state = $this->getTransactionState();171$point = $state->getSavepointName();172$depth = $state->getDepth();173174$new_transaction = ($depth == 0);175if ($new_transaction) {176$this->query('START TRANSACTION');177} else {178$this->query('SAVEPOINT '.$point);179}180181$state->increaseDepth();182183return $this;184}185186187/**188* Commit a transaction, or stage a savepoint for commit once the entire189* transaction completes if inside a transaction stack.190*191* @return this192* @task xaction193*/194public function saveTransaction() {195$state = $this->getTransactionState();196$depth = $state->decreaseDepth();197198if ($depth == 0) {199$this->query('COMMIT');200}201202return $this;203}204205206/**207* Rollback a transaction, or unstage the last savepoint if inside a208* transaction stack.209*210* @return this211*/212public function killTransaction() {213$state = $this->getTransactionState();214$depth = $state->decreaseDepth();215216if ($depth == 0) {217$this->query('ROLLBACK');218} else {219$this->query('ROLLBACK TO SAVEPOINT '.$state->getSavepointName());220}221222return $this;223}224225226/**227* Returns true if the connection is transactional.228*229* @return bool True if the connection is currently transactional.230* @task xaction231*/232public function isInsideTransaction() {233$state = $this->getTransactionState();234return ($state->getDepth() > 0);235}236237238/**239* Get the current @{class:AphrontDatabaseTransactionState} object, or create240* one if none exists.241*242* @return AphrontDatabaseTransactionState Current transaction state.243* @task xaction244*/245protected function getTransactionState() {246if (!$this->transactionState) {247$this->transactionState = new AphrontDatabaseTransactionState();248}249return $this->transactionState;250}251252253/**254* @task xaction255*/256public function beginReadLocking() {257$this->getTransactionState()->beginReadLocking();258return $this;259}260261262/**263* @task xaction264*/265public function endReadLocking() {266$this->getTransactionState()->endReadLocking();267return $this;268}269270271/**272* @task xaction273*/274public function isReadLocking() {275return $this->getTransactionState()->isReadLocking();276}277278279/**280* @task xaction281*/282public function beginWriteLocking() {283$this->getTransactionState()->beginWriteLocking();284return $this;285}286287288/**289* @task xaction290*/291public function endWriteLocking() {292$this->getTransactionState()->endWriteLocking();293return $this;294}295296297/**298* @task xaction299*/300public function isWriteLocking() {301return $this->getTransactionState()->isWriteLocking();302}303304}305306307