<?php

class Database{

	//获取编码
	function charset(){
		global $_G;
		return str_replace('-', '', $_G['product']['charset']);
	}

	//创建表
	function createtable( $sql, $dbcharset ) {
		$type = strtoupper(preg_replace("/^\s*CREATE TABLE\s+.+\s+\(.+?\).*(ENGINE|TYPE)\s*=\s*([a-z]+?).*$/isU", "\\2", $sql));
		$type = in_array($type, array('MYISAM', 'HEAP')) ? $type : 'MYISAM';
		return preg_replace("/^\s*(CREATE TABLE\s+.+\s+\(.+?\)).*$/isU", "\\1", $sql).
	(mysql_get_server_info() > '4.1' ? " ENGINE=$type DEFAULT CHARSET=$dbcharset" : " TYPE=$type");
	}

	//查询MySQL
	function query( $sql, $dbcharset = '' ){
	
		//默认编码
		$dbcharset = $dbcharset ? $dbcharset : self :: charset();

		//前辍
		$sql = str_replace("{TableManPre}",VI_DBMANPRE,$sql);
		$sql = str_replace("{TableModPre}",VI_DBMODPRE,$sql);
		
		//参数
		$sql = str_replace("{TableNow}",time(),$sql);
		$sql = str_replace("{TableIP}",GetIP(),$sql);
		
		//用户
		$sql = str_replace("{TableAdmin}",$_SESSION['Manager']['account']?$_SESSION['Manager']['account']:'admin',$sql);

		$sql = str_replace("\r", "\n", $sql);
		
		$ret = array();
		$num = 0;
		foreach(explode(";\n", trim($sql)) as $query) {
			$queries = explode("\n", trim($query));
			foreach($queries as $query) {
				$ret[$num] .= $query[0] == '#' || $query[0].$query[1] == '--' ? '' : $query;
			}
			$num++;
		}
		unset($sql);
		
		///////////////////////
		
		$succ = array();	//成功
		$fail = array();	//失败
		
		$ERR = 0;
		$MID = 0;

		foreach($ret as $query) {
			$query = trim($query);
			
			if($query) {
			
				if(substr($query, 0, 12) == 'CREATE TABLE') {
					
					$name = preg_replace("/CREATE TABLE ([a-z0-9_]+) .*/is", "\\1", $query);
					
					System :: $db -> execute( self :: createtable($query, $dbcharset) );
					
					if( mysql_errno() ){
						//$state .= '<h4>创建数据表出错</h4><p class="error">'.mysql_error().'</p>';
						
						array_push($fail,array('message'=>'创建数据表出错','query'=>$query,'error'=>mysql_error()));
						
						$ERR++;
					}else{
						//$state .= '<h4>成功创建数据表</h4><p class="note">'.$query.'</p>';
						
						array_push($succ,array('message'=>'成功创建数据表','query'=>$query));
					}

				} else {
					
					System :: $db -> execute( $query );
					
					if(mysql_errno()){
						//$state .= '<h4>写入数据出错</h4><p class="error">'.mysql_error().'</p>';
						array_push($fail,array('message'=>'执行查询出错','query'=>$query,'error'=>mysql_error()));
						$ERR++;
					}else{
						//$state .= '<h4>成功写入数据</h4><p class="note">'.$query.'</p>';
						array_push($succ,array('message'=>'成功执行查询','query'=>$query));
					}
				}

			}
		}
		
		return array('error'=>$ERR,'succ'=>$succ,'fail'=>$fail);
	}
        
	//////////////////////////////////
		
	//备份基准目录
	function direct( $dir ){
		return realpath("../../data/$dir/")."/";
	}
        
	/*
			导入 SQL 查询
			$sql    内容
	*/
	function import( $sql ){
	
		if( !$sql ) return false;
		
		ini_set("memory_limit","100M");
				
		//前置表前辍
		$sql = str_replace("{TableManPre}",VI_DBMANPRE,$sql);
		$sql = str_replace("{TableModPre}",VI_DBMODPRE,$sql);
		
		//参数
		$sql = str_replace("{TableNow}",time(),$sql);
		$sql = str_replace("{TableIP}",GetIP(),$sql);
	
		$array = self :: query( $sql );
		
		ini_set("memory_limit","12M");
		
		return $array;
			
	}
	
	/*
			导出 SQL 查询
			$file    文件名
	*/
	function export( $name ){
		global $_G;
		
		//ini_set("memory_limit","100M");
		
		$i = 0;

		//文件名为当天的日期
		$file = self :: direct( 'backup' ).$name.".sql";
		
		$handle = fopen( $file, "w");

		//缓存名称
		$text = '/*'.chr(13).'	VeryIDE '.$_G['product']['appname'].' '.$_G['product']['version'].chr(13).'	Host: '.VI_DBHOST.chr(13).'	Database: '.VI_DBNAME.chr(13).'	Name: '.$name.''.chr(13).'	Date: '.date("Y/m/d H:i:s").''.chr(13).'*/'.chr(13).chr(13);
		if( fwrite($handle, $text) === FALSE ){
			return $i;
		}

		//遍历数据表
		$tables = System :: $db -> getAll("show tables");
		
		$item = array();
		
		foreach( $tables as $row ){				
			foreach( $row as $key => $tab ){
				array_push( $item, $tab );					
			}				
		}
		
		foreach( $item as $table ){
			
			$sql = System :: $db -> getOne("show create table `$table`");

			# DLL
			$text = $sql['Create Table'].";\r\n\r\n";
			fwrite($handle, $text);

			//数据长度
			$size = System :: $db -> getValue("SELECT count(*) FROM `$table`");
			
			//起始长度
			for( $init = 0; $init < $size; $init += 1000 ){				
	
				//遍历字段
				$res = System :: $db -> getAll("SELECT * FROM `$table` limit $init, 1000");
	
				foreach( $res as $data ){
					
					$keys=array_keys($data);     
					$keys=array_map('addslashes',$keys);     
					$keys=join('`,`',$keys);     
					$keys="`".$keys."`";
					
					$vals=array_values($data);     
					$vals=array_map('addslashes',$vals);     
					$vals=join("','",$vals);     
					$vals="'".$vals."'";     
					   
					$text ="INSERT INTO `$table`($keys) values($vals);\r\n";
					fwrite($handle, $text);
					
					$i++;
				}     
				$text="\r\n";
				$i++;
				fwrite($handle, $text);
				
			}
			
		}
		
		//ini_set("memory_limit","12M");
		
		//return create_file( $file, $text );
		
		fclose($handle);
		
		return $i;
			
	}        
        
	//////////////////////////////////
	
	function update( $file ){
		
		$base = self :: direct( 'update' );
	
		$sqlfile = $base.$file;
                
		//锁文件
		$lock = str_replace(".sql",".lock",$sqlfile);
		
		if(file_exists($lock)){
			
			//echo '<div id="state" class="failure">抱歉！安装已经存在。更新于早前已经安装，并在使用中：<span class="text-key">'.$update.'</span></div>';
			return 'lock';
			
		}else{
			
			if(file_exists($sqlfile)){
				
				//日志开始时间
				$time = time();
			
				$sql = file_get_contents($sqlfile);
			
				$res = self :: query( $sql );
				
				if( $res['error'] == 0 ){
				
					//写入锁
					create_file( $lock ,date("Y-m-d H:i:s"));
		
					//写入日志
					System :: insert_event($func,$time,time(),"安装更新：".$update);
					
					//搜索模块
					Module :: search();
					
					//echo '<div id="state">恭喜！成功安装更新：'.$update.'</div>';				
					return 'done';
					
				}else{
					
					//echo '<div id="state" class="failure">抱歉！安装更新失败。以下是本错误信息详细报告：</div>';
					return 'stop';
					
					//trigger_error(str_replace('class="error"','class="text-no"',preg_replace('/<h4>(.*?)<\/h4>/','',$array[1])), E_USER_ERROR);
				}
				
			}
			
		}
		
	}
		
}

?>