<?php
if(!defined('IN_MICECMS')){header("HTTP/1.0 404 Not Found");die();}

$filesize=0;		//字符串大小
$filenewnum=0;		//文件名序号

function outfile($f, $s) {
	echo str_replace("\r\n", "<br>", $s);	
}

function write2File($fileName,$content){
	global $filesize,$filenewnum;

	//判断文件是否大于1024k,如果大于1024k,新内容写入下一个文件
	if($filesize>1024){
		$filenewnum=$filenewnum+1;		//文件名序号+1
		$filesize=0;
	}else{
		$filenewnum=$filenewnum+0;
		$filesize += strlen($content)/1024;
	}

	$fileName=str_replace("_-0", "_-".$filenewnum, $fileName);

	if(($fd = fopen($fileName,'a+')) === FALSE){
		die('Failed to open file for writing!');
	}

	fwrite($fd,$content);
	fclose($fd);
}

class DbBackup {

	function _meta_numeric_fix(&$meta) {
		if (!isset($meta->numeric)) {
			$meta->numeric = (	(strpos($meta->type, 'int')===0) ||
								(strpos($meta->type, 'tinyint')===0) ||
								(strpos($meta->type, 'float')!==false) ||
								(strpos($meta->type, 'numeric')!==false) ||
								(strpos($meta->type, 'decimal')!==false) ||
								(strpos($meta->type, 'double')!==false) ||
								(strpos($meta->type, 'real')!==false) );
		}
	}


	function mice_db_encode($s) {
		return str_replace("'", "''", $s);
	}

	//获得备份文件名
	function BackupFilename($compress,$dbtype) {
		$fname = MICE_DIR.MICE_PRIVATE.'backup/'.date('Y-m-d-H-i_').RandomString(4).'_-0-_.'.$dbtype.'.'.$compress;
		return $fname;
	}

	//备份sql
	function Backup($compress = 'echo',$dbtype) {
		$fname = $this->BackupFilename($compress,$dbtype);
		if ('sql'==$compress or 'php'==$compress) {
			$this->Create($fname,'write2File',$dbtype,$compress);
			return '';
		} elseif ('gz'==$compress) {
			$fname .= '.gz';
			$f = @gzopen($fname, 'wb');
			if ($f!==false) {
				$this->Create($f, 'gzwrite',$dbtype,$compress);
				gzclose($f);
				return $fname;
			}
			if (!$can_dump)
				return '';
		}else{
			$this->Create($f, 'outfile',$dbtype,$compress);
		}
		return '';
	}

	//创建sql
	function Create($f, $outf, $dbtype, $compress) {
		if('php'==$compress){
			$outf($f, "<?php die;?>");
		}
		global $conn;
		$tables = $conn->MetaTables();
		sort($tables);
		foreach ($tables as $table_name) {
			$table_meta=$conn->MetaColumns($table_name);
			/*echo '<pre>';
			print_r($table_meta);
			echo '</pre>';*/

			$table = '#__'.$table_name;
			$outf($f, "DROP TABLE $table;\r\n\r\n");
			$outcontent="CREATE TABLE $table (\r\n";
			$PRIMARYKEY='';
			if ($table_meta) {
				$keys = array_keys($table_meta);
				$num=0;
				foreach ($keys as $k) {
					$meta =& $table_meta[$k];
					$this->_meta_numeric_fix($meta);
					$num++;

					if( $meta->auto_increment==1 OR $meta->primary_key==1)
					{
						$outcontent.= $meta->name." INTEGER AUTO_INCREMENT";
						$PRIMARYKEY=$meta->name;
						continue ;
					}

					$outcontent.= ",\r\n".$meta->name.' ';
					$outcontent.= strtoupper($meta->type);
					if (($meta->max_length>0) && (strtoupper($meta->type)!=='INT')  && (strtoupper($meta->type)!=='INTEGER') && strtoupper($meta->type) != 'TEXT' && strtoupper($meta->type) != 'LONGTEXT'){ //跳过显示字段长度
						$outcontent.= "(".$meta->max_length.")";
					}
					if($meta->not_null OR strtoupper($meta->type)=='INT' OR strtoupper($meta->type)=='INTEGER'){
						$outcontent.= " NOT NULL";
					}
					if($meta->has_default && strtoupper($meta->type) != 'TEXT' && strtoupper($meta->type) != 'LONGTEXT' OR strtoupper($meta->type) == 'INT' OR strtoupper($meta->type)=='INTEGER' OR strtoupper($meta->type) == 'VARCHAR') {
						$outcontent.= " DEFAULT ";
						if ($meta->numeric OR strtoupper($meta->type) == 'INT' OR strtoupper($meta->type) == 'INTEGER') {
							$def = (string)$meta->default_value;
							if (!strlen($def)){
								$def='0';
							}
							$outcontent.= $def;
						} else {
							$outcontent.= "'".$this->mice_db_encode($meta->default_value)."'";
						}
					}
				}
			}
			$outcontent.= ",\r\nPRIMARY KEY (".$PRIMARYKEY.") \r\n) tableset;\r\n\r\n";
			$outf($f, $outcontent);
			
			$rscount=$conn->SelectCount($table,"*",'');
			$rsnum=0;
			for($rsc=0;$rsc<=$rscount;$rsc=$rsc+3000){
				$rsa=$conn->SelectArrayLimit($table, '*' ,'' ,$rsnum*3000 ,3000);
				$rsnum++;
				foreach($rsa as $row) {
					$outcontent = "INSERT INTO $table (";
					$c=sizeof($row);
					for($i=0;$i<$c-1;$i++) {
						$outcontent .= $table_meta[$keys[$i]]->name;
						if($table_meta[$keys[$i+1]]->name){
							$outcontent .= ',';
						}
					}
					$outcontent .= $table_meta[$keys[$c-1]]->name;
					$outcontent .= ") \nVALUES (";
					reset($table_meta);
					for($i=0;$i<$c;$i++) {
						if($table_meta[$keys[$i]]->name){
							$meta =& $table_meta[$keys[$i]];
							$val = $row[$meta->name];
							$sep = '';
							if($table_meta[$keys[$i+1]]->name)	$sep = ',';
							if (!$meta->numeric){
								$outcontent .= "'".$this->mice_db_encode($val)."'".$sep;
							}else{
								settype($val, 'string');
								$outcontent .= $val.$sep;
							}
						}
					}
					$outcontent .= ");\r\n\r\n";
					$outf($f, $outcontent);

					//if($rscount>3000){
						//$f=str_replace("__".($rsnum-1), "__".$rsnum, $f);
					//}
				}
			}
			
			//postgre数据库使用，非postgre数据库在恢复时会被去掉
			$outf($f, "SELECT setval('".$table."_".$PRIMARYKEY."_seq',max($PRIMARYKEY)) from $table;\r\n\r\n");
		}
	}
}
?>