. /** * @package GNUsocial * @author Alexei Sorokin * @copyright 2020 Free Software Foundation, Inc http://www.fsf.org * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ defined('GNUSOCIAL') || die(); require_once 'Auth/OpenID/DatabaseConnection.php'; /** * A DB abstraction error for OpenID's Auth_OpenID_SQLStore * * @package GNUsocial * @author Alexei Sorokin * @copyright 2020 Free Software Foundation, Inc http://www.fsf.org * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ class SQLStore_DB_Connection extends Auth_OpenID_DatabaseConnection { private $conn = null; private $autocommit = true; /** * @param string|array $dsn * @param array $options */ public function __construct($dsn, array $options = []) { if (!is_array($dsn)) { $dsn = MDB2::parseDSN($dsn); } $dsn['new_link'] = true; // To create a new Database connection is an absolute must, because // php-openid code delays its transactions commitment. // Is a must because our Internal Session Handler uses the database // and depends on immediate commitment. $this->conn = MDB2::connect($dsn, $options); if (MDB2::isError($this->conn)) { throw new ServerException($this->conn->getMessage()); } } public function __destruct() { $this->conn->disconnect(); } /** * Sets auto-commit mode on this database connection. * * @param bool $mode */ public function autoCommit($mode) { $this->autocommit = $mode; if ($mode && $this->conn->inTransaction()) { $this->commit(); } } /** * Run an SQL query with the specified parameters, if any. * * @param string $sql * @param array $params * @param bool $is_manip * @return mixed */ private function _query(string $sql, array $params = [], bool $is_manip) { $stmt_type = $is_manip ? MDB2_PREPARE_MANIP : MDB2_PREPARE_RESULT; if ($is_manip && !$this->autocommit) { $this->begin(); } $split = preg_split( '/((?conn->prepare($sql, null, $stmt_type); if (MDB2::isError($stmt)) { // php-openid actually expects PEAR_Error. return $res; } if (count($params) > 0) { $stmt->bindValueArray($params); } $res = $stmt->execute(); if (MDB2::isError($res)) { return $res; } return $res; } /** * Run an SQL query with the specified parameters, if any. * * @param string $sql * @param array $params * @return mixed */ public function query($sql, $params = []) { return $this->_query($sql, $params, true); } public function begin() { $this->conn->beginTransaction(); } public function commit() { $this->conn->commit(); } public function rollback() { $this->conn->rollback(); } /** * Run an SQL query and return the first column of the first row of the * result set, if any. * * @param string $sql * @param array $params * @return string|PEAR_Error */ public function getOne($sql, $params = []) { $res = $this->_query($sql, $params, false); if (MDB2::isError($res)) { return $res; } return $res->fetchOne() ?? ''; } /** * Run an SQL query and return the first row of the result set, if any. * * @param string $sql * @param array $params * @return array|PEAR_Error */ public function getRow($sql, $params = []) { $res = $this->_query($sql, $params, false); if (MDB2::isError($res)) { return $res; } return $res->fetchRow(MDB2_FETCHMODE_ASSOC); } /** * Run an SQL query with the specified parameters, if any. * * @param string $sql * @param array $params * @return array|PEAR_Error */ public function getAll($sql, $params = []) { $res = $this->_query($sql, $params, false); if (MDB2::isError($res)) { return $res; } return $res->fetchAll(MDB2_FETCHMODE_ASSOC); } }