diff --git a/DatabaseMysql.php b/DatabaseMysql.php index 20440e8..51d9066 100644 --- a/DatabaseMysql.php +++ b/DatabaseMysql.php @@ -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); }