DatabaseMysql updates

master
Vitaliy Filippov 2015-05-12 15:31:49 +00:00
parent db0e0bda54
commit 4d9a65d632
1 changed files with 57 additions and 11 deletions

View File

@ -4,7 +4,8 @@
* Very stable interface for MySQL - object-oriented at last :) * Very stable interface for MySQL - object-oriented at last :)
* Select builder is inspired by MediaWiki's one. * Select builder is inspired by MediaWiki's one.
* Also usable for querying SphinxQL. * Also usable for querying SphinxQL.
* (c) Vitaliy Filippov, 2012-2013 * Version: 2015-05-12
* (c) Vitaliy Filippov, 2012-2015
*/ */
if (!defined('MS_HASH')) if (!defined('MS_HASH'))
@ -18,7 +19,13 @@ if (!defined('MS_HASH'))
define('MS_RESULT', 8); define('MS_RESULT', 8);
} }
class DatabaseException extends Exception {} class DatabaseException extends Exception
{
function isDuplicateKey()
{
return $this->getCode() == 1062;
}
}
if (!interface_exists('Database')) if (!interface_exists('Database'))
{ {
@ -30,7 +37,7 @@ class DatabaseMysql implements Database
var $host, $port, $socket, $username, $password, $dbname; var $host, $port, $socket, $username, $password, $dbname;
var $tableNames = array(); var $tableNames = array();
var $queryLogFile; var $queryLogFile, $loggedQueries = '';
var $reconnect = true; var $reconnect = true;
var $autoBegin; var $autoBegin;
var $ondestroy = 'commit'; var $ondestroy = 'commit';
@ -89,6 +96,10 @@ class DatabaseMysql implements Database
$this->transactions = array(false); $this->transactions = array(false);
$this->$o(); $this->$o();
} }
if ($this->queryLogFile)
{
file_put_contents($this->queryLogFile, $this->loggedQueries, FILE_APPEND);
}
} }
function connect() function connect()
@ -167,7 +178,7 @@ class DatabaseMysql implements Database
$this->queryCount++; $this->queryCount++;
if ($this->queryLogFile) if ($this->queryLogFile)
{ {
file_put_contents($this->queryLogFile, date("[Y-m-d H:i:s] ").$sql."\n", FILE_APPEND); $this->loggedQueries .= date("[Y-m-d H:i:s] ").$sql."\n";
} }
$r = $this->link->query($sql, $fetchMode); $r = $this->link->query($sql, $fetchMode);
if (!$r) if (!$r)
@ -356,11 +367,36 @@ class DatabaseMysql implements Database
else else
{ {
if (is_array(reset($v))) if (is_array(reset($v)))
{
// (a,b) IN ((1,2), (3,4)) ...
foreach ($v as &$l) foreach ($v as &$l)
{
$l = "(" . implode(",", array_map(array($this, 'quote'), $l)) . ")"; $l = "(" . implode(",", array_map(array($this, 'quote'), $l)) . ")";
}
$wh[] = "$k IN (" . implode(",", $v) . ")";
}
else else
$v = array_map(array($this, 'quote'), $v); {
$wh[] = "$k IN (" . implode(",", $v) . ")"; $r = '';
$null = false;
foreach ($v as $i => $l)
{
if ($l === NULL)
{
$null = true;
}
else
{
$r .= $this->quote($l).',';
}
}
$r = $r !== '' ? "$k IN (" . substr($r, 0, -1) . ")" : '';
if ($null)
{
$r = $r !== '' ? "($r OR $k IS NULL)" : "$k IS NULL";
}
$wh[] = $r;
}
} }
} }
elseif (preg_match('/^-?\d+(\.\d+)?$/s', $v)) // int/float elseif (preg_match('/^-?\d+(\.\d+)?$/s', $v)) // int/float
@ -403,6 +439,7 @@ class DatabaseMysql implements Database
* Sphinx Search extensions: * Sphinx Search extensions:
* 'WITHIN GROUP ORDER BY' => array($orderby_field => 'ASC') * 'WITHIN GROUP ORDER BY' => array($orderby_field => 'ASC')
* 'FIELD_WEIGHTS' => array('field' => <weight>, ...) * 'FIELD_WEIGHTS' => array('field' => <weight>, ...)
* 'RANKER' => bm25|sph04|...|expr('...ranker expression...')
*/ */
function select_builder($tables, $fields, $where, $options = NULL) function select_builder($tables, $fields, $where, $options = NULL)
{ {
@ -449,15 +486,24 @@ class DatabaseMysql implements Database
$sql .= " WITHIN GROUP ORDER BY ".$this->order_option($options['WITHIN GROUP ORDER BY']); $sql .= " WITHIN GROUP ORDER BY ".$this->order_option($options['WITHIN GROUP ORDER BY']);
} }
$sql .= $this->limit_option($options); $sql .= $this->limit_option($options);
if (!empty($options['FIELD_WEIGHTS'])) if (!empty($options['FIELD_WEIGHTS']) || !empty($options['RANKER']))
{ {
// Sphinx Search extension // Sphinx Search extension
$weights = array(); $opt = array();
foreach ($options['FIELD_WEIGHTS'] as $f => $w) if (!empty($options['FIELD_WEIGHTS']))
{ {
$weights[] = "`$f`=$w"; $weights = array();
foreach ($options['FIELD_WEIGHTS'] as $f => $w)
{
$weights[] = "`$f`=$w";
}
$opt[] = "field_weights=(".implode(', ', $weights).")";
} }
$sql .= " OPTION field_weights=(".implode(', ', $weights).")"; if (!empty($options['RANKER']))
{
$opt[] = "ranker=".$options['RANKER'];
}
$sql .= " OPTION ".implode(', ', $opt);
} }
if (isset($options['FOR UPDATE'])) if (isset($options['FOR UPDATE']))
$sql .= ' FOR UPDATE'; $sql .= ' FOR UPDATE';