diff --git a/DatabaseMysql.php b/DatabaseMysql.php index 6a2fe43..3c83726 100644 --- a/DatabaseMysql.php +++ b/DatabaseMysql.php @@ -19,9 +19,14 @@ if (!defined('MS_HASH')) class DatabaseException extends Exception {} -class DatabaseMysql +if (!interface_exists('Database')) { - var $host, $port, $socket, $username, $password, $dbName; + interface Database {} +} + +class DatabaseMysql implements Database +{ + var $host, $port, $socket, $username, $password, $dbname; var $tableNames = array(); var $queryLogFile; @@ -34,33 +39,37 @@ class DatabaseMysql /** * Creates a MySQL connection object. * - * @param string $host either 'host', 'host:port', or ':/var/run/mysqld/mysqld.sock' - * @param string $username - * @param string $password - * @param string $dbname - * @param string $port (optional) - * @param string $socket (optional) + * @param array $options Possible options: + * host Host name or IP address to connect to [localhost] + * socket Path to UNIX socket to connect to [/var/run/mysqld/mysqld.sock] + * port TCP port to connect to [3306] + * dbname DB name to use + * username Username + * password Password + * reconnect Whether to reconnect on idle timeout [true] + * queryLogFile Path to query log file */ - function __construct($host, $username, $password, $dbname, $port = NULL, $socket = NULL) + function __construct($options) { - $host = explode(':', $host, 2); - if (!$host[0]) + $defOpts = array( + 'host' => 'localhost', + 'port' => 3306, + 'socket' => '/var/run/mysqld/mysqld.sock', + 'dbname' => '', + 'username' => '', + 'password' => '', + 'reconnect' => true, + 'queryLogFile' => '', + ); + $options += $defOpts; + if ($options['socket']) { - $socket = $host[1]; - $host = 'localhost'; + $options['host'] = 'localhost'; } - else + foreach ($defOpts as $k => $v) { - if (isset($host[1])) - { - $port = $host[1]; - } - $host = $host[0]; + $this->$k = $options[$k]; } - $this->host = $host; - $this->username = $username; - $this->password = $password; - $this->dbname = $dbname; } function connect() @@ -77,7 +86,17 @@ class DatabaseMysql { $this->link = new mysqli($this->host, $this->username, $this->password, $this->dbname); } - $this->link->set_charset('utf8'); + $errno = $this->link->connect_errno; + $error = $this->link->connect_error; + if ($errno) + { + $this->link = NULL; + throw new DatabaseException($error, $errno); + } + else + { + $this->link->set_charset('utf8'); + } } function getDBName() @@ -211,13 +230,13 @@ class DatabaseMysql $wh = array(); foreach ($where as $k => $v) { - if (ctype_digit($k)) + if (ctype_digit("$k")) $wh[] = $v; elseif (is_array($v)) { if (!$v) { - throw new DatabaseException(E_DB_EMPTY_IN, "Error: empty array for '$k IN (...)', don't know what to do"); + throw new DatabaseException("Error: empty array for '$k IN (...)', don't know what to do"); } else { @@ -266,13 +285,13 @@ class DatabaseMysql else { foreach ($options as $k => $v) - if (ctype_digit($k)) + if (ctype_digit("$k")) $options[$v] = true; } if (is_array($fields)) { foreach ($fields as $k => $v) - if (!ctype_digit($k)) + if (!ctype_digit("$k")) $fields[$k] = "$v AS ".$this->quoteId($k); $fields = join(',', $fields); } @@ -294,7 +313,7 @@ class DatabaseMysql $g1 = array(); foreach ($g as $k => $v) { - if (ctype_digit($k)) + if (ctype_digit("$k")) $g1[] = $v; else $g1[] = "$k $v"; @@ -311,7 +330,7 @@ class DatabaseMysql $g1 = array(); foreach ($g as $k => $v) { - if (ctype_digit($k)) + if (ctype_digit("$k")) $g1[] = $v; else $g1[] = "$k $v"; @@ -365,7 +384,7 @@ class DatabaseMysql $t = ''; foreach ($tables as $k => $v) { - if (!ctype_digit($k)) + if (!ctype_digit("$k")) { if (is_array($v)) { @@ -429,7 +448,7 @@ class DatabaseMysql */ function select($tables, $fields = '*', $where = 1, $options = NULL, $format = 0) { - if (ctype_digit("$fields")) + if (is_int($fields) || is_string($fields) && ctype_digit($fields)) { $sql = $tables; $format = $fields; @@ -502,7 +521,7 @@ class DatabaseMysql * @param boolean $onduplicatekey If true, include * ON DUPLICATE KEY UPDATE column=VALUES(column) for all columns. */ - function insert_builder($table, $rows, $onduplicatekey = false) + function insert_builder($table, $rows, $onduplicatekey = false, $replace = false) { if (isset($this->tableNames[$table])) { @@ -519,7 +538,8 @@ class DatabaseMysql foreach ($key as &$k) if (strpos($k, '`') === false) $k = $this->quoteId($k); - $sql = "INSERT INTO $table (".implode(",",$key).") VALUES ".implode(",",$rows); + $sql = ($replace ? "REPLACE" : "INSERT"). + " INTO $table (".implode(",",$key).") VALUES ".implode(",",$rows); if ($onduplicatekey) { foreach ($key as &$k) @@ -560,6 +580,7 @@ class DatabaseMysql * @param array $options Options for update query: * 'LIMIT' => array($limit, $offset) or array($limit) or just $limit * 'OFFSET' => $offset, for the case when 'LIMIT' is just $limit + * 'REPLACE' => true to use REPLACE instead of INSERT */ function update($table, $rows, $where = NULL, $options = NULL) { @@ -569,9 +590,9 @@ class DatabaseMysql { if (!is_array($rows)) return false; - if (!is_array($rows[0])) + if (!is_array(@$rows[0])) $rows = array($rows); - $sql = $this->insert_builder($table, $rows, true); + $sql = $this->insert_builder($table, $rows, true, !empty($options['replace'])); } else { @@ -580,7 +601,7 @@ class DatabaseMysql $rows = array($rows); foreach ($rows as $k => $v) { - if (!ctype_digit($k)) + if (!ctype_digit("$k")) $sql[] = $k.'='.$this->quote($v); else $sql[] = $v;