Adding utils & anyValueFallback

This commit is contained in:
Philipp Holzer 2019-04-13 22:46:19 +02:00
parent c97f07f370
commit f4a99d2058
No known key found for this signature in database
GPG Key ID: 517BE60E2CE5C8A5
7 changed files with 34 additions and 30 deletions

View File

@ -169,7 +169,7 @@ class DBA
public static function p($sql)
{
$params = Utils::getParameters(func_get_args());
$params = Util::getParameters(func_get_args());
return self::$db->prepared($sql, $params);
}
@ -177,7 +177,7 @@ class DBA
public static function e($sql)
{
$params = Utils::getParameters(func_get_args());
$params = Util::getParameters(func_get_args());
return self::$db->execute($sql, $params);
}

View File

@ -158,7 +158,7 @@ class Database implements IDatabase, IDatabaseLock
return false;
}
$columns = $this->driver->fetch($stmt);
$columns = $this->driver->fetchRow($stmt);
$this->profiler->saveTimestamp($stamp1, 'database', System::callstack());
@ -476,8 +476,7 @@ class Database implements IDatabase, IDatabaseLock
$logger->warning('Query parameters mismatch.', ['query' => $sql, 'args' => $args, 'callstack' => System::callstack()]);
}
$sql = $this->cleanQuery($sql);
$sql = $this->anyValueFallback($sql);
$sql = Util::cleanQuery($sql);
if ($config->get('system', 'db_callstack') !== null) {
$sql = "/*".System::callstack()." */ ".$sql;
@ -731,7 +730,6 @@ class Database implements IDatabase, IDatabaseLock
}
}
/**
* @brief Callback function for "esc_array"
*

View File

@ -77,4 +77,26 @@ abstract class AbstractDriver implements IDriver
return $sql;
}
/**
* @brief Replaces ANY_VALUE() function by MIN() function,
* if the database server does not support ANY_VALUE().
*
* Considerations for Standard SQL, or MySQL with ONLY_FULL_GROUP_BY (default since 5.7.5).
* ANY_VALUE() is available from MySQL 5.7.5 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html
* A standard fall-back is to use MIN().
*
* @param string $sql An SQL string without the values
*
* @return string The input SQL string modified if necessary.
*/
protected function anyValueFallback($sql)
{
$server_info = $this->getServerInfo();
if (version_compare($server_info, '5.7.5', '<') ||
(stripos($server_info, 'MariaDB') !== false)) {
$sql = str_ireplace('ANY_VALUE(', 'MIN(', $sql);
}
return $sql;
}
}

View File

@ -97,7 +97,7 @@ interface IDriver
*
* @return array
*/
function fetch($stmt);
function fetchRow($stmt);
/**
* Executes a given SQL in context of the current connected database

View File

@ -139,7 +139,7 @@ class MySQLiDriver extends AbstractDriver implements IDriver
*
* @throws DriverException In case of a wrong statement
*/
public function fetch($stmt)
public function fetchRow($stmt)
{
if ($stmt instanceof mysqli_result) {
return $stmt->fetch_assoc();
@ -181,6 +181,8 @@ class MySQLiDriver extends AbstractDriver implements IDriver
*/
public function executePrepared($sql, array $args = [])
{
$sql = $this->anyValueFallback($sql);
// There are SQL statements that cannot be executed with a prepared statement
$parts = explode(' ', $sql);
$command = strtolower($parts[0]);

View File

@ -131,7 +131,7 @@ class PDODriver extends AbstractDriver implements IDriver
*
* @param PDOStatement $stmt
*/
public function fetch($stmt)
public function fetchRow($stmt)
{
return $stmt->fetch(PDO::FETCH_ASSOC);
}
@ -141,6 +141,8 @@ class PDODriver extends AbstractDriver implements IDriver
*/
public function executePrepared($sql, array $args = [])
{
$sql = $this->anyValueFallback($sql);
// If there are no arguments we use "query"
if (count($args) == 0) {
if (!$retval = $this->connection->query($sql)) {

View File

@ -2,7 +2,7 @@
namespace Friendica\Database;
class Utils
class Util
{
/**
* Convert parameter array to an universal form
@ -23,26 +23,6 @@ class Utils
}
}
/**
* @brief Replaces ANY_VALUE() function by MIN() function,
* if the database server does not support ANY_VALUE().
*
* Considerations for Standard SQL, or MySQL with ONLY_FULL_GROUP_BY (default since 5.7.5).
* ANY_VALUE() is available from MySQL 5.7.5 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html
* A standard fall-back is to use MIN().
*
* @param string $sql An SQL string without the values
* @return string The input SQL string modified if necessary.
*/
public static function anyValueFallback($sql) {
$server_info = self::serverInfo();
if (version_compare($server_info, '5.7.5', '<') ||
(stripos($server_info, 'MariaDB') !== false)) {
$sql = str_ireplace('ANY_VALUE(', 'MIN(', $sql);
}
return $sql;
}
/**
* @brief beautifies the query - useful for "SHOW PROCESSLIST"
*