Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34768411
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
12 KB
Subscribers
None
View Options
diff --git a/src/aphront/storage/connection/mysql/AphrontMySQLDatabaseConnection.php b/src/aphront/storage/connection/mysql/AphrontMySQLDatabaseConnection.php
index 7371863..40a2c6c 100644
--- a/src/aphront/storage/connection/mysql/AphrontMySQLDatabaseConnection.php
+++ b/src/aphront/storage/connection/mysql/AphrontMySQLDatabaseConnection.php
@@ -1,233 +1,233 @@
<?php
final class AphrontMySQLDatabaseConnection
extends AphrontBaseMySQLDatabaseConnection {
public function escapeUTF8String($string) {
$this->validateUTF8String($string);
return $this->escapeBinaryString($string);
}
public function escapeBinaryString($string) {
return mysql_real_escape_string($string, $this->requireConnection());
}
public function getInsertID() {
return mysql_insert_id($this->requireConnection());
}
public function getAffectedRows() {
return mysql_affected_rows($this->requireConnection());
}
protected function closeConnection() {
mysql_close($this->requireConnection());
}
protected function connect() {
if (!function_exists('mysql_connect')) {
// We have to '@' the actual call since it can spew all sorts of silly
// noise, but it will also silence fatals caused by not having MySQL
// installed, which has bitten me on three separate occasions. Make sure
// such failures are explicit and loud.
throw new Exception(
pht(
'About to call %s, but the PHP MySQL extension is not available!',
'mysql_connect()'));
}
$user = $this->getConfiguration('user');
$host = $this->getConfiguration('host');
$port = $this->getConfiguration('port');
if ($port) {
$host .= ':'.$port;
}
$database = $this->getConfiguration('database');
$pass = $this->getConfiguration('pass');
if ($pass instanceof PhutilOpaqueEnvelope) {
$pass = $pass->openEnvelope();
}
$timeout = $this->getConfiguration('timeout');
$timeout_ini = 'mysql.connect_timeout';
if ($timeout) {
$old_timeout = ini_get($timeout_ini);
ini_set($timeout_ini, $timeout);
}
try {
$conn = @mysql_connect(
$host,
$user,
$pass,
$new_link = true,
$flags = 0);
} catch (Exception $ex) {
if ($timeout) {
ini_set($timeout_ini, $old_timeout);
}
throw $ex;
}
if ($timeout) {
ini_set($timeout_ini, $old_timeout);
}
if (!$conn) {
$errno = mysql_errno();
$error = mysql_error();
$this->throwConnectionException($errno, $error, $user, $host);
}
if ($database !== null) {
$ret = @mysql_select_db($database, $conn);
if (!$ret) {
$this->throwQueryException($conn);
}
}
$ok = @mysql_set_charset('utf8mb4', $conn);
if (!$ok) {
- mysql_set_charset('utf8', $conn);
+ mysql_set_charset('binary', $conn);
}
return $conn;
}
protected function rawQuery($raw_query) {
return @mysql_query($raw_query, $this->requireConnection());
}
/**
* @phutil-external-symbol function mysql_multi_query
* @phutil-external-symbol function mysql_fetch_result
* @phutil-external-symbol function mysql_more_results
* @phutil-external-symbol function mysql_next_result
*/
protected function rawQueries(array $raw_queries) {
$conn = $this->requireConnection();
$results = array();
if (!function_exists('mysql_multi_query')) {
foreach ($raw_queries as $key => $raw_query) {
$results[$key] = $this->processResult($this->rawQuery($raw_query));
}
return $results;
}
if (!mysql_multi_query(implode("\n;\n\n", $raw_queries), $conn)) {
$ex = $this->processResult(false);
return array_fill_keys(array_keys($raw_queries), $ex);
}
$processed_all = false;
foreach ($raw_queries as $key => $raw_query) {
$results[$key] = $this->processResult(@mysql_fetch_result($conn));
if (!mysql_more_results($conn)) {
$processed_all = true;
break;
}
mysql_next_result($conn);
}
if (!$processed_all) {
throw new Exception(
pht('There are some results left in the result set.'));
}
return $results;
}
protected function freeResult($result) {
mysql_free_result($result);
}
public function supportsParallelQueries() {
// fb_parallel_query() doesn't support results with different columns.
return false;
}
/**
* @phutil-external-symbol function fb_parallel_query
*/
public function executeParallelQueries(
array $queries,
array $conns = array()) {
assert_instances_of($conns, __CLASS__);
$map = array();
$is_write = false;
foreach ($queries as $id => $query) {
$is_write = $is_write || $this->checkWrite($query);
$conn = idx($conns, $id, $this);
$host = $conn->getConfiguration('host');
$port = 0;
$match = null;
if (preg_match('/(.+):(.+)/', $host, $match)) {
list(, $host, $port) = $match;
}
$pass = $conn->getConfiguration('pass');
if ($pass instanceof PhutilOpaqueEnvelope) {
$pass = $pass->openEnvelope();
}
$map[$id] = array(
'sql' => $query,
'ip' => $host,
'port' => $port,
'username' => $conn->getConfiguration('user'),
'password' => $pass,
'db' => $conn->getConfiguration('database'),
);
}
$profiler = PhutilServiceProfiler::getInstance();
$call_id = $profiler->beginServiceCall(
array(
'type' => 'multi-query',
'queries' => $queries,
'write' => $is_write,
));
$map = fb_parallel_query($map);
$profiler->endServiceCall($call_id, array());
$results = array();
$pos = 0;
$err_pos = 0;
foreach ($queries as $id => $query) {
$errno = idx(idx($map, 'errno', array()), $err_pos);
$err_pos++;
if ($errno) {
try {
$this->throwQueryCodeException($errno, $map['error'][$id]);
} catch (Exception $ex) {
$results[$id] = $ex;
}
continue;
}
$results[$id] = $map['result'][$pos];
$pos++;
}
return $results;
}
protected function fetchAssoc($result) {
return mysql_fetch_assoc($result);
}
protected function getErrorCode($connection) {
return mysql_errno($connection);
}
protected function getErrorDescription($connection) {
return mysql_error($connection);
}
}
diff --git a/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php b/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
index f3c5d88..240dff4 100644
--- a/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
+++ b/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
@@ -1,199 +1,199 @@
<?php
/**
* @phutil-external-symbol class mysqli
*/
final class AphrontMySQLiDatabaseConnection
extends AphrontBaseMySQLDatabaseConnection {
public function escapeUTF8String($string) {
$this->validateUTF8String($string);
return $this->escapeBinaryString($string);
}
public function escapeBinaryString($string) {
return $this->requireConnection()->escape_string($string);
}
public function getInsertID() {
return $this->requireConnection()->insert_id;
}
public function getAffectedRows() {
return $this->requireConnection()->affected_rows;
}
protected function closeConnection() {
$this->requireConnection()->close();
}
protected function connect() {
if (!class_exists('mysqli', false)) {
throw new Exception(pht(
'About to call new %s, but the PHP MySQLi extension is not available!',
'mysqli()'));
}
$user = $this->getConfiguration('user');
$host = $this->getConfiguration('host');
$port = $this->getConfiguration('port');
$database = $this->getConfiguration('database');
$pass = $this->getConfiguration('pass');
if ($pass instanceof PhutilOpaqueEnvelope) {
$pass = $pass->openEnvelope();
}
// If the host is "localhost", the port is ignored and mysqli attempts to
// connect over a socket.
if ($port) {
if ($host === 'localhost' || $host === null) {
$host = '127.0.0.1';
}
}
$conn = mysqli_init();
$timeout = $this->getConfiguration('timeout');
if ($timeout) {
$conn->options(MYSQLI_OPT_CONNECT_TIMEOUT, $timeout);
}
@$conn->real_connect(
$host,
$user,
$pass,
$database,
$port);
$errno = $conn->connect_errno;
if ($errno) {
$error = $conn->connect_error;
$this->throwConnectionException($errno, $error, $user, $host);
}
$ok = @$conn->set_charset('utf8mb4');
if (!$ok) {
- $ok = $conn->set_charset('utf8');
+ $ok = $conn->set_charset('binary');
}
return $conn;
}
protected function rawQuery($raw_query) {
$conn = $this->requireConnection();
$time_limit = $this->getQueryTimeout();
// If we have a query time limit, run this query synchronously but use
// the async API. This allows us to kill queries which take too long
// without requiring any configuration on the server side.
if ($time_limit && $this->supportsAsyncQueries()) {
$conn->query($raw_query, MYSQLI_ASYNC);
$read = array($conn);
$error = array($conn);
$reject = array($conn);
$result = mysqli::poll($read, $error, $reject, $time_limit);
if ($result === false) {
$this->closeConnection();
throw new Exception(
pht('Failed to poll mysqli connection!'));
} else if ($result === 0) {
$this->closeConnection();
throw new AphrontQueryTimeoutQueryException(
pht(
'Query timed out after %s second(s)!',
new PhutilNumber($time_limit)));
}
return @$conn->reap_async_query();
}
return @$conn->query($raw_query);
}
protected function rawQueries(array $raw_queries) {
$conn = $this->requireConnection();
$have_result = false;
$results = array();
foreach ($raw_queries as $key => $raw_query) {
if (!$have_result) {
// End line in front of semicolon to allow single line comments at the
// end of queries.
$have_result = $conn->multi_query(implode("\n;\n\n", $raw_queries));
} else {
$have_result = $conn->next_result();
}
array_shift($raw_queries);
$result = $conn->store_result();
if (!$result && !$this->getErrorCode($conn)) {
$result = true;
}
$results[$key] = $this->processResult($result);
}
if ($conn->more_results()) {
throw new Exception(
pht('There are some results left in the result set.'));
}
return $results;
}
protected function freeResult($result) {
$result->free_result();
}
protected function fetchAssoc($result) {
return $result->fetch_assoc();
}
protected function getErrorCode($connection) {
return $connection->errno;
}
protected function getErrorDescription($connection) {
return $connection->error;
}
public function supportsAsyncQueries() {
return defined('MYSQLI_ASYNC');
}
public function asyncQuery($raw_query) {
$this->checkWrite($raw_query);
$async = $this->beginAsyncConnection();
$async->query($raw_query, MYSQLI_ASYNC);
return $async;
}
public static function resolveAsyncQueries(array $conns, array $asyncs) {
assert_instances_of($conns, __CLASS__);
assert_instances_of($asyncs, 'mysqli');
$read = $error = $reject = array();
foreach ($asyncs as $async) {
$read[] = $error[] = $reject[] = $async;
}
if (!mysqli::poll($read, $error, $reject, 0)) {
return array();
}
$results = array();
foreach ($read as $async) {
$key = array_search($async, $asyncs, $strict = true);
$conn = $conns[$key];
$conn->endAsyncConnection($async);
$results[$key] = $conn->processResult($async->reap_async_query());
}
return $results;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Jan 25, 7:14 AM (1 d, 20 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
7d/d8/bc2825af9f734a6ff1237b30b3b9
Attached To
rPHUTIL libphutil
Event Timeline
Log In to Comment