<?php
// ¾«Ñ¸CMS¿ò¼ÜSQL²Ù×÷Ä£ÐÍ
class SqlModel extends Model {
	public $offset = 0;
	public $tableid = 0;
	public $sqlDump = '';
	public $reSetCharset = 0;
	public function execute($sql) {
		if ($this -> db() -> version() > '4.1' && C('DB_CHARSET', 1)) {
			if ($this -> reSetCharset) {
				$sql = preg_replace("/ENGINE=(InnoDB|MyISAM)([^;]+)?/i", "ENGINE=\\1 DEFAULT CHARSET=" . C('DB_CHARSET', 1), $sql);
			}
		}
		$sql = str_replace("\r", "\n", $sql);
		$num = 0;
		$tmp = explode(";\n", trim($sql));
		foreach($tmp as $query) {
			$sql = '';
			$queries = explode("\n", trim($query));
			$queries = array_filter($queries);
			foreach($queries as $query) {
				$str = substr($query, 0, 1);
				if ($str != '#' && $str != '-') $sql .= $query;
			}
			$this -> db() -> query($sql);
			$num++;
		}
		if (!$num) {
			$this -> db() -> query($sql);
			$num = 1;
		}
		return $num;
	}
	public function operate($work) {
		$work = strtoupper($work);
		if (!in_array($work, array('REPAIR', 'OPTIMIZE', 'CHECK', 'ANALYZE'))) {
			return L('ERROR_ACTION');
		}
		$selids = R('selids');
		$tables = explode(',', R('selids'));
		$tmp = array();
		foreach($tables as $table) {
			$table = trim($table);
			$tmp[] = $this -> db() -> addSpecialChar($table);
		}
		if (empty($tmp)) {
			return L('NOPARAM');
		} else $tables = implode(', ', $tmp);
		$rs = $this -> db() -> query($work . ' TABLE ' . $tables) ? L('OPERATE_SUCCESS') : L('OPERATE_FAIL');
		return $rs;
	}
	public function dumpTable($tables, $fileSize = 2048) {
		$this -> tableid = intval(R('tableid'));
		$this -> offset = intval(R('offset'));
		$this -> sqlDump = '';
		$cnt = count($tables);
		for($i = $this -> tableid; $i < $cnt && strlen($this -> sqlDump) < $fileSize * 1000; $i++) {
			$table = $this -> db() -> addSpecialChar($tables[$i]);
			if ($this -> offset == 0) {
				$this -> dumpTableCreate($table);
			}
			$this -> dumpTableData($table, $fileSize);
		}
		if ($this -> offset) {
			$this -> tableid = $i ? $i-1 : 0;
		} else $this -> tableid = $i;
		return $this -> sqlDump;
	}
	private function dumpTableCreate($table) {
		$this -> sqlDump .= "\nDROP TABLE IF EXISTS $table;\n";
		$tmp = $this -> db() -> query('SHOW CREATE TABLE ' . $table);
		$tmp = $this -> db() -> fetchRow($tmp);
		$this -> sqlDump .= $tmp[1] . ";\n\n";
		return true;
	}
	private function dumpTableData($table, $fileSize) {
		$this -> pageSize = 100;
		while (strlen($this -> sqlDump) < $fileSize * 1000) {
			$rs = $this -> db() -> query('SELECT * FROM ' . $table . ' LIMIT ' . $this -> offset . ', ' . $this -> pageSize);
			$numFields = $this -> db() -> numFields($rs);
			$numRows = $this -> db() -> numRows($rs);
			while ($row = $this -> db() -> fetchRow($rs)) {
				$comma = '';
				$this -> sqlDump .= 'INSERT INTO ' . $table . ' VALUES (';
				for($i = 0; $i < $numFields; $i++) {
					$this -> sqlDump .= $comma . "'" . $this -> db() -> escapeString($row[$i]) . "'";
					$comma = ',';
				}
				$this -> sqlDump .= ");\n";
				$this -> offset += 1;
				if (strlen($this -> sqlDump) >= $fileSize * 1000) {
					break 2;
				}
			}
			if ($numRows < $this -> pageSize) {
				$this -> offset = 0;
				break;
			}
		}
		return true;
	}
}