Path: blob/master/src/infrastructure/storage/connection/mysql/AphrontMySQLDatabaseConnection.php
12242 views
<?php12final class AphrontMySQLDatabaseConnection3extends AphrontBaseMySQLDatabaseConnection {45public function escapeUTF8String($string) {6$this->validateUTF8String($string);7return $this->escapeBinaryString($string);8}910public function escapeBinaryString($string) {11return mysql_real_escape_string($string, $this->requireConnection());12}1314public function getInsertID() {15return mysql_insert_id($this->requireConnection());16}1718public function getAffectedRows() {19return mysql_affected_rows($this->requireConnection());20}2122protected function closeConnection() {23mysql_close($this->requireConnection());24}2526protected function connect() {27if (!function_exists('mysql_connect')) {28// We have to '@' the actual call since it can spew all sorts of silly29// noise, but it will also silence fatals caused by not having MySQL30// installed, which has bitten me on three separate occasions. Make sure31// such failures are explicit and loud.32throw new Exception(33pht(34'About to call %s, but the PHP MySQL extension is not available!',35'mysql_connect()'));36}3738$user = $this->getConfiguration('user');39$host = $this->getConfiguration('host');40$port = $this->getConfiguration('port');4142if ($port) {43$host .= ':'.$port;44}4546$database = $this->getConfiguration('database');4748$pass = $this->getConfiguration('pass');49if ($pass instanceof PhutilOpaqueEnvelope) {50$pass = $pass->openEnvelope();51}5253$timeout = $this->getConfiguration('timeout');54$timeout_ini = 'mysql.connect_timeout';55if ($timeout) {56$old_timeout = ini_get($timeout_ini);57ini_set($timeout_ini, $timeout);58}5960try {61$conn = @mysql_connect(62$host,63$user,64$pass,65$new_link = true,66$flags = 0);67} catch (Exception $ex) {68if ($timeout) {69ini_set($timeout_ini, $old_timeout);70}71throw $ex;72}7374if ($timeout) {75ini_set($timeout_ini, $old_timeout);76}7778if (!$conn) {79$errno = mysql_errno();80$error = mysql_error();81$this->throwConnectionException($errno, $error, $user, $host);82}8384if ($database !== null) {85$ret = @mysql_select_db($database, $conn);86if (!$ret) {87$this->throwQueryException($conn);88}89}9091$ok = @mysql_set_charset('utf8mb4', $conn);92if (!$ok) {93mysql_set_charset('binary', $conn);94}9596return $conn;97}9899protected function rawQuery($raw_query) {100return @mysql_query($raw_query, $this->requireConnection());101}102103/**104* @phutil-external-symbol function mysql_multi_query105* @phutil-external-symbol function mysql_fetch_result106* @phutil-external-symbol function mysql_more_results107* @phutil-external-symbol function mysql_next_result108*/109protected function rawQueries(array $raw_queries) {110$conn = $this->requireConnection();111$results = array();112113if (!function_exists('mysql_multi_query')) {114foreach ($raw_queries as $key => $raw_query) {115$results[$key] = $this->processResult($this->rawQuery($raw_query));116}117return $results;118}119120if (!mysql_multi_query(implode("\n;\n\n", $raw_queries), $conn)) {121$ex = $this->processResult(false);122return array_fill_keys(array_keys($raw_queries), $ex);123}124125$processed_all = false;126foreach ($raw_queries as $key => $raw_query) {127$results[$key] = $this->processResult(@mysql_fetch_result($conn));128if (!mysql_more_results($conn)) {129$processed_all = true;130break;131}132mysql_next_result($conn);133}134135if (!$processed_all) {136throw new Exception(137pht('There are some results left in the result set.'));138}139140return $results;141}142143protected function freeResult($result) {144mysql_free_result($result);145}146147public function supportsParallelQueries() {148// fb_parallel_query() doesn't support results with different columns.149return false;150}151152/**153* @phutil-external-symbol function fb_parallel_query154*/155public function executeParallelQueries(156array $queries,157array $conns = array()) {158assert_instances_of($conns, __CLASS__);159160$map = array();161$is_write = false;162foreach ($queries as $id => $query) {163$is_write = $is_write || $this->checkWrite($query);164$conn = idx($conns, $id, $this);165166$host = $conn->getConfiguration('host');167$port = 0;168$match = null;169if (preg_match('/(.+):(.+)/', $host, $match)) {170list(, $host, $port) = $match;171}172173$pass = $conn->getConfiguration('pass');174if ($pass instanceof PhutilOpaqueEnvelope) {175$pass = $pass->openEnvelope();176}177178$map[$id] = array(179'sql' => $query,180'ip' => $host,181'port' => $port,182'username' => $conn->getConfiguration('user'),183'password' => $pass,184'db' => $conn->getConfiguration('database'),185);186}187188$profiler = PhutilServiceProfiler::getInstance();189$call_id = $profiler->beginServiceCall(190array(191'type' => 'multi-query',192'queries' => $queries,193'write' => $is_write,194));195196$map = fb_parallel_query($map);197198$profiler->endServiceCall($call_id, array());199200$results = array();201$pos = 0;202$err_pos = 0;203foreach ($queries as $id => $query) {204$errno = idx(idx($map, 'errno', array()), $err_pos);205$err_pos++;206if ($errno) {207try {208$this->throwQueryCodeException($errno, $map['error'][$id]);209} catch (Exception $ex) {210$results[$id] = $ex;211}212continue;213}214$results[$id] = $map['result'][$pos];215$pos++;216}217return $results;218}219220protected function fetchAssoc($result) {221return mysql_fetch_assoc($result);222}223224protected function getErrorCode($connection) {225return mysql_errno($connection);226}227228protected function getErrorDescription($connection) {229return mysql_error($connection);230}231232}233234235