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