diff --git a/DatabaseMysql.php b/DatabaseMysql.php index 3e070a1..92993ab 100644 --- a/DatabaseMysql.php +++ b/DatabaseMysql.php @@ -169,7 +169,7 @@ class DatabaseMysql extends MysqlQueryBuilder implements Database } $r = $this->link->query($sql, $streamResult ? MYSQLI_USE_RESULT : MYSQLI_STORE_RESULT); if (!$r) - $r = $this->check_reconnect('query', [ $sql, $fetchMode ]); + $r = $this->check_reconnect('query', [ $sql, $streamResult ]); if ($this->queryLogFile) { $end = explode(' ', microtime(), 2); @@ -443,7 +443,7 @@ class DatabaseMysql extends MysqlQueryBuilder implements Database * 'LIMIT' => array($limit, $offset) or array($limit) or just $limit * 'OFFSET' => $offset, for the case when 'LIMIT' is just $limit */ - function update($table, $rows, $where = NULL, $options = NULL) + function update($tables, $rows, $where = NULL, $options = NULL) { if (!$rows) return false; diff --git a/DatabasePdoPgsql.php b/DatabasePdoPgsql.php index ce8fd86..45bb3b6 100644 --- a/DatabasePdoPgsql.php +++ b/DatabasePdoPgsql.php @@ -3,7 +3,7 @@ /** * PDO/PostgreSQL wrapper with (mostly) DatabaseMySQL interface :) * Select builder is inspired by MediaWiki's one. - * Version: 2018-11-04 + * Version: 2018-12-18 * (c) Vitaliy Filippov, 2015-2018 */ @@ -38,13 +38,14 @@ if (!interface_exists('Database')) class DatabasePdoPgsql implements Database { - var $host, $port, $socket, $username, $password, $dbname; + var $host, $port, $socket, $username, $password, $dbname, $sslmode, $sslcert, $sslkey; var $tableNames = array(); var $init = array(); var $queryLogFile; var $reconnect = true; var $autoBegin; + var $beginHook; var $ondestroy = 'commit'; var $queryCount = 0; @@ -60,6 +61,8 @@ class DatabasePdoPgsql implements Database * host Host name or IP address to connect to [localhost] * socket Directory of UNIX socket [/var/run/postgresql] * port TCP port to connect to [5432] + * sslcert client SSL certificate to use + * sslkey client SSL key to use * dbname DB name to use * username Username * password Password @@ -67,6 +70,7 @@ class DatabasePdoPgsql implements Database * 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] + * beginHook Callback to call when starting a transaction * ondestroy commit/rollback/none during destruction [commit] * init Initialisation queries (array) */ @@ -79,10 +83,13 @@ class DatabasePdoPgsql implements Database 'dbname' => '', 'username' => '', 'password' => '', + 'sslcert' => '', + 'sslkey' => '', 'reconnect' => true, 'tableNames' => array(), 'queryLogFile' => '', 'autoBegin' => false, + 'beginHook' => NULL, 'ondestroy' => 'commit', 'init' => array(), ); @@ -111,6 +118,10 @@ class DatabasePdoPgsql implements Database { $str = "pgsql:port=".intval($this->port); $str .= ";host='".($this->host == 'localhost' && $this->socket !== NULL ? $this->socket : $this->host)."';dbname='".$this->dbname."'"; + if ($this->sslcert && $this->sslkey) + { + $str .= ";sslmode=require;sslcert='".$this->sslcert."';sslkey='".$this->sslkey."'"; + } try { $this->link = new PDO($str, $this->username, $this->password, array( @@ -175,12 +186,17 @@ class DatabasePdoPgsql implements Database $t = substr(floatval(microtime()), 1, 7); file_put_contents($this->queryLogFile, date("[Y-m-d H:i:s$t] ").$sql."\n", FILE_APPEND); } - try + retry: try { $r = $this->link->query($sql); } catch (Exception $e) { + if ($this->reconnect && substr($e->getMessage(), 0, strlen('SQLSTATE[HY000]: General error: 7')) == 'SQLSTATE[HY000]: General error: 7') + { + $this->connect(); + goto retry; + } if ($this->queryLogFile) file_put_contents($this->queryLogFile, date("[Y-m-d H:i:s] ")."Error: $e\n---- Query: $sql\n", FILE_APPEND); throw $e; @@ -197,9 +213,19 @@ class DatabasePdoPgsql implements Database $this->transactions[] = $savepoint; $n = count($this->transactions); if ($n == 1) - return $this->query("BEGIN"); + { + $r = $this->query("BEGIN"); + if ($this->beginHook) + { + $cb = $this->beginHook; + $cb($this); + } + return $r; + } elseif ($savepoint) + { return $this->query("SAVEPOINT sp$n"); + } return true; }