<?php
/**
 * DB 操作扩展库
 * @copyright reginx.com
 * $Id$
 */
class db_lib{

	/**
	 * 数据库操作对象
	 *
	 * @var unknown_type
	 */
	private $dbobj = null;

	/**
	 * 前缀标识串
	 *
	 * @var unknown_type
	 */
	private $pre = 'pre_';

	/**
	 * dir 
	 *
	 * @var unknown_type
	 */
	private $dir = '';

	public static function log($data = null){
		$log = array();
		if($data === null){
			if(file_exists(DATA_PATH . 'backup.log.php')){
				$log = include(DATA_PATH . 'backup.log.php');
			}
			return $log;
		}else{
			$str  = "<?php\r\n/**\r\n";
			$str .= " *  @Created By Reginx v".REGINX_VERSION." data backup log file\r\n";
			$str .= " *  @Time:" . date('Y-m-d H:i:s' , REQUEST_TIME) . "\r\n */";
			$str .= "\r\nreturn " . var_export($data , true) .  ";\r\n?>";
			return file_put_contents(DATA_PATH . 'backup.log.php' , $str , LOCK_EX);
		}
	}

	/**
	 * 架构函数
	 *
	 * @param unknown_type $conf
	 * @return db_lib
	 */
	public function db_lib($conf = array()){
		if(empty($this->dbobj)){
			$this->dbobj = db_extra::getobj($conf);
			$this->pre   = $conf[$conf['class']][$this->dbobj->serverid()]['pre'];
		}
	}

	/**
	 * 设置当前dir名称
	 *
	 * @param unknown_type $dir
	 */
	public function setdir($dir){
		$this->dir   = $dir;
		if(!is_dir(DATA_PATH . $this->dir)){
			core::makedir(DATA_PATH . $this->dir);
		}
	}

	/**
	 * 获取系统表
	 *
	 * @return unknown
	 */
	public function gettabs(){
		$ret = $tabs = array();
		$query = $this->dbobj->query('show tables');
		$plen = strlen($this->pre);
		while($tab = $this->dbobj->fetch_array($query , MYSQL_NUM)){
			if($this->pre == substr($tab[0] , 0 ,$plen) && substr($tab[0] , $plen) != 'temp'){
				$tabs[] = substr($tab[0] , $plen);
			}
		}
		if(!empty($tabs)){
			foreach ($tabs as $v){
				$q = $this->dbobj->query("show fields from {$this->pre}{$v}");
				while($row = $this->dbobj->fetch_array($q)){
					$type = 'int';
					if(strpos($row['Type'] , 'char') !== false || strpos($row['Type'] , 'text') !== false){
						$type = 'char';
					}
					$ret[$v][$row['Field']] =  $type;
				}
			}
		}
		return $ret;
	}

	/**
	 * 备份表结构
	 *
	 */
	public function tabdump($tabs){
		$file = DATA_PATH . $this->dir . '/struct.sql';
		$fp = fopen($file , 'w');
		foreach ($tabs as $v){
			fwrite($fp , $this->getstruct($v));
		}
		fclose($fp);
	}

	/**
	 * 获取表结构
	 *
	 * @param unknown_type $tab
	 * @return unknown
	 */
	public function getstruct($tab){
		$struct =  "\r\ndrop table if exists `{$this->pre}{$tab}`;\r\n";
		if(!empty($tab)){
			$query = $this->dbobj->query("show create table {$this->pre}{$tab}");
			$plen = strlen($this->pre);
			$tab = $this->dbobj->fetch_array($query , MYSQL_NUM);
			$struct .= $tab[1] . ";";
		}
		return $struct;
	}

	/**
	 * 分卷
	 *
	 * @param unknown_type $dir
	 * @param unknown_type $vsize
	 * @return unknown
	 */
	public function vol($dir , $vsize = 2097152 ){
		$ret = array();
		$this->setdir($dir);
		$fp = fopen(DATA_PATH . $this->dir . '/data.sql' , 'rb');
		$fname = DATA_PATH . $this->dir . '/vol_';
		$ret['size'] = filesize(DATA_PATH . $this->dir . '/data.sql');
		$i = 1;
		while (!feof($fp)) {
			if($vsize > 0){
				// 分卷
				file_put_contents($fname . $i . '.txt', fread($fp , ceil($vsize * 0.98)) . fgets($fp));
			}else{
				break;
			}
			$i++;
		}
		fclose($fp);
		$ret['dir'] = $dir;
		$ret['vol'] = $i;
		$ret['date'] = REQUEST_TIME;
		return $ret;
	}

	public function getsql($tab , $fields , $pn = 1){
		$file = DATA_PATH . $this->dir . '/data.sql';
		$limit = 3000;
		$start = ($pn - 1) * $limit;
		$ret['pn']    = $pn;
		$ret['limit'] = $limit;
		$ret['total'] = $this->dbobj->count("select count(*) from {$this->pre}{$tab}");
		$ret['max'] = ceil($ret['total'] / $ret['limit']);
		$fstr = '`' . strtolower(join('`,`' , array_keys($fields))) . '`';
		$fp = fopen($file , 'ab');
		$query = $this->dbobj->unbufquery("select {$fstr} from {$this->pre}{$tab} limit {$start},{$limit}");
		while ($row = $this->dbobj->fetch_array($query)) {
			$sql = "replace into {$this->pre}{$tab}({$fstr}) values (";
			$i = 0;
			foreach ($fields as $k => $v){
				$ischar = $v == 'char' ? 1 : 0;
				if($i === 0){
					$sql .= $ischar ? ("x'"  . bin2hex($row[$k]) . "'") : ("'{$row[$k]}'");
					$i = 1;
				}else{
					$sql .= $ischar ? (",x'"  . bin2hex($row[$k]) . "'") : (",'{$row[$k]}'");
				}
			}
			$sql .= ");\r\n";
			fwrite($fp , $sql);
			$sql = '';
		}
		fclose($fp);
		$ret['less'] = $ret['pn'] * $ret['limit'];
		return $ret;
	}


	/**
	 * 导入sql文件
	 *
	 * @param unknown_type $file
	 * @param unknown_type $lines
	 * @param unknown_type $seek
	 * @return unknown
	 */
	public function restore($file , $lines = 3000, $seek = 0){
		$ret = array();
		$ret['fsize'] = filesize($file);
		$fp = fopen($file , 'r');
		fseek($fp , $seek , SEEK_CUR);
		$index =  0;
		while(!feof($fp)){
			$sql = trim(fgets($fp));
			if(!empty($sql)){
				$this->dbobj->query($sql);
			}
			if($index == $lines){
				break;
			}
			$index++;
		}
		$ret['seek'] = ftell($fp);
		fclose($fp);
		return $ret;
	}


}

?>