<?php

/**
 *--------------------------------------
 * database
 *--------------------------------------
 * @project		: loga
 * @author		: cblee
 * @created		: 2016-07-02
 * @copyright	: (c)2016 AsThis
 *--------------------------------------
 */
defined('PFA_PATH') or exit('Access Denied');

class DatabaseModl extends Modl {
	public function __construct() {
		$this->autoCheckFields = false;
		parent::__construct();
	}

	public function get_tableList() {
		$tablelist = array('core' => array(), 'other' => array());
		$tables = $this->db->get_tables();
		if(empty($tables)) {
			return null;
		}
		foreach($tables as $table) {
			$tableInfo = $this->query('SHOW TABLE STATUS WHERE NAME = \''.$table.'\';');
			$tableInfo[0]['Data_length'] = byte_format($tableInfo[0]['Data_length']);
			$tableInfo[0]['Index_length'] = byte_format($tableInfo[0]['Index_length']);
			$tableInfo[0]['Data_free'] = byte_format($tableInfo[0]['Data_free']);
			if(preg_match('/^'.C('DB.PREFIX').'/', $tableInfo[0]['Name'])) {
				$tablelist['core'][] = $tableInfo[0];
			}
			else {
				$tablelist['other'][] = $tableInfo[0];
			}
		}
		return $tablelist;
	}

	public function backup_tableStructure($table, $mark) {
		$timestamp = substr(md5(date('YmdHis')), 0, 8);
		$structure = '';
		foreach($table as $table) {
			$structure .= $this->get_tableStructureSQL($table);
		}
		if(empty($structure)) {
			return false;
		}

		$dataDir = RUNTIME_PATH.D_S.'bak'.D_S.$mark;
		if(!is_dir($dataDir)) {
			mk_dir($dataDir);
		}

		$structureFilename = $dataDir.D_S.'table_structure_'.$timestamp.'.sql';
		return file_put_contents($structureFilename, trim($structure));
	}

	public function backup_tableData($table, $mark, $volumeSize = 2048, $limit = 5000) {
		$volumeSize *= 1024;
		$dataDir = RUNTIME_PATH.D_S.'bak'.D_S.$mark;
		if(!is_dir($dataDir)) {
			mk_dir($dataDir);
		}

		$timestamp = substr(md5(date('YmdHis')), 0, 8);

		$dataCount = M()->query('SELECT COUNT(*) AS pfa_count FROM `'.$table.'` LIMIT 1;');
		$dataCount = $dataCount[0]['pfa_count'];

		$start = 0;
		$content = "TRUNCATE TABLE `".$table."`;\r\n";
		for($p = 0; $p * $limit < $dataCount; $p++) {
			$data = M()->query('SELECT * FROM `'.$table.'` LIMIT '.$p * $limit.','.$limit.';');
			if(!empty($data)) {
				foreach($data as $k => $_data) {
					$content .= M('Database')->get_tableDataSQL($table, $_data);
					if($volumeSize <= strlen($content)) {
						$dataFilename = $dataDir.D_S.$table.'_'.$start.'_'.$timestamp.'.sql';
						if(!file_put_contents($dataFilename, $content)) {
							return false;
						}
						$content = '';
						$start++;
					}
				}
				$dataFilename = $dataDir.D_S.$table.'_'.$start.'_'.$timestamp.'.sql';
				if(!empty($content) and !file_put_contents($dataFilename, $content)) {
					return false;
				}
				$content = '';
				$start++;
			}
		}
		return true;
	}

	public function optimize_table($table) {
		if(!empty($table)) {
			$sql = "OPTIMIZE TABLE `{$table}`";
			if(false !== $this->query($sql)) {
				return true;
			}
		}
		return false;
	}

	public function repair_table($table) {
		if(!empty($table)) {
			$sql = "REPAIR TABLE `{$table}`";
			if(false !== $this->query($sql)) {
				return true;
			}
		}
		return false;
	}

	/* get table data INSERT SQL */
	public function get_tableDataSQL($table, $data) {
		$insertSql = 'INSERT INTO `'.$table.'` VALUES(';
		foreach($data as $key => $val) {
			if(is_int($key)) {
				continue;
			}
			$insertSql .= '\''.addslashes($val).'\',';
		}
		$insertSql = rtrim($insertSql, ',');
		$insertSql .= ");\r\n";
		return $insertSql;
	}

	/* get table structure SQL(database) */
	public function get_tableStructureSQL($table) {
		/* table structure */
		$tableStructure = "DROP TABLE IF EXISTS `".$table."`;\r\n";
		$_t_sct = $this->query('SHOW CREATE TABLE `'.$table.'`');
		$tableStructure .= $_t_sct[0]['Create Table'].";\r\n\r\n";
		return $tableStructure;
	}

	public function get_backupMarkList() {
		$_ML = array();

		$dh = dir(RUNTIME_PATH.D_S.'bak');
		while(false !== ($fs = $dh->read())) {
			if('.' == $fs or '..' == $fs or '.svn' == $fs or '_names.php' == $fs or 'index.html' == $fs) {
				continue;
			}

			if(is_dir(RUNTIME_PATH.D_S.'bak'.D_S.$fs)) {
				$_ML[] = $fs;
			}
		}
		return $_ML;
	}

	public function get_backupFileList($mark) {
		$_BFL = array(
			'structure' => '',
			'data_core' => array(),
			'data_other' => array(),
			);

		$dataDir = RUNTIME_PATH.D_S.'bak'.D_S.$mark;
		$fileList = array();
		if(!is_dir($dataDir)) {
			return null;
		}

		$dh = dir($dataDir);
		while(false !== ($filename = $dh->read())) {
			$fileList[] = $filename;
		}
		$dh->close();
		natsort($fileList);
		foreach($fileList as $filename) {
			$file = array(
				'filename' => $filename,
				'filesize' => byte_format(filesize($dataDir.D_S.$filename)),
				'backup_time' => date(C('APP.TIME_FORMAT'), filemtime($dataDir.D_S.$filename)),
				);
			if(preg_match("/^table_structure\_/", $filename)) {
				$_BFL['structure'] = $file;
			}
			elseif(preg_match('/^'.C('DB.PREFIX').'/', $filename)) {
				$_BFL['data_core'][] = $file;
			}
			elseif(preg_match('/\.sql$/', $filename)) {
				$_BFL['data_other'][] = $file;
			}
		}
		return $_BFL;
	}

	public function restore_data($dataFile, $mark) {
		$sql = file_get_contents(RUNTIME_PATH.D_S.'bak'.D_S.$mark.D_S.$dataFile);
		vendor('Sql#class');
		$sql = Sql::remove_comments(Sql::remove_remarks($sql));
		$query = trim_array(Sql::split_sql($sql));
		if(!empty($query)) {
			foreach($query as $q) {
				if(!empty($q) and false === $this->execute($q)) {
					return false;
				}
			}
		}
		return true;
	}

	/* show progress $barLength: % */
	public function show_progress($msg, $barLength = '50') {
		echo '<script>show_progress("'.$msg.'", "'.$barLength.'%");</script>';
		@ob_flush();
		@flush();
	}

	/* show direction */
	public function show_direction($nextUrl, $show = false) {
		if($show) {
			echo '<script>show_direction("'.$nextUrl.'")</script>';
		}
		echo '<script>location.href = "'.$nextUrl.'";</script>';
		@ob_flush();
		@flush();
	}

}

?>