Seditio Source
Root |
./othercms/dotclear-2.22/inc/libs/clearbricks/dblayer/class.mysqlimb4.php
<?php
/**
 * @class mysqlimb4Connection
 * @brief MySQLi utf8-mb4 Database Driver
 *
 * See the {@link dbLayer} documentation for common methods.
 *
 * @package Clearbricks
 * @subpackage DBLayer
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 */

/* @cond ONCE */
if (class_exists('dbLayer')) {
   
/** @endcond */
   
class mysqlimb4Connection extends dbLayer implements i_dbLayer
   
{
        public static
$weak_locks = true; ///< boolean: Enables weak locks if true

       
protected $__driver = 'mysqlimb4';
        protected
$__syntax = 'mysql';

        public function
db_connect($host, $user, $password, $database)
        {
            if (!
function_exists('mysqli_connect')) {
                throw new
Exception('PHP MySQLi functions are not available');
            }

           
$port   = abs((int) ini_get('mysqli.default_port'));
           
$socket = '';
            if (
strpos($host, ':') !== false) {
               
// Port or socket given
               
$bits   = explode(':', $host);
               
$host   = array_shift($bits);
               
$socket = array_shift($bits);
                if (
abs((int) $socket) > 0) {
                   
// TCP/IP connection on given port
                   
$port   = abs((int) $socket);
                   
$socket = '';
                } else {
                   
// Socket connection
                   
$port = 0;
                }
            }
            if ((
$link = @mysqli_connect($host, $user, $password, $database, $port, $socket)) === false) {
                throw new
Exception('Unable to connect to database');
            }

           
$this->db_post_connect($link, $database);

            return
$link;
        }

        public function
db_pconnect($host, $user, $password, $database)
        {
           
// No pconnect wtih mysqli, below code is for comatibility
           
return $this->db_connect($host, $user, $password, $database);
        }

        private function
db_post_connect($link, $database)
        {
            if (
version_compare($this->db_version($link), '5.7.7', '>=')) {
               
$this->db_query($link, 'SET NAMES utf8mb4');
               
$this->db_query($link, 'SET CHARACTER SET utf8mb4');
               
$this->db_query($link, "SET COLLATION_CONNECTION = 'utf8mb4_unicode_ci'");
               
$this->db_query($link, "SET COLLATION_SERVER = 'utf8mb4_unicode_ci'");
               
$this->db_query($link, "SET CHARACTER_SET_SERVER = 'utf8mb4'");
                if (
version_compare($this->db_version($link), '8.0', '<')) {
                   
// Setting CHARACTER_SET_DATABASE is obosolete for MySQL 8.0+
                   
$this->db_query($link, "SET CHARACTER_SET_DATABASE = 'utf8mb4'");
                }
               
$link->set_charset('utf8mb4');
            } else {
                throw new
Exception('Unable to connect to an utf8mb4 database');
            }
        }

        public function
db_close($handle)
        {
            if (
$handle instanceof MySQLi) {
               
$handle->close();
            }
        }

        public function
db_version($handle)
        {
            if (
$handle instanceof MySQLi) {
               
$v = $handle->server_version;

                return
sprintf('%s.%s.%s', ($v - ($v % 10000)) / 10000, ($v - ($v % 100)) % 10000 / 100, $v % 100);
            }

            return
'';
        }

        public function
db_query($handle, $query)
        {
            if (
$handle instanceof MySQLi) {
               
$res = @$handle->query($query);
                if (
$res === false) {
                   
$e = new Exception($this->db_last_error($handle));

                    throw
$e;
                }

                return
$res;
            }

            return
null;
        }

        public function
db_exec($handle, $query)
        {
            return
$this->db_query($handle, $query);
        }

        public function
db_num_fields($res)
        {
            if (
$res instanceof MySQLi_Result) {
               
//return mysql_num_fields($res);
               
return $res->field_count;
            }

            return
0;
        }

        public function
db_num_rows($res)
        {
            if (
$res instanceof MySQLi_Result) {
                return
$res->num_rows;
            }

            return
0;
        }

        public function
db_field_name($res, $position)
        {
            if (
$res instanceof MySQLi_Result) {
               
$res->field_seek($position);
               
$finfo = $res->fetch_field();

                return
$finfo->name;    // @phpstan-ignore-line
           
}

            return
'';
        }

        public function
db_field_type($res, $position)
        {
            if (
$res instanceof MySQLi_Result) {
               
$res->field_seek($position);
               
$finfo = $res->fetch_field();

                return
$this->_convert_types($finfo->type); // @phpstan-ignore-line
           
}

            return
'';
        }

        public function
db_fetch_assoc($res)
        {
            if (
$res instanceof MySQLi_Result) {
               
$v = $res->fetch_assoc();

                return (
$v === null) ? false : $v;
            }

            return
false;
        }

        public function
db_result_seek($res, $row)
        {
            if (
$res instanceof MySQLi_Result) {
                return
$res->data_seek($row);
            }

            return
false;
        }

        public function
db_changes($handle, $res)
        {
            if (
$handle instanceof MySQLi) {
                return
$handle->affected_rows;
            }

            return
0;
        }

        public function
db_last_error($handle)
        {
            if (
$handle instanceof MySQLi) {
               
$e = $handle->error;
                if (
$e) {
                    return
$e . ' (' . $handle->errno . ')';
                }
            }

            return
false;
        }

        public function
db_escape_string($str, $handle = null)
        {
            if (
$handle instanceof MySQLi) {
                return
$handle->real_escape_string((string) $str);
            }

            return
addslashes($str);
        }

        public function
db_write_lock($table)
        {
            try {
               
$this->execute('LOCK TABLES ' . $this->escapeSystem($table) . ' WRITE');
            } catch (
Exception $e) {
               
# As lock is a privilege in MySQL, we can avoid errors with weak_locks static var
               
if (!self::$weak_locks) {
                    throw
$e;
                }
            }
        }

        public function
db_unlock()
        {
            try {
               
$this->execute('UNLOCK TABLES');
            } catch (
Exception $e) {
                if (!
self::$weak_locks) {
                    throw
$e;
                }
            }
        }

        public function
vacuum($table)
        {
           
$this->execute('OPTIMIZE TABLE ' . $this->escapeSystem($table));
        }

        public function
dateFormat($field, $pattern)
        {
           
$pattern = str_replace('%M', '%i', $pattern);

            return
'DATE_FORMAT(' . $field . ',' . "'" . $this->escape($pattern) . "') ";
        }

        public function
orderBy()
        {
           
$default = [
               
'order'   => '',
               
'collate' => false,
            ];
            foreach (
func_get_args() as $v) {
                if (
is_string($v)) {
                   
$res[] = $v;
                } elseif (
is_array($v) && !empty($v['field'])) {
                   
$v          = array_merge($default, $v);
                   
$v['order'] = (strtoupper($v['order']) == 'DESC' ? 'DESC' : '');
                   
$res[]      = $v['field'] . ($v['collate'] ? ' COLLATE utf8mb4_unicode_ci' : '') . ' ' . $v['order'];
                }
            }

            return empty(
$res) ? '' : ' ORDER BY ' . implode(',', $res) . ' ';
        }

        public function
lexFields()
        {
           
$fmt = '%s COLLATE utf8mb4_unicode_ci';
            foreach (
func_get_args() as $v) {
                if (
is_string($v)) {
                   
$res[] = sprintf($fmt, $v);
                } elseif (
is_array($v)) {
                   
$res = array_map(fn ($i) => sprintf($fmt, $i), $v);
                }
            }

            return empty(
$res) ? '' : implode(',', $res);
        }

        public function
concat()
        {
           
$args = func_get_args();

            return
'CONCAT(' . implode(',', $args) . ')';
        }

        public function
escapeSystem($str)
        {
            return
'`' . $str . '`';
        }

        protected function
_convert_types($id)
        {
           
$id2type = [
               
'1' => 'int',
               
'2' => 'int',
               
'3' => 'int',
               
'8' => 'int',
               
'9' => 'int',

               
'16' => 'int', //BIT type recognized as unknown with mysql adapter

               
'4'   => 'real',
               
'5'   => 'real',
               
'246' => 'real',

               
'253' => 'string',
               
'254' => 'string',

               
'10' => 'date',
               
'11' => 'time',
               
'12' => 'datetime',
               
'13' => 'year',

               
'7' => 'timestamp',

               
'252' => 'blob',

            ];
           
$type = 'unknown';

            if (isset(
$id2type[$id])) {
               
$type = $id2type[$id];
            }

            return
$type;
        }
    }

   
/* @cond ONCE */
}
/* @endcond */