TrackManiaControl/application/core/Database/Database.php

202 lines
5.1 KiB
PHP
Raw Normal View History

2013-11-09 17:24:03 +01:00
<?php
2014-04-27 21:31:55 +02:00
namespace ManiaControl\Database;
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
/**
* 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
*/
class Database implements TimerListener {
/*
* 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
/*
* Private Properties
2013-11-09 17:24:03 +01:00
*/
private $maniaControl = null;
2014-06-20 19:06:55 +02:00
/** @var Config $config */
private $config = 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
*/
public function __construct(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
2014-05-02 17:40:47 +02: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
$this->loadConfig();
$this->mysqli = @new \mysqli($this->config->host, $this->config->user, $this->config->pass, null, $this->config->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();
$this->optimizeTables();
2014-05-02 17:40:47 +02: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
/**
* Load the Database Config
*/
private function loadConfig() {
$databaseElements = $this->maniaControl->config->xpath('database');
if (!$databaseElements) {
trigger_error('No Database configured!', E_USER_ERROR);
}
$databaseElement = $databaseElements[0];
// Host
$hostElements = $databaseElement->xpath('host');
if (!$hostElements) {
trigger_error("Invalid database configuration (Host).", E_USER_ERROR);
}
$host = (string)$hostElements[0];
// Port
$portElements = $databaseElement->xpath('port');
if (!$portElements) {
trigger_error("Invalid database configuration (Port).", E_USER_ERROR);
}
$port = (string)$portElements[0];
// User
$userElements = $databaseElement->xpath('user');
if (!$userElements) {
trigger_error("Invalid database configuration (User).", E_USER_ERROR);
}
$user = (string)$userElements[0];
// Pass
$passElements = $databaseElement->xpath('pass');
if (!$passElements) {
trigger_error("Invalid database configuration (Pass).", E_USER_ERROR);
}
$pass = (string)$passElements[0];
// Name
$nameElements = $databaseElement->xpath('name');
if (!$nameElements) {
$nameElements = $databaseElement->xpath('db_name');
}
if (!$nameElements) {
trigger_error("Invalid database configuration (Name).", E_USER_ERROR);
}
$name = (string)$nameElements[0];
// Create config object
2014-06-20 19:06:55 +02:00
$config = new Config($host, $port, $user, $pass, $name);
if (!$config->validate()) {
$this->maniaControl->quit("Your config file doesn't seem to be maintained properly. Please check the database configuration again!", true);
}
$this->config = $config;
}
/**
* Connect to the defined Database
*
* @return bool
2013-11-09 17:24:03 +01:00
*/
private function initDatabase() {
// Try to connect
$result = $this->mysqli->select_db($this->config->name);
2014-05-02 17:40:47 +02:00
if ($result) {
return true;
}
$this->maniaControl->log("Database '{$this->config->name}' doesn't exit! Trying to create it...");
2014-05-02 17:40:47 +02:00
// Create database
2014-06-29 19:59:02 +02:00
$databaseQuery = "CREATE DATABASE " . $this->mysqli->escape_string($this->config->name) . ";";
$this->mysqli->query($databaseQuery);
if ($this->mysqli->error) {
2014-05-09 14:08:39 +02:00
$this->maniaControl->quit($this->mysqli->error, true);
return false;
2013-11-09 17:24:03 +01:00
}
2014-05-02 17:40:47 +02:00
// Connect to new database
$this->mysqli->select_db($this->config->name);
if ($this->mysqli->error) {
$message = "Couldn't select database '{$this->config->name}'. {$this->mysqli->error}";
2014-05-09 14:08:39 +02:00
$this->maniaControl->quit($message, true);
return false;
2013-11-09 17:24:03 +01:00
}
return true;
2013-11-09 17:24:03 +01:00
}
/**
* Optimize all existing Tables
2013-11-09 17:24:03 +01:00
*
* @return bool
2013-11-09 17:24:03 +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) {
trigger_error($this->mysqli->error);
return false;
2013-11-09 17:24:03 +01:00
}
$count = $result->num_rows;
if ($count <= 0) {
$result->free();
return true;
2013-11-09 17:24:03 +01:00
}
$optimizeQuery = "OPTIMIZE TABLE ";
2014-05-02 17:40:47 +02:00
$index = 0;
while ($row = $result->fetch_row()) {
$tableName = $row[0];
$optimizeQuery .= "`{$tableName}`";
if ($index < $count - 1) {
$optimizeQuery .= ", ";
2013-11-09 17:24:03 +01:00
}
$index++;
2013-11-09 17:24:03 +01:00
}
$result->free();
$optimizeQuery .= ";";
$this->mysqli->query($optimizeQuery);
2013-11-09 17:24:03 +01:00
if ($this->mysqli->error) {
trigger_error($this->mysqli->error);
return false;
2013-11-09 17:24:03 +01:00
}
return true;
2013-11-09 17:24:03 +01:00
}
2014-05-02 17:40:47 +02:00
/**
* Check whether the Database Connection is still open
2014-05-02 17:40:47 +02:00
*/
public function checkConnection() {
2014-05-09 14:08:39 +02:00
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
2014-05-02 17:40:47 +02:00
*/
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
}