<?php
namespace MVC\MySql {
Imports("System.Text.StringBuilder");
Imports("Microsoft.VisualBasic.Strings");
class sqlDriver {
#region "MySql connection info"
public $database;
private $user;
private $password;
private $host;
private $port;
#endregion
protected $last_mysql_expression;
static $mysqliCache = [];
function __construct($database, $user, $password, $host = "localhost", $port = 3306) {
$this->database = $database;
$this->user = $user;
$this->password = $password;
$this->host = $host;
$this->port = $port;
}
public function GetDatabaseName() {
return $this->database;
}
public function Describe($tableName) {
$db = $this->database;
$SQL = "DESCRIBE `$db`.`$tableName`;";
$link = $this->__init_MySql(false);
\mysqli_select_db($link, $db);
\mysqli_query($link, "SET names 'utf8'");
$schema = \mysqli_query($link, $SQL);
if (empty($schema)) {
$message = "Database query error for table schema: $tableName.\n\n";
$message = $message . "<code>$SQL</code>";
$message = $message . "Connection Info: \n\n";
$message = $message . \json_encode([
"host" => $this->host,
"port" => $this->port,
"database" => $this->database,
"user" => $this->user,
"password" => $this->password
]);
# throw new \dotnetException($message);
\dotnet::ThrowException($message);
}
\console::log($SQL);
# 2018-08-21 在这里是将打开的mysql链接加入到缓存池之中
# 所以在这里就不关闭mysql链接了
# \mysqli_close($link);
return $schema;
}
protected function __init_MySql($new = true) {
if ($new) {
return $this->openNew();
} else if (!array_key_exists($this->database, self::$mysqliCache)) {
self::$mysqliCache[$this->database] = $this->openNew();
}
$conn = self::$mysqliCache[$this->database];
# https://stackoverflow.com/questions/3075116/php-how-to-determine-if-a-database-connection-is-open
if (is_resource($conn) && get_resource_type($conn) === 'mysql link') {
# 这个链接是没有被关闭的
# do nothing
return $conn;
} else {
self::$mysqliCache[$this->database] = $this->openNew();
return self::$mysqliCache[$this->database];
}
}
private function openNew() {
$link = @\mysqli_connect(
$this->host,
$this->user,
$this->password,
$this->database,
$this->port
);
# 2018-07-27
# 如果连接最新版本的mysql的时候,出现错误
#
# Error: Unable to connect to MySQL.
# Debugging errno: 2054
# Debugging error: The server requested authentication method unknown to the client
#
# 这是因为新版本的mysql采用了新的验证方式,这个时候会需要修改mysql之中的用户验证方式为旧的验证方式
# 使用下面的sql语句进行修改:
#
# use mysql;
# ALTER USER 'native'@'localhost' IDENTIFIED WITH mysql_native_password BY 'new_password';
# FLUSH PRIVILEGES;
#
# 或者升级php至最新版本
if (false == $link) {
$msg = (new \StringBuilder("", "<br />"))
->AppendLine("Error: Unable to connect to MySQL.")
->AppendLine("Debugging errno: " . mysqli_connect_errno())
->AppendLine("Debugging error: " . mysqli_connect_error())
->ToString();
\dotnet::ThrowException($msg);
} else {
return $link;
}
}
public function getLastMySql() {
return $this->last_mysql_expression;
}
public function getLastMySqlError() {
return \mysqli_error($this->__init_MySql(false));
}
}
interface ISqlDriver {
public function getLastMySql();
public function ExecuteSql($SQL);
public function Fetch($SQL);
public function ExecuteScalar($SQL);
}
}
?>