2012-10-01 02:44:34 +04:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Very stable interface for MySQL - object-oriented at last :)
|
|
|
|
* Select builder is inspired by MediaWiki's one.
|
2013-03-05 19:31:23 +04:00
|
|
|
* Also usable for querying SphinxQL.
|
2018-09-10 14:26:14 +03:00
|
|
|
* Version: 2018-09-10
|
|
|
|
* (c) Vitaliy Filippov, 2012-2018
|
2012-10-01 02:44:34 +04:00
|
|
|
*/
|
|
|
|
|
2018-09-10 15:39:50 +03:00
|
|
|
require_once __DIR__.'/MysqlQueryBuilder.php';
|
|
|
|
|
2012-10-01 02:44:37 +04:00
|
|
|
if (!defined('MS_HASH'))
|
|
|
|
{
|
|
|
|
define('MS_HASH', 0);
|
|
|
|
define('MS_LIST', 1);
|
|
|
|
define('MS_ROW', 2);
|
|
|
|
define('MS_ONE', 2);
|
|
|
|
define('MS_COL', 4);
|
|
|
|
define('MS_VALUE', 6);
|
|
|
|
define('MS_RESULT', 8);
|
|
|
|
}
|
2012-10-01 02:44:34 +04:00
|
|
|
|
2016-05-29 17:36:52 +03:00
|
|
|
if (!class_exists('DatabaseException'))
|
|
|
|
{
|
|
|
|
class DatabaseException extends Exception {}
|
|
|
|
}
|
|
|
|
|
|
|
|
class DatabaseMysqlException extends DatabaseException
|
2015-05-12 18:31:49 +03:00
|
|
|
{
|
|
|
|
function isDuplicateKey()
|
|
|
|
{
|
|
|
|
return $this->getCode() == 1062;
|
|
|
|
}
|
|
|
|
}
|
2012-10-10 02:20:40 +04:00
|
|
|
|
2013-02-18 17:54:46 +04:00
|
|
|
if (!interface_exists('Database'))
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
2013-02-18 17:54:46 +04:00
|
|
|
interface Database {}
|
|
|
|
}
|
|
|
|
|
2018-09-10 15:39:50 +03:00
|
|
|
class DatabaseMysql extends MysqlQueryBuilder implements Database
|
2013-02-18 17:54:46 +04:00
|
|
|
{
|
2018-09-10 14:26:14 +03:00
|
|
|
var $host, $port, $socket, $username, $password, $dbname, $isSphinx;
|
2012-10-01 02:44:37 +04:00
|
|
|
|
2012-10-01 02:44:34 +04:00
|
|
|
var $tableNames = array();
|
2016-05-29 17:36:52 +03:00
|
|
|
var $init = array();
|
2015-05-12 18:31:49 +03:00
|
|
|
var $queryLogFile, $loggedQueries = '';
|
2012-10-10 02:20:40 +04:00
|
|
|
var $reconnect = true;
|
2013-03-30 00:57:58 +04:00
|
|
|
var $autoBegin;
|
2013-03-05 19:31:23 +04:00
|
|
|
var $ondestroy = 'commit';
|
2012-10-10 02:20:40 +04:00
|
|
|
|
|
|
|
var $queryCount = 0;
|
|
|
|
var $link;
|
2013-05-08 13:21:50 +04:00
|
|
|
var $transactions = array();
|
2012-10-01 02:44:34 +04:00
|
|
|
|
2012-10-01 02:44:37 +04:00
|
|
|
/**
|
|
|
|
* Creates a MySQL connection object.
|
|
|
|
*
|
2013-02-18 17:54:46 +04:00
|
|
|
* @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
|
2013-03-05 19:31:23 +04:00
|
|
|
* tableNames Table name mappings (virtual => real)
|
2013-02-18 17:54:46 +04:00
|
|
|
* queryLogFile Path to query log file
|
2013-03-05 19:31:23 +04:00
|
|
|
* reconnect Whether to reconnect on idle timeout [true]
|
2016-05-29 17:36:52 +03:00
|
|
|
* autoBegin Whether to automatically begin a transaction on first query [false]
|
2013-03-05 19:31:23 +04:00
|
|
|
* ondestroy commit/rollback/none during destruction [commit]
|
2016-05-29 17:36:52 +03:00
|
|
|
* init Initialisation queries (array)
|
2012-10-01 02:44:37 +04:00
|
|
|
*/
|
2013-02-18 17:54:46 +04:00
|
|
|
function __construct($options)
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
2013-02-18 17:54:46 +04:00
|
|
|
$defOpts = array(
|
|
|
|
'host' => 'localhost',
|
|
|
|
'port' => 3306,
|
|
|
|
'socket' => '/var/run/mysqld/mysqld.sock',
|
|
|
|
'dbname' => '',
|
|
|
|
'username' => '',
|
|
|
|
'password' => '',
|
|
|
|
'reconnect' => true,
|
2013-03-05 19:31:23 +04:00
|
|
|
'tableNames' => array(),
|
2013-02-18 17:54:46 +04:00
|
|
|
'queryLogFile' => '',
|
2013-03-30 00:57:58 +04:00
|
|
|
'autoBegin' => false,
|
2013-03-05 19:31:23 +04:00
|
|
|
'ondestroy' => 'commit',
|
2016-05-29 17:36:52 +03:00
|
|
|
'init' => array(),
|
2013-02-18 17:54:46 +04:00
|
|
|
);
|
|
|
|
$options += $defOpts;
|
|
|
|
if ($options['socket'])
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
2013-02-18 17:54:46 +04:00
|
|
|
$options['host'] = 'localhost';
|
2012-10-01 02:44:34 +04:00
|
|
|
}
|
2013-02-18 17:54:46 +04:00
|
|
|
foreach ($defOpts as $k => $v)
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
2013-02-18 17:54:46 +04:00
|
|
|
$this->$k = $options[$k];
|
2012-10-01 02:44:37 +04:00
|
|
|
}
|
2018-09-10 14:26:14 +03:00
|
|
|
$this->isSphinx = !$this->username && !$this->password && !$this->dbname;
|
|
|
|
if (!$this->isSphinx)
|
2016-05-29 17:36:52 +03:00
|
|
|
{
|
|
|
|
// READ COMMITTED is more consistent for average usage
|
|
|
|
$this->init[] = 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED';
|
|
|
|
}
|
2012-10-01 02:44:37 +04:00
|
|
|
}
|
|
|
|
|
2013-03-05 19:31:23 +04:00
|
|
|
function __destruct()
|
|
|
|
{
|
|
|
|
$o = $this->ondestroy;
|
|
|
|
if (($o === 'commit' || $o === 'rollback') && $this->transactions)
|
|
|
|
{
|
|
|
|
$this->transactions = array(false);
|
|
|
|
$this->$o();
|
|
|
|
}
|
2015-05-12 18:31:49 +03:00
|
|
|
if ($this->queryLogFile)
|
|
|
|
{
|
|
|
|
file_put_contents($this->queryLogFile, $this->loggedQueries, FILE_APPEND);
|
|
|
|
}
|
2013-03-05 19:31:23 +04:00
|
|
|
}
|
|
|
|
|
2012-10-01 02:44:37 +04:00
|
|
|
function connect()
|
|
|
|
{
|
|
|
|
if ($this->socket !== NULL)
|
|
|
|
$this->link = new mysqli($this->host, $this->username, $this->password, $this->dbname, $this->port, $this->socket);
|
|
|
|
elseif ($this->port !== NULL)
|
|
|
|
$this->link = new mysqli($this->host, $this->username, $this->password, $this->dbname, $this->port);
|
2012-10-01 02:44:34 +04:00
|
|
|
else
|
2012-10-01 02:44:37 +04:00
|
|
|
$this->link = new mysqli($this->host, $this->username, $this->password, $this->dbname);
|
2013-02-18 17:54:46 +04:00
|
|
|
$errno = $this->link->connect_errno;
|
|
|
|
$error = $this->link->connect_error;
|
|
|
|
if ($errno)
|
|
|
|
{
|
|
|
|
$this->link = NULL;
|
2016-05-29 17:36:52 +03:00
|
|
|
throw new DatabaseMysqlException($error, $errno);
|
2013-02-18 17:54:46 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-11-16 02:23:05 +04:00
|
|
|
$this->transactions = array();
|
2013-02-18 17:54:46 +04:00
|
|
|
$this->link->set_charset('utf8');
|
2016-05-29 17:36:52 +03:00
|
|
|
foreach ($this->init as $q)
|
|
|
|
$this->link->query($q);
|
2013-02-18 17:54:46 +04:00
|
|
|
}
|
2012-10-01 02:44:34 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
function getDBName()
|
|
|
|
{
|
2012-10-01 02:44:37 +04:00
|
|
|
return $this->dbname;
|
2012-10-01 02:44:34 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
function quote($value)
|
|
|
|
{
|
|
|
|
if ($value === NULL)
|
|
|
|
return "NULL";
|
2012-10-10 02:20:40 +04:00
|
|
|
if (!$this->link)
|
|
|
|
$this->connect();
|
2012-10-01 02:44:37 +04:00
|
|
|
return "'" . $this->link->real_escape_string($value) . "'";
|
2012-10-01 02:44:34 +04:00
|
|
|
}
|
|
|
|
|
2018-09-10 14:26:14 +03:00
|
|
|
function query($sql, $streamResult = false)
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
2013-03-30 00:57:58 +04:00
|
|
|
if (!$this->link)
|
|
|
|
$this->connect();
|
2016-05-29 17:36:52 +03:00
|
|
|
if ($this->autoBegin && !$this->transactions)
|
|
|
|
$this->begin();
|
2012-10-01 02:44:34 +04:00
|
|
|
$this->queryCount++;
|
|
|
|
if ($this->queryLogFile)
|
|
|
|
{
|
2015-05-13 14:00:14 +03:00
|
|
|
$begin = explode(' ', microtime(), 2);
|
2012-10-01 02:44:34 +04:00
|
|
|
}
|
2018-09-10 14:26:14 +03:00
|
|
|
$r = $this->link->query($sql, $streamResult ? MYSQLI_USE_RESULT : MYSQLI_STORE_RESULT);
|
2016-05-29 17:36:52 +03:00
|
|
|
if (!$r)
|
|
|
|
$r = $this->check_reconnect('query', [ $sql, $fetchMode ]);
|
2015-05-13 14:00:14 +03:00
|
|
|
if ($this->queryLogFile)
|
|
|
|
{
|
|
|
|
$end = explode(' ', microtime(), 2);
|
|
|
|
$this->loggedQueries .= date("[Y-m-d H:i:s.").substr($end[0], 2, 6)."] [".
|
|
|
|
sprintf("%.05fs", $end[1]-$begin[1]+$end[0]-$begin[0])."] $sql\n";
|
|
|
|
}
|
2016-05-29 17:36:52 +03:00
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function check_reconnect($f, $args)
|
|
|
|
{
|
|
|
|
$r = false;
|
|
|
|
if ($this->link->errno == 2006 && $this->reconnect && (!$this->transactions || $args[0] == "BEGIN"))
|
2012-10-10 02:20:40 +04:00
|
|
|
{
|
2016-05-29 17:36:52 +03:00
|
|
|
// "MySQL server has gone away"
|
|
|
|
$this->connect();
|
|
|
|
$r = call_user_func_array([ $this->link, $f ], $args);
|
|
|
|
if (!$r && $this->link->errno == 2006)
|
|
|
|
$this->link = false;
|
2013-03-05 19:31:23 +04:00
|
|
|
if (!$r)
|
2016-05-29 17:36:52 +03:00
|
|
|
$st = " (reconnect failed)";
|
|
|
|
}
|
|
|
|
elseif ($this->link->errno != 2006)
|
|
|
|
$st = "";
|
|
|
|
elseif (!$this->reconnect)
|
|
|
|
$st = " (reconnect disabled";
|
|
|
|
elseif ($this->transactions)
|
|
|
|
$st = " (not reconnecting because of active transactions)";
|
|
|
|
if (!$r)
|
|
|
|
throw new DatabaseMysqlException('#'.$this->link->errno.': '.$this->link->error . $st . "\nQuery: ".$args[0], $this->link->errno);
|
2012-10-10 02:20:40 +04:00
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
|
2013-03-05 19:31:23 +04:00
|
|
|
function multi_select(array $queries, $format = 0)
|
|
|
|
{
|
2013-03-30 00:57:58 +04:00
|
|
|
if (!$this->link)
|
|
|
|
$this->connect();
|
2016-05-29 17:36:52 +03:00
|
|
|
if ($this->autoBegin && !$this->transactions)
|
|
|
|
$this->begin();
|
2013-03-05 19:31:23 +04:00
|
|
|
$this->queryCount += count($queries);
|
|
|
|
$log = '';
|
|
|
|
foreach ($queries as &$sql)
|
|
|
|
{
|
|
|
|
if (!is_string($sql))
|
|
|
|
{
|
|
|
|
$sql = $this->select_builder($sql[0], $sql[1], $sql[2], @$sql[3]);
|
|
|
|
}
|
|
|
|
$log .= date("[Y-m-d H:i:s] ").$sql."\n";
|
|
|
|
}
|
|
|
|
unset($sql);
|
|
|
|
if ($this->queryLogFile)
|
|
|
|
{
|
|
|
|
file_put_contents($this->queryLogFile, $log, FILE_APPEND);
|
|
|
|
}
|
|
|
|
$sql = implode('; ', $queries);
|
|
|
|
$r = $this->link->multi_query($sql);
|
|
|
|
if (!$r)
|
2016-05-29 17:36:52 +03:00
|
|
|
$this->check_reconnect('multi_query', [ $sql ]);
|
2013-03-05 19:31:23 +04:00
|
|
|
$results = array();
|
2013-03-30 00:57:58 +04:00
|
|
|
$i = 0;
|
2013-03-05 19:31:23 +04:00
|
|
|
foreach ($queries as $k => $q)
|
|
|
|
{
|
2013-03-30 00:57:58 +04:00
|
|
|
if ($i++)
|
|
|
|
{
|
|
|
|
$this->link->next_result();
|
|
|
|
}
|
|
|
|
$r = $this->link->store_result();
|
2013-03-05 19:31:23 +04:00
|
|
|
$results[$k] = $this->fetch_all($r, $format);
|
|
|
|
}
|
|
|
|
return $results;
|
|
|
|
}
|
|
|
|
|
2012-10-10 02:20:40 +04:00
|
|
|
/**
|
|
|
|
* Starts a transaction, supports nested calls and savepoints.
|
|
|
|
* @param boolean $savepoint Creates savepoints only this parameter is true.
|
|
|
|
*/
|
|
|
|
function begin($savepoint = false)
|
|
|
|
{
|
2016-05-29 17:36:52 +03:00
|
|
|
$n = count($this->transactions)+1;
|
|
|
|
$this->transactions[] = $savepoint ? "sp$n" : false;
|
2012-10-10 02:20:40 +04:00
|
|
|
if ($n == 1)
|
|
|
|
return $this->query("BEGIN");
|
|
|
|
elseif ($savepoint)
|
|
|
|
return $this->query("SAVEPOINT sp$n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Commits transaction or releases last savepoint.
|
|
|
|
* If there is no last savepoint, just returns true.
|
|
|
|
*/
|
|
|
|
function commit()
|
|
|
|
{
|
2016-05-29 17:36:52 +03:00
|
|
|
$r = true;
|
2012-10-10 02:20:40 +04:00
|
|
|
$savepoint = array_pop($this->transactions);
|
|
|
|
if (!$this->transactions)
|
2016-05-29 17:36:52 +03:00
|
|
|
$r = $this->query("COMMIT");
|
|
|
|
elseif ($savepoint)
|
|
|
|
$r = $this->query("RELEASE SAVEPOINT $savepoint");
|
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Commits transaction
|
|
|
|
*/
|
|
|
|
function commitAll()
|
|
|
|
{
|
|
|
|
$r = true;
|
|
|
|
if ($this->transactions)
|
2012-10-10 02:20:40 +04:00
|
|
|
{
|
2016-05-29 17:36:52 +03:00
|
|
|
$r = $this->query("COMMIT");
|
|
|
|
$this->transactions = [];
|
2012-10-10 02:20:40 +04:00
|
|
|
}
|
2016-05-29 17:36:52 +03:00
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Rollbacks transaction
|
|
|
|
*/
|
|
|
|
function rollbackAll()
|
|
|
|
{
|
|
|
|
$r = true;
|
|
|
|
if ($this->transactions)
|
2012-10-10 02:20:40 +04:00
|
|
|
{
|
2016-05-29 17:36:52 +03:00
|
|
|
$r = $this->query("ROLLBACK");
|
|
|
|
$this->transactions = [];
|
2012-10-10 02:20:40 +04:00
|
|
|
}
|
2016-05-29 17:36:52 +03:00
|
|
|
return $r;
|
2012-10-10 02:20:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Rollbacks transaction or last savepoint.
|
|
|
|
* If there is no savepoint, returns false.
|
|
|
|
*/
|
|
|
|
function rollback()
|
|
|
|
{
|
2016-05-29 17:36:52 +03:00
|
|
|
$r = false;
|
2012-10-10 02:20:40 +04:00
|
|
|
$savepoint = array_pop($this->transactions);
|
|
|
|
if (!$this->transactions)
|
2016-05-29 17:36:52 +03:00
|
|
|
$r = $this->query("ROLLBACK");
|
2012-10-10 02:20:40 +04:00
|
|
|
elseif ($savepoint)
|
2016-05-29 17:36:52 +03:00
|
|
|
$r = $this->query("ROLLBACK TO SAVEPOINT $savepoint");
|
|
|
|
return $r;
|
2012-10-10 02:20:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
function errno()
|
|
|
|
{
|
|
|
|
return $this->link->errno;
|
2012-10-01 02:44:34 +04:00
|
|
|
}
|
|
|
|
|
2012-10-10 02:20:40 +04:00
|
|
|
function error()
|
|
|
|
{
|
|
|
|
return $this->link->error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run a SELECT query and return results.
|
|
|
|
*
|
|
|
|
* Usage: either
|
|
|
|
* $this->select($tables, $fields, $where, $options, $format)
|
|
|
|
* using $this->select_builder() or
|
|
|
|
* $this->select($sql_text, $format)
|
|
|
|
* using query text.
|
|
|
|
*
|
|
|
|
* @param int $format Return format, bitmask of MS_XX constants:
|
|
|
|
* MS_RESULT = return mysqli result object to manually fetch from
|
|
|
|
* MS_LIST = return rows as indexed arrays
|
|
|
|
* MS_HASH = return rows as associative arrays (default)
|
|
|
|
* MS_ROW = only return the first row
|
|
|
|
* MS_COL = only return the first column
|
|
|
|
* MS_VALUE = only return the first cell (just 1 value)
|
|
|
|
*/
|
2012-10-01 02:44:34 +04:00
|
|
|
function select($tables, $fields = '*', $where = 1, $options = NULL, $format = 0)
|
|
|
|
{
|
2013-03-30 00:57:58 +04:00
|
|
|
if (is_int($fields))
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
|
|
|
$sql = $tables;
|
|
|
|
$format = $fields;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
$sql = $this->select_builder($tables, $fields, $where, $options);
|
|
|
|
if ($format & MS_RESULT)
|
|
|
|
return $this->query($sql, MYSQLI_USE_RESULT);
|
2013-03-05 19:31:23 +04:00
|
|
|
$res = $this->query($sql);
|
|
|
|
return $this->fetch_all($res, $format);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fetch_all($res, $format = 0)
|
|
|
|
{
|
2012-10-01 02:44:34 +04:00
|
|
|
if ($format & MS_LIST)
|
2013-03-05 19:31:23 +04:00
|
|
|
$r = $this->get_rows($res);
|
2012-10-01 02:44:34 +04:00
|
|
|
else
|
2013-03-05 19:31:23 +04:00
|
|
|
$r = $this->get_assocs($res);
|
2012-10-01 02:44:34 +04:00
|
|
|
if (!$r)
|
|
|
|
$r = array();
|
|
|
|
if ($format & MS_ROW)
|
|
|
|
{
|
2012-10-10 02:20:40 +04:00
|
|
|
if (!count($r))
|
|
|
|
return NULL;
|
2012-10-01 02:44:34 +04:00
|
|
|
if ($format & MS_COL)
|
|
|
|
{
|
|
|
|
$r = $r[0];
|
|
|
|
$k = array_keys($r);
|
|
|
|
$r = $r[$k[0]];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
$r = $r[0];
|
|
|
|
}
|
|
|
|
elseif ($format & MS_COL)
|
|
|
|
{
|
2013-03-05 19:31:23 +04:00
|
|
|
$k = false;
|
2012-10-01 02:44:34 +04:00
|
|
|
foreach ($r as $i => $v)
|
|
|
|
{
|
|
|
|
if (!$k)
|
|
|
|
{
|
|
|
|
$k = array_keys($v);
|
|
|
|
$k = $k[0];
|
|
|
|
}
|
|
|
|
$r[$i] = $v[$k];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
|
|
|
|
function found_rows()
|
|
|
|
{
|
|
|
|
return $this->select('SELECT FOUND_ROWS()', MS_VALUE);
|
|
|
|
}
|
|
|
|
|
2012-10-10 02:20:40 +04:00
|
|
|
/**
|
|
|
|
* Delete a set of rows.
|
|
|
|
* @param mixed $tables see $this->tables_builder()
|
|
|
|
* @param mixed $where see $this->where_builder()
|
|
|
|
* @param array $options Options for query:
|
|
|
|
* 'LIMIT' => array($limit, $offset) or array($limit) or just $limit
|
|
|
|
* 'OFFSET' => $offset, for the case when 'LIMIT' is just $limit
|
|
|
|
*/
|
2012-10-01 02:44:34 +04:00
|
|
|
function delete($tables, $where, $options = NULL)
|
|
|
|
{
|
2018-09-10 15:39:50 +03:00
|
|
|
$this->query($this->delete_builder($tables, $where, $options));
|
2012-10-01 02:44:34 +04:00
|
|
|
return $this->link->affected_rows;
|
|
|
|
}
|
|
|
|
|
2012-10-10 02:20:40 +04:00
|
|
|
/**
|
|
|
|
* Insert a single row into $table and return inserted ID.
|
|
|
|
* @param string $table Table name to insert row to.
|
|
|
|
* @param array $rows Row to be inserted.
|
|
|
|
* @return int $insert_id Autoincrement ID of inserted row (if appropriate).
|
|
|
|
*/
|
2012-10-01 02:44:34 +04:00
|
|
|
function insert_row($table, $row)
|
|
|
|
{
|
|
|
|
$sql = $this->insert_builder($table, array($row));
|
|
|
|
if ($this->query($sql))
|
|
|
|
return $this->link->insert_id;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-10-01 02:44:37 +04:00
|
|
|
function insert_id()
|
|
|
|
{
|
|
|
|
return $this->link->insert_id;
|
|
|
|
}
|
|
|
|
|
2012-10-10 02:20:40 +04:00
|
|
|
/**
|
2016-05-29 17:36:52 +03:00
|
|
|
* Update row(s) in $table.
|
|
|
|
* $this->update($table, $set, $where, $options);
|
2012-10-10 02:20:40 +04:00
|
|
|
*
|
|
|
|
* @param string $table Table name to update.
|
|
|
|
* @param array $set Assoc array with values for update query.
|
|
|
|
* @param array $where Conditions for update query, see $this->where_builder().
|
|
|
|
* @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
|
|
|
|
*/
|
2012-10-01 02:44:34 +04:00
|
|
|
function update($table, $rows, $where = NULL, $options = NULL)
|
|
|
|
{
|
|
|
|
if (!$rows)
|
|
|
|
return false;
|
2018-09-10 15:39:50 +03:00
|
|
|
if ($this->query($this->update_builder($tables, $rows, $where, $options)))
|
2016-05-29 17:36:52 +03:00
|
|
|
return $this->link->affected_rows;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* INSERT / REPLACE / INSERT IGNORE / INSERT OR UPDATE
|
|
|
|
*/
|
|
|
|
function insert($table, $rows, $onConflict = NULL, $uniqueKey = NULL)
|
|
|
|
{
|
|
|
|
if (!$rows || !is_array($rows))
|
|
|
|
return false;
|
2018-09-10 15:39:50 +03:00
|
|
|
if ($this->query($this->insert_builder($table, $rows, $onConflict, $uniqueKey)))
|
2012-10-01 02:44:34 +04:00
|
|
|
return $this->link->affected_rows;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-05-29 17:36:52 +03:00
|
|
|
function insert_ignore($table, $rows, $uniqueKey = NULL)
|
|
|
|
{
|
|
|
|
return $this->insert($table, $rows, 'IGNORE', $uniqueKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
function upsert($table, $rows, $uniqueKey = NULL, $updateCols = NULL)
|
|
|
|
{
|
|
|
|
return $this->insert($table, $rows, 'UPDATE', $uniqueKey, $updateCols);
|
|
|
|
}
|
|
|
|
|
|
|
|
function replace($table, $rows, $uniqueKey = NULL)
|
2013-03-05 19:31:23 +04:00
|
|
|
{
|
2016-05-29 17:36:52 +03:00
|
|
|
return $this->insert($table, $rows, 'REPLACE', $uniqueKey);
|
2013-03-05 19:31:23 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function get_rows($res)
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
|
|
|
$r = array();
|
2013-03-05 19:31:23 +04:00
|
|
|
if ($res)
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
|
|
|
while ($row = $res->fetch_row())
|
|
|
|
$r[] = $row;
|
|
|
|
$res->free();
|
|
|
|
}
|
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
|
2013-03-05 19:31:23 +04:00
|
|
|
protected function get_assocs($res)
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
|
|
|
$r = array();
|
2013-03-05 19:31:23 +04:00
|
|
|
if ($res)
|
2012-10-01 02:44:34 +04:00
|
|
|
{
|
|
|
|
while ($row = $res->fetch_assoc())
|
|
|
|
$r[] = $row;
|
|
|
|
$res->free();
|
|
|
|
}
|
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
}
|