2013-11-09 17:24:03 +01:00
|
|
|
<?php
|
|
|
|
|
2014-04-27 21:31:55 +02:00
|
|
|
namespace ManiaControl\Database;
|
2014-03-20 16:19:09 +01:00
|
|
|
|
2014-03-12 13:27:14 +01:00
|
|
|
use ManiaControl\Callbacks\TimerListener;
|
2014-04-27 21:31:55 +02:00
|
|
|
use ManiaControl\ManiaControl;
|
2013-11-09 17:24:03 +01:00
|
|
|
|
|
|
|
/**
|
2014-04-12 12:14:37 +02:00
|
|
|
* Database Connection Class
|
2013-11-09 17:24:03 +01:00
|
|
|
*
|
2014-05-02 17:40:47 +02:00
|
|
|
* @author ManiaControl Team <mail@maniacontrol.com>
|
|
|
|
* @copyright 2014 ManiaControl Team
|
|
|
|
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
|
2013-11-09 17:24:03 +01:00
|
|
|
*/
|
2014-03-20 16:19:09 +01:00
|
|
|
class Database implements TimerListener {
|
2014-04-12 12:14:37 +02:00
|
|
|
/*
|
|
|
|
* Public Properties
|
2013-11-09 17:24:03 +01:00
|
|
|
*/
|
|
|
|
public $mysqli = null;
|
2014-04-27 21:31:55 +02:00
|
|
|
public $migrationHelper = null;
|
2014-05-02 17:40:47 +02:00
|
|
|
|
2014-04-12 12:14:37 +02:00
|
|
|
/*
|
|
|
|
* Private Properties
|
2013-11-09 17:24:03 +01:00
|
|
|
*/
|
2013-11-10 02:55:08 +01:00
|
|
|
private $maniaControl = null;
|
2013-11-09 17:24:03 +01:00
|
|
|
|
|
|
|
/**
|
2014-05-09 17:30:31 +02:00
|
|
|
* Construct a new Database Connection
|
|
|
|
*
|
|
|
|
* @param ManiaControl $maniaControl
|
2013-11-09 17:24:03 +01:00
|
|
|
*/
|
2013-11-10 02:55:08 +01:00
|
|
|
public function __construct(ManiaControl $maniaControl) {
|
|
|
|
$this->maniaControl = $maniaControl;
|
2014-05-02 17:40:47 +02:00
|
|
|
|
2013-11-09 17:24:03 +01:00
|
|
|
// Get mysql server information
|
2014-05-09 18:42:45 +02:00
|
|
|
$databaseXmlTag = $this->maniaControl->config->database;
|
|
|
|
$host = $databaseXmlTag->xpath('host');
|
2014-05-02 15:35:52 +02:00
|
|
|
if (!$host) {
|
2014-05-09 13:13:29 +02:00
|
|
|
$message = "Invalid database configuration (host).";
|
2014-05-09 14:08:39 +02:00
|
|
|
$this->maniaControl->quit($message, true);
|
2014-05-02 15:35:52 +02:00
|
|
|
}
|
2014-05-09 18:42:45 +02:00
|
|
|
$port = $databaseXmlTag->xpath('port');
|
2014-05-02 15:35:52 +02:00
|
|
|
if (!$port) {
|
2014-05-09 13:13:29 +02:00
|
|
|
$message = "Invalid database configuration (port).";
|
2014-05-09 14:08:39 +02:00
|
|
|
$this->maniaControl->quit($message, true);
|
2014-05-02 15:35:52 +02:00
|
|
|
}
|
2014-05-09 18:42:45 +02:00
|
|
|
$user = $databaseXmlTag->xpath('user');
|
2014-05-02 15:35:52 +02:00
|
|
|
if (!$user) {
|
2014-05-09 13:13:29 +02:00
|
|
|
$message = "Invalid database configuration (user).";
|
2014-05-09 14:08:39 +02:00
|
|
|
$this->maniaControl->quit($message, true);
|
2014-05-02 15:35:52 +02:00
|
|
|
}
|
2014-05-09 18:42:45 +02:00
|
|
|
$pass = $databaseXmlTag->xpath('pass');
|
2014-05-02 15:35:52 +02:00
|
|
|
if (!$pass) {
|
2014-05-09 13:13:29 +02:00
|
|
|
$message = "Invalid database configuration (pass).";
|
2014-05-09 14:08:39 +02:00
|
|
|
$this->maniaControl->quit($message, true);
|
2014-05-02 15:35:52 +02:00
|
|
|
}
|
2014-05-02 17:40:47 +02:00
|
|
|
|
|
|
|
$host = (string)$host[0];
|
|
|
|
$port = (int)$port[0];
|
|
|
|
$user = (string)$user[0];
|
|
|
|
$pass = (string)$pass[0];
|
|
|
|
|
2014-03-20 16:19:09 +01:00
|
|
|
// Enable mysqli Reconnect
|
2014-03-12 13:27:14 +01:00
|
|
|
ini_set('mysqli.reconnect', 'on');
|
2014-05-02 17:40:47 +02:00
|
|
|
|
2013-11-09 17:24:03 +01:00
|
|
|
// Open database connection
|
2014-02-24 22:47:35 +01:00
|
|
|
$this->mysqli = @new \mysqli($host, $user, $pass, null, $port);
|
2013-11-09 17:24:03 +01:00
|
|
|
if ($this->mysqli->connect_error) {
|
2014-05-09 13:13:29 +02:00
|
|
|
$message = "Couldn't connect to Database: '{$this->mysqli->connect_error}'";
|
2014-05-09 14:08:39 +02:00
|
|
|
$this->maniaControl->quit($message, true);
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
|
|
|
$this->mysqli->set_charset("utf8");
|
2014-05-02 17:40:47 +02:00
|
|
|
|
2013-11-09 17:24:03 +01:00
|
|
|
$this->initDatabase();
|
2013-11-10 02:55:08 +01:00
|
|
|
$this->optimizeTables();
|
2014-05-02 17:40:47 +02:00
|
|
|
|
2014-03-20 16:19:09 +01:00
|
|
|
// Register Method which checks the Database Connection every 5 seconds
|
2014-03-12 13:27:14 +01:00
|
|
|
$this->maniaControl->timerManager->registerTimerListening($this, 'checkConnection', 5000);
|
2014-05-02 17:40:47 +02:00
|
|
|
|
2014-04-27 21:31:55 +02:00
|
|
|
// Create migration helper
|
|
|
|
$this->migrationHelper = new MigrationHelper($maniaControl);
|
2014-03-12 13:27:14 +01:00
|
|
|
}
|
|
|
|
|
2013-11-09 17:24:03 +01:00
|
|
|
/**
|
|
|
|
* Connect to the defined database (create it if needed)
|
2013-11-10 02:55:08 +01:00
|
|
|
*
|
|
|
|
* @return bool
|
2013-11-09 17:24:03 +01:00
|
|
|
*/
|
|
|
|
private function initDatabase() {
|
2014-01-06 14:22:48 +01:00
|
|
|
$dbName = $this->maniaControl->config->database->xpath('db_name');
|
2013-12-09 13:45:58 +01:00
|
|
|
if (!$dbName) {
|
2014-05-09 14:08:39 +02:00
|
|
|
$this->maniaControl->quit("Invalid Database Configuration (db_name).", true);
|
2013-11-10 17:38:54 +01:00
|
|
|
return false;
|
|
|
|
}
|
2014-05-02 17:40:47 +02:00
|
|
|
$dbName = (string)$dbName[0];
|
|
|
|
|
2013-11-09 17:24:03 +01:00
|
|
|
// Try to connect
|
2013-12-09 13:45:58 +01:00
|
|
|
$result = $this->mysqli->select_db($dbName);
|
2014-05-02 17:40:47 +02:00
|
|
|
if ($result) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-11-10 02:55:08 +01:00
|
|
|
// Create database
|
2014-05-02 17:40:47 +02:00
|
|
|
$databaseQuery = "CREATE DATABASE ?;";
|
2013-11-10 02:55:08 +01:00
|
|
|
$databaseStatement = $this->mysqli->prepare($databaseQuery);
|
|
|
|
if ($this->mysqli->error) {
|
2014-05-09 14:08:39 +02:00
|
|
|
$this->maniaControl->quit($this->mysqli->error, true);
|
2013-11-10 02:55:08 +01:00
|
|
|
return false;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2013-12-09 13:45:58 +01:00
|
|
|
$databaseStatement->bind_param('s', $dbName);
|
2013-11-10 02:55:08 +01:00
|
|
|
$databaseStatement->execute();
|
|
|
|
if ($databaseStatement->error) {
|
2014-05-09 14:08:39 +02:00
|
|
|
$this->maniaControl->quit($databaseStatement->error, true);
|
2013-11-10 02:55:08 +01:00
|
|
|
return false;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2013-11-10 02:55:08 +01:00
|
|
|
$databaseStatement->close();
|
2014-05-02 17:40:47 +02:00
|
|
|
|
2013-11-10 02:55:08 +01:00
|
|
|
// Connect to new database
|
2013-12-09 13:45:58 +01:00
|
|
|
$this->mysqli->select_db($dbName);
|
2013-11-10 02:55:08 +01:00
|
|
|
if ($this->mysqli->error) {
|
2014-05-09 14:08:39 +02:00
|
|
|
$message = "Couldn't select database '{$dbName}'. {$this->mysqli->error}";
|
|
|
|
$this->maniaControl->quit($message, true);
|
2013-11-10 02:55:08 +01:00
|
|
|
return false;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2013-11-10 02:55:08 +01:00
|
|
|
return true;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2013-11-10 02:55:08 +01:00
|
|
|
* Optimize all existing tables
|
2013-11-09 17:24:03 +01:00
|
|
|
*
|
2013-11-10 02:55:08 +01:00
|
|
|
* @return bool
|
2013-11-09 17:24:03 +01:00
|
|
|
*/
|
2013-11-10 02:55:08 +01:00
|
|
|
private function optimizeTables() {
|
|
|
|
$showQuery = "SHOW TABLES;";
|
2014-05-02 17:40:47 +02:00
|
|
|
$result = $this->mysqli->query($showQuery);
|
2013-11-09 17:24:03 +01:00
|
|
|
if ($this->mysqli->error) {
|
2013-11-10 02:55:08 +01:00
|
|
|
trigger_error($this->mysqli->error);
|
|
|
|
return false;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2013-11-10 02:55:08 +01:00
|
|
|
$count = $result->num_rows;
|
|
|
|
if ($count <= 0) {
|
2014-03-20 16:19:09 +01:00
|
|
|
$result->close();
|
2013-11-10 02:55:08 +01:00
|
|
|
return true;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2013-11-10 02:55:08 +01:00
|
|
|
$optimizeQuery = "OPTIMIZE TABLE ";
|
2014-05-02 17:40:47 +02:00
|
|
|
$index = 0;
|
2013-11-10 02:55:08 +01:00
|
|
|
while ($row = $result->fetch_row()) {
|
|
|
|
$tableName = $row[0];
|
|
|
|
$optimizeQuery .= "`{$tableName}`";
|
|
|
|
if ($index < $count - 1) {
|
|
|
|
$optimizeQuery .= ", ";
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2013-11-10 02:55:08 +01:00
|
|
|
$index++;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2014-03-20 16:19:09 +01:00
|
|
|
$result->close();
|
2013-11-10 02:55:08 +01:00
|
|
|
$optimizeQuery .= ";";
|
|
|
|
$this->mysqli->query($optimizeQuery);
|
2013-11-09 17:24:03 +01:00
|
|
|
if ($this->mysqli->error) {
|
2013-11-10 02:55:08 +01:00
|
|
|
trigger_error($this->mysqli->error);
|
|
|
|
return false;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2013-11-10 02:55:08 +01:00
|
|
|
return true;
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|
2014-05-02 17:40:47 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if Connection still exists every 5 seconds
|
|
|
|
*
|
2014-05-09 14:08:39 +02:00
|
|
|
* @param float $time
|
2014-05-02 17:40:47 +02:00
|
|
|
*/
|
2014-05-09 14:08:39 +02:00
|
|
|
public function checkConnection($time = null) {
|
|
|
|
if (!$this->mysqli || !$this->mysqli->ping()) {
|
|
|
|
$this->maniaControl->quit("The MySQL server has gone away!", true);
|
2014-05-02 17:40:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destruct database connection
|
|
|
|
*/
|
|
|
|
public function __destruct() {
|
2014-05-09 13:13:29 +02:00
|
|
|
if ($this->mysqli && !$this->mysqli->connect_error) {
|
2014-05-02 17:40:47 +02:00
|
|
|
$this->mysqli->close();
|
|
|
|
}
|
|
|
|
}
|
2013-11-09 17:24:03 +01:00
|
|
|
}
|