Some fixes and new classes

master
Vitaliy Filippov 2013-03-29 20:57:58 +00:00
parent cfd6ddddd9
commit 0e848aff3b
1 changed files with 42 additions and 27 deletions

View File

@ -32,6 +32,7 @@ class DatabaseMysql implements Database
var $tableNames = array(); var $tableNames = array();
var $queryLogFile; var $queryLogFile;
var $reconnect = true; var $reconnect = true;
var $autoBegin;
var $ondestroy = 'commit'; var $ondestroy = 'commit';
var $queryCount = 0; var $queryCount = 0;
@ -51,6 +52,7 @@ class DatabaseMysql implements Database
* tableNames Table name mappings (virtual => real) * tableNames Table name mappings (virtual => real)
* queryLogFile Path to query log file * queryLogFile Path to query log file
* reconnect Whether to reconnect on idle timeout [true] * reconnect Whether to reconnect on idle timeout [true]
* autoBegin Whether to automatically begin a transaction of first query [false]
* ondestroy commit/rollback/none during destruction [commit] * ondestroy commit/rollback/none during destruction [commit]
*/ */
function __construct($options) function __construct($options)
@ -65,6 +67,7 @@ class DatabaseMysql implements Database
'reconnect' => true, 'reconnect' => true,
'tableNames' => array(), 'tableNames' => array(),
'queryLogFile' => '', 'queryLogFile' => '',
'autoBegin' => false,
'ondestroy' => 'commit', 'ondestroy' => 'commit',
); );
$options += $defOpts; $options += $defOpts;
@ -112,6 +115,10 @@ class DatabaseMysql implements Database
else else
{ {
$this->link->set_charset('utf8'); $this->link->set_charset('utf8');
if ($this->autoBegin)
{
$this->begin();
}
} }
} }
@ -129,12 +136,12 @@ class DatabaseMysql implements Database
{ {
$i = 0; $i = 0;
$r = ''; $r = '';
while (($p = strrpos($str, '?')) !== false) while (($p = strpos($str, '?')) !== false)
{ {
$r = $this->quote($params[$i++]) . substr($str, $p+1) . $r; $r .= substr($str, 0, $p) . $this->quote($params[$i++]);
$str = substr($str, 0, $p); $str = substr($str, $p+1);
} }
return $str.$r; return $r.$str;
} }
function quote($value) function quote($value)
@ -152,15 +159,15 @@ class DatabaseMysql implements Database
function query($sql, $fetchMode = MYSQLI_STORE_RESULT) function query($sql, $fetchMode = MYSQLI_STORE_RESULT)
{ {
if (!$this->link)
{
$this->connect();
}
$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); file_put_contents($this->queryLogFile, date("[Y-m-d H:i:s] ").$sql."\n", FILE_APPEND);
} }
if (!$this->link)
{
$this->connect();
}
$r = $this->link->query($sql, $fetchMode); $r = $this->link->query($sql, $fetchMode);
if (!$r) if (!$r)
{ {
@ -184,6 +191,10 @@ class DatabaseMysql implements Database
function multi_select(array $queries, $format = 0) function multi_select(array $queries, $format = 0)
{ {
if (!$this->link)
{
$this->connect();
}
$this->queryCount += count($queries); $this->queryCount += count($queries);
$log = ''; $log = '';
foreach ($queries as &$sql) foreach ($queries as &$sql)
@ -199,10 +210,6 @@ class DatabaseMysql implements Database
{ {
file_put_contents($this->queryLogFile, $log, FILE_APPEND); file_put_contents($this->queryLogFile, $log, FILE_APPEND);
} }
if (!$this->link)
{
$this->connect();
}
$sql = implode('; ', $queries); $sql = implode('; ', $queries);
$r = $this->link->multi_query($sql); $r = $this->link->multi_query($sql);
if (!$r) if (!$r)
@ -223,10 +230,15 @@ class DatabaseMysql implements Database
} }
} }
$results = array(); $results = array();
$i = 0;
foreach ($queries as $k => $q) foreach ($queries as $k => $q)
{ {
if ($i++)
{
$this->link->next_result();
}
$r = $this->link->store_result();
$results[$k] = $this->fetch_all($r, $format); $results[$k] = $this->fetch_all($r, $format);
$this->link->next_result();
} }
return $results; return $results;
} }
@ -356,15 +368,15 @@ class DatabaseMysql implements Database
else else
$wh[] = "$k IS NULL"; $wh[] = "$k IS NULL";
} }
if (!$wh) if (!$this->username && !$this->password && !$this->dbname)
$where = '1';
elseif (!$this->username && !$this->password && !$this->dbname)
{ {
// Sphinx supports neither brackets nor OR operator as of 2.0.6-release O_o // Sphinx supports neither brackets nor OR operator as of 2.0.6-release O_o
$where = join(' AND ', $wh); $where = join(' AND ', $wh);
} }
else elseif ($where)
$where = '(' . join(') AND (', $wh) . ')'; $where = '(' . join(') AND (', $wh) . ')';
else
$where = '';
return $where; return $where;
} }
@ -383,7 +395,7 @@ class DatabaseMysql implements Database
* 'FOR UPDATE' or 'LOCK IN SHARE MODE' * 'FOR UPDATE' or 'LOCK IN SHARE MODE'
* 'GROUP BY' => array($groupby_field1 => 'ASC', $groupby_field2 => 'DESC') * 'GROUP BY' => array($groupby_field1 => 'ASC', $groupby_field2 => 'DESC')
* 'ORDER BY' => array($orderby_field1 => 'ASC', $orderby_field2 => 'DESC') * 'ORDER BY' => array($orderby_field1 => 'ASC', $orderby_field2 => 'DESC')
* 'LIMIT' => array($limit, $offset) or array($limit) or just $limit * 'LIMIT' => array($offset, $limit) or array($limit) or just $limit
* 'OFFSET' => $offset, for the case when 'LIMIT' is just $limit * 'OFFSET' => $offset, for the case when 'LIMIT' is just $limit
* *
* Sphinx Search extensions: * Sphinx Search extensions:
@ -415,7 +427,11 @@ class DatabaseMysql implements Database
$sql .= 'SQL_NO_CACHE '; $sql .= 'SQL_NO_CACHE ';
elseif (isset($options['CACHE']) || isset($options['SQL_CACHE'])) elseif (isset($options['CACHE']) || isset($options['SQL_CACHE']))
$sql .= 'SQL_CACHE '; $sql .= 'SQL_CACHE ';
$sql .= "$fields FROM $tables WHERE $where"; $sql .= "$fields FROM $tables";
if ($where)
{
$sql .= " WHERE $where";
}
if (isset($options['GROUP BY'])) if (isset($options['GROUP BY']))
{ {
$sql .= " GROUP BY ".$this->order_option($options['GROUP BY']); $sql .= " GROUP BY ".$this->order_option($options['GROUP BY']);
@ -510,7 +526,7 @@ class DatabaseMysql implements Database
else else
$table = (isset($this->tableNames[$v[1]]) ? $this->quoteId($this->tableNames[$v[1]]) : $v[1]) . ' ' . $k; $table = (isset($this->tableNames[$v[1]]) ? $this->quoteId($this->tableNames[$v[1]]) : $v[1]) . ' ' . $k;
if ($t) if ($t)
$t .= " $join JOIN $table ON ".$this->where_builder($v[2]); $t .= " $join JOIN $table ON ".($this->where_builder($v[2]) ?: '1=1');
else else
$t = $table; $t = $table;
continue; continue;
@ -558,7 +574,7 @@ class DatabaseMysql implements Database
*/ */
function select($tables, $fields = '*', $where = 1, $options = NULL, $format = 0) function select($tables, $fields = '*', $where = 1, $options = NULL, $format = 0)
{ {
if (is_int($fields) || is_string($fields) && ctype_digit($fields)) if (is_int($fields))
{ {
$sql = $tables; $sql = $tables;
$format = $fields; $format = $fields;
@ -624,7 +640,7 @@ class DatabaseMysql implements Database
function delete($tables, $where, $options = NULL) function delete($tables, $where, $options = NULL)
{ {
$tables = $this->tables_builder($tables); $tables = $this->tables_builder($tables);
$where = $this->where_builder($where); $where = $this->where_builder($where) ?: '1=1';
$sql = "DELETE FROM $tables WHERE $where"; $sql = "DELETE FROM $tables WHERE $where";
$sql .= $this->limit_option($options); $sql .= $this->limit_option($options);
$this->query($sql); $this->query($sql);
@ -653,8 +669,9 @@ class DatabaseMysql implements Database
$rs[] = $this->quote($r[$k]); $rs[] = $this->quote($r[$k]);
$r = "(".implode(",", $rs).")"; $r = "(".implode(",", $rs).")";
} }
$sphinx = !$this->username && !$this->password && !$this->dbname;
foreach ($key as &$k) foreach ($key as &$k)
if (strpos($k, '`') === false) if (strpos($k, '`') === false && (!$sphinx || $k !== 'id'))
$k = $this->quoteId($k); $k = $this->quoteId($k);
$sql = ($replace ? "REPLACE" : "INSERT"). $sql = ($replace ? "REPLACE" : "INSERT").
" INTO $table (".implode(",",$key).") VALUES ".implode(",",$rows); " INTO $table (".implode(",",$key).") VALUES ".implode(",",$rows);
@ -715,16 +732,14 @@ class DatabaseMysql implements Database
else else
{ {
$sql = array(); $sql = array();
if (!is_array($rows)) foreach ((array)$rows as $k => $v)
$rows = array($rows);
foreach ($rows as $k => $v)
{ {
if (!ctype_digit("$k")) if (!ctype_digit("$k"))
$sql[] = $k.'='.$this->quote($v); $sql[] = $k.'='.$this->quote($v);
else else
$sql[] = $v; $sql[] = $v;
} }
$where = $this->where_builder($where); $where = $this->where_builder($where) ?: '1=1';
$sql = 'UPDATE ' . $this->tables_builder($table) . ' SET ' . implode(', ', $sql) . ' WHERE ' . $where; $sql = 'UPDATE ' . $this->tables_builder($table) . ' SET ' . implode(', ', $sql) . ' WHERE ' . $where;
$sql .= $this->limit_option($options); $sql .= $this->limit_option($options);
} }