<?php
/*
* @package LabCMS
* @copyright (c) 2006 Alexander Levin aka Loki (loki_angel@mail.ru)
* @support http://labcms.ru
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/

include_once dirname(__FILE__)."/DbSimple/Generic.php";
include_once dirname(__FILE__)."/DbSimple/Mysql.php";

class Db extends DbSimple_Generic
{
	public static $connected=null;
	private static $db=null;
	private static $initLog=array();
	
	private function __construct()
	{
		// Подключаемся к БД.
		self::$db=parent::connect(
			"mysqli://".config::get('core.dbuser').":"
			.config::get('core.dbpasswd')."@".config::get('core.dblocation')
			."/".config::get('core.dbname')
		);

		if (!config::get('core.noDBErrorHandler')) {
			self::$db->setErrorHandler(array('Db', 'databaseErrorHandler'));
		}

		if (!self::$db->link) return false;

		if (config::get('core.cache')) {
			$cacher = Cache_Generic::init(
				config::get('core.use_memcached_db')?'memcache':'file'
			);
		} else $cacher=false;

		self::$db->setCacher($cacher);
		
		Db::_set_logger();
		
		//задаем префикс для таблиц
		self::$db->setIdentPrefix(config::get('core.prefix'));
		
		self::$connected=true;
	}
	
	public static function i()
	{
		return self::instance();
	}

	public static function instance()
	{
		if (self::$db === null) {
			new self;
		}
		return self::$db;
	}
	
	private static function _set_logger()
	{
		//если первичная инициализация конфига, то логируем в переменную
		if ('init'==config::get('core.debug_mode')) {
			self::$db->setLogger(array('Db', 'initLogger'));
		} elseif (config::get('core.debug_mode') || LabVars::$allow_debug) {
			if (config::get('core.debug_console')
				&& (!isset($_GET['data_type']) || !in_array(
					$_GET['data_type'],
					array('js', 'xml', 'json', 'ajax')
				))
			) {
				new Debug_HackerConsole_Main(true);
				$logger=array('Db', 'myLogger_console');
			} elseif (isset($_GET["debug"])) {
				$logger=array('Db', 'myLogger');
			}
			
			if (isset($logger) && is_array($logger)) {
				self::$db->setLogger($logger);
				if (self::$initLog) {
					foreach (self::$initLog as $sql) {
						call_user_func_array($logger, array(self::$db, $sql));
					}
					self::$initLog=array();
				}
			}
		}
	}
	
	static function databaseErrorHandler($message, $info)
	{
		if (!error_reporting()) return;
		if (config::get('core.debug_mode')
			|| $_SESSION['allow_debug']) {
			echo "SQL Error: $message<br><pre>"; print_r($info); echo "</pre>";
		} else {
			header("HTTP/1.0 503 Service Unavailable");
			$subject="Произошла ошибка на сайте ".$_SERVER["SERVER_NAME"];
			$body="Добрый день, "
			.($_SERVER["HTTP_REFERER"]?"когда я перешел со страницы "
			.$_SERVER["HTTP_REFERER"].",":'')." По адресу http://"
			.$_SERVER["SERVER_NAME"].$_SERVER['REDIRECT_URL']
			. " произошла ошибка. \nПрошу внести исправления.";
			
			$emails=explode(',', config::get('core.admin_mail'));
			echo "Произошла ошибка при работе с БД. Убедительная просьба "
			."сообщить о ней <a href='mailto:".trim($emails[0])
			."?subject=".rawurlencode(iconv("UTF-8", "CP1251", $subject))
			."&body=".rawurlencode(iconv("UTF-8", "CP1251", $body))
			."'>администрации</a>. Спасибо!";
			
			if (config::get('core.admin_mail')) {
				$filename=LAB_PATH_DATA.'/cache/error_'.md5($info['code'].$info['context']);
				if (!file_exists($filename) || filemtime($filename)<(time()-60*60)) {
					$mail=new Mailer(config::get('core.admin_mail'));
					$mail->From = 'bug@'.config::get('core.domain');
					$mail->FromName = "Ошибка сервера";
					$mail->Subject = $subject;
					$mail->Body    = $body."Error: $message\r\n".print_r($info, true).print_r($_SESSION, true);
					$mail->Send();
					touch($filename);
				}
			}
		}
		exit();
	}
	
	static function myLogger_console($db, $sql)
	{
		Debug_HackerConsole_Main::out($sql, "sql", null, "");
	}

	static function myLogger($db, $sql)
	{
		echo "<xmp title=''>";
		print_r($sql);
		echo "</xmp>";
	}
	
	static function initLogger($db, $sql)
	{
		self::$initLog[]=$sql;
	}
	
	/**
	 * Парсинг sql
	 *
	 * @param string $url
	 * @return boolean
	 * @author Akira, Loki
	 */
	static function parse_mysql_dump($url, $display=true)
	{
		
		$file_content = file($url);
		$query = "";
		$all_ok=true;
		foreach ($file_content as $key=>$sql_line) {
			$sql_line = trim($sql_line);
			if (($sql_line != "")
				&& (mb_substr($sql_line, 0, 2) != "--")
				&& (mb_substr($sql_line, 0, 1) != "#")
			) {
				$query .= $sql_line;
				if (preg_match('/;$/', $sql_line) || $key==(count($file_content)-1)) {
					$result = self::instance()->query($query);
					if (!self::instance()->error['code']) {
						if ($display) echo " <span style='color:#00F'>";
					} else {
						if ($display) {
							echo " <span style='color:#f00; font-weight:bold;'>Fail:";
						}
						$all_ok=false;
					}
					if ($display) echo htmlspecialchars($query)."</span><br />";
					$query = "";
				}
			}
		}
		return $all_ok;
	}
	
	public static function destroy()
	{
		self::$db=self::$connected=null;
	}
}