| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- <?php
- /**
- * [Discuz!] (C)2001-2099 Discuz! Team
- * This is NOT a freeware, use is subject to license terms
- * https://license.discuz.vip
- */
- if(!defined('IN_DISCUZ')) {
- exit('Access Denied');
- }
- class db_driver_pdo extends db_driver_mysqli {
- var $tablepre;
- var $version = '';
- var $drivertype = 'pdo';
- var $querynum = 0;
- var $slaveid = 0;
- var $curlink;
- var $link = [];
- var $config = [];
- var $sqldebug = [];
- var $map = [];
- function db_mysql($config = []) {
- if(!empty($config)) {
- $this->set_config($config);
- }
- }
- function connect($serverid = 1) {
- if(empty($this->config) || empty($this->config[$serverid])) {
- $this->halt('config_db_not_found');
- }
- if(!empty($this->config[$serverid]['dsn'])) {
- $this->link[$serverid] = $this->_dbconnectWithDSN(
- $this->config[$serverid]['dsn'],
- $this->config[$serverid]['dbuser'],
- $this->config[$serverid]['dbpw'],
- $this->config[$serverid]['pconnect']
- );
- } else {
- $this->link[$serverid] = $this->_dbconnect(
- $this->config[$serverid]['dbhost'],
- $this->config[$serverid]['dbuser'],
- $this->config[$serverid]['dbpw'],
- $this->config[$serverid]['dbcharset'],
- $this->config[$serverid]['dbname'],
- $this->config[$serverid]['pconnect']
- );
- }
- $this->curlink = $this->link[$serverid];
- }
- function _dbconnect($dbhost, $dbuser, $dbpw, $dbcharset, $dbname, $pconnect, $halt = true) {
- $option = [];
- if(intval($pconnect) === 1) {
- $option = [PDO::ATTR_PERSISTENT => true];
- }
- $link = new PDO('mysql:host='.$dbhost.';dbname='.$dbname.';charset='.$dbcharset, $dbuser, $dbpw, $option);
- if(!$link) {
- $halt && $this->halt('notconnect', $this->errno());
- } else {
- $this->curlink = $link;
- $link->query('SET sql_mode=\'\',character_set_client=binary');
- }
- return $link;
- }
- function _dbconnectWithDSN($dsn, $dbuser, $dbpw, $pconnect, $halt = true) {
- $option = [];
- if(intval($pconnect) === 1) {
- $option = [PDO::ATTR_PERSISTENT => true];
- }
- $link = new PDO($dsn, $dbuser, $dbpw, $option);
- if(!$link) {
- $halt && $this->halt('notconnect', $this->errno());
- } else {
- $this->curlink = $link;
- $link->query('SET sql_mode=\'\',character_set_client=binary');
- }
- return $link;
- }
- function select_db($dbname) {
- return false;
- }
- function fetch_array($query, $result_type = MYSQLI_ASSOC) {
- $result_type = match ($result_type) {
- 'MYSQL_ASSOC', MYSQLI_ASSOC, 1 => PDO::FETCH_ASSOC,
- 'MYSQL_NUM', MYSQLI_NUM, 2 => PDO::FETCH_NUM,
- default => PDO::FETCH_BOTH,
- };
- return $query ? $query->fetch($result_type) : null;
- }
- function fetch_first($sql) {
- return $this->fetch_array($this->query($sql));
- }
- function result_first($sql) {
- return $this->result($this->query($sql), 0);
- }
- public function query($sql, $silent = false, $unbuffered = false) {
- $arg = [];
- if(is_array($sql)) {
- $arg = !empty($sql[1]) ? (array)$sql[1] : [];
- $sql = $sql[0];
- }
- if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
- $starttime = microtime(true);
- }
- if('UNBUFFERED' === $silent) {
- $silent = false;
- $unbuffered = true;
- } elseif('SILENT' === $silent) {
- $silent = true;
- $unbuffered = false;
- }
- if(!$unbuffered) {
- $this->curlink->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, TRUE);
- }
- $query = $this->curlink->prepare($sql);
- try {
- $query->execute($arg);
- } catch (Exception $e) {
- if(in_array($this->errno(), ['01002', '08003', '08S01', '08007']) && !str_starts_with($silent, 'RETRY')) {
- $this->connect();
- return $this->query([$sql, $arg], 'RETRY'.$silent);
- }
- if(!$silent) {
- $this->halt($this->error(), $this->errno(), $sql);
- }
- }
- if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
- $this->sqldebug[] = [$sql, number_format((microtime(true) - $starttime), 6), debug_backtrace(), $this->curlink, $arg];
- }
- $this->querynum++;
- $cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' '))));
- if($cmd === 'UPDATE' || $cmd === 'DELETE' || $cmd === 'INSERT') {
- $this->rowCount = $query->rowCount();
- }
- return $query;
- }
- function affected_rows() {
- return $this->rowCount;
- }
- function error() {
- return (($this->curlink) ? $this->curlink->errorInfo()[2] : 'pdo_error');
- }
- function errno() {
- return intval(($this->curlink) ? $this->curlink->errorCode() : 99999);
- }
- function result($query, $row = 0) {
- if(!$query || $query->rowCount() == 0) {
- return null;
- }
- return $query->fetchColumn($row);
- }
- function num_rows($query) {
- return $query ? $query->rowCount() : 0;
- }
- function num_fields($query) {
- return $query ? $query->columnCount() : null;
- }
- function free_result($query) {
- return true;
- }
- function insert_id() {
- return ($id = $this->curlink->lastInsertId()) >= 0 ? $id : $this->result($this->query('SELECT last_insert_id()'), 0);
- }
- function fetch_row($query) {
- return $query ? $query->fetch_row() : null;
- }
- function fetch_fields($query) {
- return $query ? $query->fetch_field() : null;
- }
- function version() {
- if(empty($this->version)) {
- $this->version = $this->curlink->getAttribute(PDO::ATTR_SERVER_VERSION);
- }
- return $this->version;
- }
- function escape_string($str) {
- return substr($this->curlink->quote($str), 1, -1);
- }
- function close() {
- return true;
- }
- function halt($message = '', $code = 0, $sql = '') {
- throw new DbException(var_export($message, true), $code, $sql);
- }
- function begin_transaction() {
- if($this->curlink->beginTransaction()) {
- return true;
- } else {
- return false;
- }
- }
- function commit() {
- if($this->curlink->commit()) {
- return true;
- } else {
- return false;
- }
- }
- function rollback() {
- if($this->curlink->rollBack()) {
- return true;
- } else {
- return false;
- }
- }
- }
|