ソースを参照

Update: update drive base file

Jinhui Zhu 5 年 前
コミット
1eb7b67cb4

+ 1 - 1
src/Cache/Loader.php

@@ -37,7 +37,7 @@ class Loader
         $this->cache = $cache;
         $cacheFile = dirname(__FILE__) . DS . DS . ucwords($cache) . '.php';
         if (!is_file($cacheFile)) {
-            throw new \Exception('Unsupport cache class '. $cacheFile);
+            throw new \Exception('Unsupported cache class '. $cacheFile);
         }
         \Qii\Autoloader\Import::requires($cacheFile);
     }

+ 1117 - 0
src/Driver/Base-backup2019-12-03.php

@@ -0,0 +1,1117 @@
+<?php
+
+namespace Qii\Driver;
+
+class Base
+{
+    const VERSION = '1.2';
+    public $cache;
+    public $language;
+    protected $_query = array(
+        "INSERT" => "INSERT INTO %s(%s) VALUES('%s')",
+        "REPLACE" => "REPLACE %s (%s) VALUES('%s')",
+        "SELECT" => "SELECT %s FROM %s",
+        "LEFT_JOIN" => " LEFT JOIN %s ON %s",
+        "RIGHT_JOIN" => " RIGHT JOIN %s ON %s",
+        "UPDATE" => "UPDATE %s SET ",
+        "DELETE" => "DELETE FROM %s %s",
+        "WHERE" => " WHERE %s",
+        "OR" => " `%s` = '%s' ",
+        "LIKE" => " `%s` LIKE '%s'",
+        "ORDER" => " ORDER BY %s %s",
+        "GROUP" => " GROUP BY %s",
+        "LIMIT" => " LIMIT %d, %d"
+    );
+    private $setArray = array();
+    public $modelSQL = "";
+    protected $fields;
+    protected $groupBy;
+    protected $limit;
+    protected $orderBy;
+    public $load;
+    public $where = null;
+    public $join = null;
+    /**
+     * @var string $response Response对象
+     */
+    public $response;
+
+    //方法对应的别名
+    protected $_modelAlias = array('selectRows' => 'selectAll', 'select' => 'selectRow', 'getOne' => 'selectOne', 'getRow' => 'selectRow', 'getAll' => 'selectAll', 'remove' => 'deleteRows');
+
+    public function __construct()
+    {
+        $this->language = \Qii\Autoloader\Psr4::getInstance()->loadClass('Qii\Language\Loader');
+        $this->load = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Autoloader\Loader');
+        $this->response = new \Qii\Driver\Response();
+    }
+
+    /**
+     * 获取数据库中所有的数据表
+     * @return array
+     */
+    public function getAllDatabases()
+    {
+        $sql = "SHOW DATABASES";
+        $rs = $this->setQuery($sql);
+
+        $database = array();
+        while ($row = $rs->fetch()) {
+            $database[] = $row['Database'];
+        }
+        return $database;
+    }
+
+    /**
+     * 数据库中是否包含指定库
+     * @param string $database 数据库名
+     * @return bool
+     */
+    public function hasDatabase($database)
+    {
+        if (!$database) return false;
+        $sql = "SHOW DATABASES LIKE '" . $database . "'";
+        $rs = $this->setQuery($sql);
+        while ($row = $rs->fetch()) {
+            $val = array_values($row);
+            if (in_array($database, $val)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 获取当前数据库中所有的表
+     * @param null|string $database 数据库
+     * @return array
+     */
+    public function getAllTables($database = null)
+    {
+        if ($database) {
+            $this->setQuery('USE ' . $database);
+        }
+        $sql = "SHOW TABLES";
+        $rs = $this->setQuery($sql);
+        $tables = array();
+        while ($row = $rs->fetch()) {
+            if (is_array($row)) {
+                foreach ($row AS $val) {
+                    $tables[] = $val;
+                }
+            }
+        }
+        return $tables;
+    }
+
+    /**
+     * 获取指定数据表的所有字段
+     * @param string $table 表名
+     * @param string $database 数据库名
+     * @param string $autoIncr 自动增长的序号
+     * @return array
+     */
+    public function getTableInfo($table, $database = null, $autoIncr = null)
+    {
+        if (!$database) $database = $this->currentDB;
+        $sql = "SELECT * from information_schema.COLUMNS where table_name = '" . $table . "' and table_schema = '" . $database . "'";
+        $data = ['fields' => [],
+            'rules' => [
+                'pri' => [], 'required' => []
+            ]
+        ];
+
+        $rs = $this->setQuery($sql);
+        while ($row = $rs->fetch()) {
+            $data['fields'][] = $row['COLUMN_NAME'];
+            if ($row['EXTRA']) {
+                $data['rules']['extra'][$row['EXTRA']][] = $row['COLUMN_NAME'];
+            }
+            if ($row['COLUMN_KEY'] == 'PRI') {
+                $data['rules']['pri'][] = $row['COLUMN_NAME'];
+                $data['rules']['required'][] = $row['COLUMN_NAME'];
+            }
+            if ($row['IS_NULLABLE'] == 'NO') {
+                $data['rules']['required'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], ['varchar', 'char'])) {
+                $data['rules']['maxlength'][$row['COLUMN_NAME']] = $row['CHARACTER_MAXIMUM_LENGTH'];
+            }
+            if (in_array($row['DATA_TYPE'], ['mediumtext', 'TINYTEXT', 'text', 'longtext'])) {
+                $data['rules']['text'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], ['bigint', 'int', 'smallint', 'tinyint', 'integer'])) {
+                preg_match('/[\d]{1,}/', $row['COLUMN_TYPE'], $matches);
+                $data['rules']['int'][$row['COLUMN_NAME']] = $matches[0];
+                $data['rules']['number'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], ['float', 'double', 'decimal'])) {
+                $data['rules']['float'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
+            }
+            if (in_array($row['DATA_TYPE'], ['timestamp', 'datatime'])) {
+                $data['rules']['timestamp'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], ['enum', 'set'])) {
+                $data['rules']['sets'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
+            }
+            if (isset($row['COLUMN_DEFAULT'])) {
+                $data['rules']['default'][$row['COLUMN_NAME']] = $row['COLUMN_DEFAULT'];
+            }
+        }
+        $data['sql'] = $this->getTableSQL($table, $database, $autoIncr);
+        return $data;
+    }
+
+    /**
+     * 从括号中获取指定的值
+     * @param string $str 需要获取的内容
+     * @return array
+     */
+    public function getValueFromBrackets($str)
+    {
+        preg_match("/(?:\()(.*)(?:\))/i", $str, $matches);
+        $str = $matches[1];
+        $a = explode(",", $str);
+        for ($i = 0; $i < count($a); $i++) {
+            $this->removeQuote($a[$i]);//从字符串中去除单引号
+        }
+        return $a;
+    }
+
+    /**
+     * 去除双引号
+     * @param string $str 去除双引号
+     */
+    public function removeQuote(&$str)
+    {
+        if (preg_match("/^\'/", $str)) {
+            $str = substr($str, 1, strlen($str) - 1);
+        }
+        if (preg_match("/\'$/", $str)) {
+            $str = substr($str, 0, strlen($str) - 1);
+        }
+        return $str;
+    }
+
+    /**
+     * 查询数据库中是否有指定的表
+     * @param string $tableName 表名
+     * @param null|string $database 数据库
+     * @return bool
+     */
+    public function hasTable($tableName, $database = null)
+    {
+        if ($database) {
+            $this->setQuery('USE ' . $database);
+        }
+        $sql = "SHOW TABLES LIKE '" . $tableName . "'";
+        $rs = $this->setQuery($sql);
+
+        $tables = array();
+        while ($row = $this->fetch($rs)) {
+            if (is_array($row)) {
+                foreach ($row AS $val) {
+                    if ($val == $tableName) return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 获取创建表的SQL语句
+     * @param string $tableName 表名
+     * @param null|string $database 数据库
+     * @param int|null $autoIncr 自增长的值,null的话就不使用
+     * @return string
+     */
+    public function getTableSQL($tableName, $database = null, $autoIncr = null)
+    {
+        if ($database) {
+            $this->setQuery('USE ' . $database);
+        }
+        $row = $this->getRow("SHOW CREATE TABLE `" . $tableName . "`");
+        if (!$row) {
+            throw new \Exception('数据表不存在', __LINE__);
+        }
+        $sql = $row['Create Table'];
+        if ($autoIncr === null) {
+            return $sql;
+        }
+        return preg_replace("/AUTO_INCREMENT=[\d]{1,}/", "AUTO_INCREMENT=" . intval($autoIncr), $sql);
+    }
+
+    /**
+     * 通过数据表名称获取规则
+     * @param string $table 表名
+     * @param string $database 数据库名
+     */
+    public function buildRulesForTable($table, $database = null)
+    {
+        if (!$database) $database = $this->currentDB;
+        $tableInfo = $this->getTableInfo($table, $database);
+        $rules = new \Qii\Base\Rules();
+        $rules->addFields($tableInfo['fields']);
+        if ($tableInfo['rules']['required']) {
+            $rules->addForceValidKey($tableInfo['rules']['required']);
+        }
+        if (isset($tableInfo['rules']['number'])) {
+            foreach ($tableInfo['rules']['number'] as $key => $value) {
+                $rules->addRules($value, 'number', true, $value . '字段必须是数字');
+            }
+        }
+        if (isset($tableInfo['rules']['maxlength'])) {
+            foreach ($tableInfo['rules']['maxlength'] as $key => $value) {
+                $rules->addRules($key, 'maxlength', $value, $key . '字段内容长度不能大于' . $value . '个字符');
+            }
+        }
+        if (isset($tableInfo['rules']['timestamp'])) {
+            foreach ($tableInfo['rules']['timestamp'] as $key => $value) {
+                $rules->addRules($value, 'datetime', true, $value . '字段必须为日期格式');
+            }
+        }
+        return $rules;
+    }
+
+    final public function getAlias($alias)
+    {
+        return isset($this->_modelAlias[$alias]) ? $this->_modelAlias[$alias] : null;
+    }
+
+    /**
+     * 设置Cache
+     *
+     * @param String $cache
+     * @param Array $policy
+     */
+    final public function setCache($cache, $policy)
+    {
+        \Qii\Autoloader\Import::requires(Qii_DIR . DS . 'Qii' . DS . 'Cache.php');
+        $this->cache = \Qii\Autoloader\Psr4::loadClass('\Qii\Cache', $cache)->initialization($policy);//载入cache类文件
+    }
+
+    /**
+     * 缓存内容
+     *
+     * @param String $id
+     * @param Array $value
+     * @return Bool
+     */
+    final public function cache($id, $value)
+    {
+        return $this->cache->set($id, $value);
+    }
+
+    /**
+     * 获取缓存的类
+     */
+    final public function getCache()
+    {
+        return $this->cache;
+    }
+
+    /**
+     * 获取缓存内容
+     *
+     * @param String $id
+     * @return Array
+     */
+    final public function getCacheData($id)
+    {
+        return $this->cache->get($id);
+    }
+
+    /**
+     * 获取表的名称
+     * @param String $table
+     * @return String
+     */
+    public function getTable($table)
+    {
+        list($database, $tableName) = array_pad(explode('.', $table), 2, '');
+
+        if ($tableName) {
+            $tableName = stristr($tableName, '`') || stristr($tableName, " ") ? $tableName : '`'. $tableName .'`';
+            return "`{$database}`.`{$tableName}`";
+        }
+        $table = stristr($table, '`') || stristr($tableName, " ")  ? $table : '`'. $table .'`';
+        return $table;
+    }
+
+    public function setLanguage()
+    {
+        $this->language = \Qii\Autoloader\Psr4::loadClass('Qii\Language\Loader');
+    }
+
+    /**
+     *
+     * Insert Object
+     * @param String $table
+     * @param Array|Object $dataArray
+     */
+    final function insertObject($table, $dataArray)
+    {
+        if (empty($table)) {
+            return -1;
+        }
+        if (sizeof($dataArray) > 0 || (is_object($dataArray) && get_object_vars($dataArray)) > 0) {
+            $keys = array();
+            $values = array();
+            foreach ($dataArray AS $key => $value) {
+                $keys[] = $key;
+                if (is_array($value)) {
+                    throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
+                }
+                $values[] = $this->setQuote($value);
+            }
+
+            $this->modelSQL = $sql = "INSERT INTO " . $this->getTable($table) . "(`" . join("`, `", $keys) . "`) VALUES('" . join("', '", $values) . "')";
+            $this->setQuery($sql);
+            $this->cleanData();
+            $this->setError();
+            return $this->lastInsertId();
+        }
+        return -2;
+    }
+
+    /**
+     * 左连表
+     *
+     * @param string $table 表名
+     * @param string $on on条件
+     * @return $this
+     */
+    final function leftJoinObject($table, $on)
+    {
+        if(empty($table) || empty($on)) return $this;
+
+        $this->join .= sprintf($this->_query['LEFT_JOIN'], $table, $on);
+        return $this;
+    }
+
+    /**
+     * 右连表
+     *
+     * @param string $table 表名
+     * @param string $on on条件
+     * @return $this
+     */
+    final function rightJoinObject($table, $on)
+    {
+        if(empty($table) || empty($on)) return $this;
+
+        $this->join .= sprintf($this->_query['RIGHT_JOIN'], $table, $on);
+        return $this;
+    }
+
+    /**
+     *
+     * Replace Object
+     * @param String $table
+     * @param Array|Object $dataArray
+     */
+    final function replaceObject($table, $dataArray)
+    {
+        if (empty($table)) {
+            return -1;
+        }
+        if (sizeof($dataArray) > 0 || get_object_vars($dataArray) > 0) {
+            $keys = array();
+            $values = array();
+            foreach ($dataArray AS $key => $value) {
+                $keys[] = $key;
+                if (is_array($value)) {
+                    throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
+                }
+                $values[] = $this->setQuote($value);
+            }
+            $this->modelSQL = $sql = "REPLACE INTO " . $this->getTable($table) . "(`" . join("`, `", $keys) . "`) VALUES('" . join("', '", $values) . "')";
+            $rs = $this->setQuery($sql);
+            $this->cleanData();
+            $this->setError();
+            return $this->AffectedRows($rs);
+        }
+        return -2;
+    }
+
+    /**
+     *
+     * Update data
+     * @param String $table
+     * @param Array|Objct $dataArray
+     * @param Array $keys
+     */
+    final function updateObject($table, $dataArray, $keys = array())
+    {
+        if (empty($table) || !is_array($keys)) {
+            return -1;
+        }
+        if (sizeof($dataArray) > 0 || get_object_vars($dataArray) > 0) {
+            $values = array();
+            $where = array();
+            foreach ($dataArray AS $key => $value) {
+                if (is_array($value)) {
+                    throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
+                }
+                $value = $this->setQuote($value);
+                if (in_array($key, $keys)) {
+                    $where[] = "`{$key}` = '" . $value . "'";
+                } else {
+                    $values[] = "`{$key}` = '" . $value . "'";
+                }
+            }
+            //$keys为key => value的方式,就直接用keys
+            if (empty($where) && count($keys) > 0) {
+                foreach ($keys as $key => $value) {
+                    $value = $this->setQuote($value);
+                    $where[] = "`{$key}` = '" . $value . "'";
+                }
+            }
+            $whereSQL = $this->where;
+            if (sizeof($where) > 0) {
+                $whereSQL = $this->where ? $this->where . " AND (" . join(" AND ", $where) . ")" : " WHERE " . join(" AND ", $where);
+            }
+            $this->modelSQL = $sql = "UPDATE " . $this->getTable($table) . " SET " . join(", ", $values) . $whereSQL;
+            $rs = $this->setQuery($sql);
+            $this->cleanData();
+            $this->setError();
+            return $this->AffectedRows($rs);
+        }
+        return 0;
+    }
+
+    /**
+     *
+     * 删除数据
+     * @param String $table
+     * @param Array $keys
+     */
+    final function deleteObject($table, $keys = array())
+    {
+        if (empty($table)) {
+            return -1;
+        }
+        $where = array();
+        if (sizeof($keys) > 0 || (is_a($keys, 'stdclass') && get_object_vars($keys))) {
+            foreach ($keys AS $k => $v) {
+                $where[] = "`{$k}` = '" . $this->setQuote($v) . "'";
+            }
+        }
+        $whereSQL = $this->where;
+        if (sizeof($where) > 0) {
+            $whereSQL = $this->where ? $this->where . " AND (" . join(" AND ", $where) . ")" : " WHERE " . join(" AND ", $where);
+        }
+        $this->modelSQL = $sql = "DELETE FROM " . $this->getTable($table) . " " . $whereSQL;
+        $rs = $this->query($sql);
+        $this->cleanData();
+        $this->setError();
+        return $this->AffectedRows($rs);
+    }
+
+    /**
+     * 需要清除的数据
+     *
+     * @return array
+     */
+    final function cleanOptions()
+    {
+        return array('fields', 'where', 'groupBy', 'orderBy', 'limit', 'setArray', 'join');
+    }
+
+    /**
+     * 清除数据
+     *
+     */
+    final function cleanData()
+    {
+        $array = $this->cleanOptions();
+        foreach ($array AS $k) {
+            if (is_array($this->$k)) {
+                $this->$k = array();
+            } else {
+                $this->$k = null;
+            }
+        }
+    }
+
+    /**
+     *
+     * 查询的字段
+     * @param String $fields
+     */
+    final function fields($fields = "*")
+    {
+        $this->fields = null;
+        if (empty($fields)) $fields = "*";
+        if (is_array($fields)) {
+            foreach($fields as $key => $val)
+            {
+                $alias = explode('.', $val);
+                if(count($alias) > 1)
+                {
+                    $fields[$key] = $alias[0] . ".`".join(".", array_slice($alias, 1))."`";
+                }
+            }
+            $fields = join(',', $fields);
+        }
+        $this->fields = $fields;
+        return $this;
+    }
+
+    /**
+     *
+     * GROUP BY方法
+     * @param String $fields
+     */
+    final function groupBy($fields)
+    {
+        $this->groupBy = null;
+        if (!empty($fields)) {
+            $fields = is_array($fields) ? join(', ', $fields) : $fields;
+            $this->groupBy = sprintf($this->_query['GROUP'], $fields);
+        }
+        return $this;
+    }
+
+    /**
+     *
+     * 插入数据用
+     * @param Array $array
+     */
+    final function dataArray($array)
+    {
+        $this->fileds = null;
+        if (is_array($array)) {
+            $tmpArray = array();
+            foreach ($array AS $k => $v) {
+                $tmpArray['k'][] = $this->setQuote($k);
+                $tmpArray['v'][] = $this->setQuote($v);
+            }
+            $this->fileds = $tmpArray;
+        }
+        return $this;
+    }
+
+    /**
+     *
+     * Order By函数
+     * @param String $field
+     * @param String $orderBy
+     */
+    final function orderBy($field, $orderBy)
+    {
+        if (!empty($field)) return $this;
+
+        if ($this->orderBy != '') {
+            $this->orderBy .= $field . ' ' . $orderBy;
+        } else {
+            $this->orderBy = sprintf($this->_query['ORDER'], $field, $orderBy);
+        }
+    }
+
+    /**
+     * 多个order by条件
+     */
+    final function orderByArr($map)
+    {
+        if (empty($map)) return $this;
+        foreach ($map AS $val) {
+            $this->orderBy($val['field'], $val['orderBy']);
+        }
+        return $this;
+    }
+
+    /**
+     * order by
+     * @param string order by
+     */
+    final function orderByStr($orderBy)
+    {
+        if (!$orderBy) return $this;
+        $this->orderBy = $orderBy;
+        return $this;
+    }
+
+    /**
+     *
+     * Limit函数,如果省略第二个参数则第一个为0,第二个参数值取第一个
+     * @param Int $limit
+     * @param Int $offset
+     */
+    final function limit($limit, $offset = 0)
+    {
+        $this->limit = null;
+        if ($limit !== '') {
+            if (!$offset) {
+                $this->limit = sprintf($this->_query["LIMIT"], 0, $limit);
+            } else {
+                $this->limit = sprintf($this->_query["LIMIT"], $limit, $offset);
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * 创建Like查询条件
+     * @param string | array $like like的条件
+     */
+    final function like($like)
+    {
+        if (empty($like)) return $this;
+        $likeArray = array();
+        if ($like && !is_array($like)) {
+            $likeArray[] = $like;
+        } else {
+            foreach ($like AS $key => $val) {
+                if(stristr($key, '.')) {
+                    $likeArray[] = sprintf("%s LIKE '%s'", $key, "%" . $this->setQuote($val) . "%");
+                }else{
+                    $likeArray[] = sprintf($this->_query['LIKE'], $key, "%" . $this->setQuote($val) . "%");
+                }
+            }
+        }
+        if (count($likeArray) > 0) {
+            $likeSQL = join(" OR ", $likeArray);
+            if (!$this->where) {
+                $this->where = sprintf($this->_query["WHERE"], $likeSQL);
+            } else {
+                $this->where .= ' AND (' . $likeSQL . ')';
+            }
+        }
+        return $this;
+    }
+    /**
+     * 不包含的条件
+     * @param array $where 条件
+     * @return $this
+     */
+    final function exclude($where)
+    {
+        if (empty($where)) return $this;
+        $whereArray = array();
+        if ($where && !is_array($where)) {
+            $whereArray[] = $where;
+        } else {
+            foreach ($where AS $key => $val) {
+            	$whereArray[] = sprintf("%s != '%s'", $key, $this->setQuote($val));
+            }
+        }
+        if (count($whereArray) > 0) {
+            $whereSQL = join(" AND ", $whereArray);
+            if (!$this->where) {
+                $this->where = sprintf($this->_query["WHERE"], $whereSQL);
+            } else {
+                $this->where .= ' AND (' . $whereSQL . ')';
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * 传的条件为数组
+     * @param  Array $where 条件
+     * @return Object       对象本身
+     */
+    final function whereArray($where)
+    {
+        $this->where = null;
+        if (!empty($where)) {
+            $whereArray = array();
+            foreach ($where AS $k => $v) {
+                $v = $this->setQuote($v);
+                if(stristr($k, '.')) {
+                    $whereArray[] = " {$k} = '{$v}'";
+                }else{
+                    $whereArray[] = " `{$k}` = '{$v}'";
+                }
+            }
+            if (sizeof($whereArray) > 0) {
+                $whereSQL = join(" AND ", $whereArray);
+                if (!$this->where) {
+                    $this->where = sprintf($this->_query["WHERE"], $whereSQL);
+                } else {
+                    $this->where .= " AND (" . $whereSQL . ")";
+                }
+            }
+        }
+        return $this;
+    }
+
+    /**
+     *
+     * WHERE 子句
+     * @param String $where
+     */
+    final function where($where)
+    {
+        if (is_array($where)) return $this->whereArray($where);
+        $this->where = null;
+        if (!empty($where)) {
+            $this->where = sprintf($this->_query["WHERE"], $where);
+        }
+        return $this;
+    }
+    /**
+     * 操作where条件语句
+     *
+     * @param $and
+     * @param string $insideBrackets or条件里边的操作符
+     * @param string $outsideBrackets 链接or条件的操作符
+     * @return $this
+     */
+    final function and($and, $insideBrackets = "OR", $outsideBrackets = "AND") {
+        return $this->or($and, $insideBrackets, $outsideBrackets);
+    }
+    /**
+     * 操作where条件语句
+     *
+     * @param $or
+     * @param string $insideBrackets or条件里边的操作符
+     * @param string $outsideBrackets 链接or条件的操作符
+     * @return $this
+     */
+    final function andStr($or, $insideBrackets = "AND", $outsideBrackets = "OR") {
+        return $this->orStr($or, $insideBrackets, $outsideBrackets);
+    }
+    /**
+     * 操作where条件语句
+     *
+     * @param $or
+     * @param string $insideBrackets or条件里边的操作符
+     * @param string $outsideBrackets 链接or条件的操作符
+     * @return $this
+     */
+    final function or($or, $insideBrackets = "AND", $outsideBrackets = "OR")
+    {
+        if(empty($or)) return $this;
+        $orCond = array();
+        if(is_array($or)) {
+            foreach($or as $key => $val) {
+                $orCond[] = sprintf($this->_query['OR'], $key, $this->setQuote($val));
+            }
+        }
+        else
+        {
+            $orCond[] = $or;
+        }
+        if(!empty($this->where)) {
+            $this->where .= " ". $outsideBrackets. "  (". join(" ". $insideBrackets . " ", $orCond) .")";
+        }else{
+            $this->where = " WHERE (". join(" ". $insideBrackets . " ", $orCond) .")";
+        }
+        return $this;
+    }
+    /**
+     * 操作where条件语句
+     *
+     * @param $or
+     * @param string $insideBrackets or条件里边的操作符
+     * @param string $outsideBrackets 链接or条件的操作符
+     * @return $this
+     */
+    final function orStr($or, $insideBrackets = "AND", $outsideBrackets = "OR") {
+        if(empty($or)) return $this;
+        if(is_array($or)) {
+            $or = join(" ". $insideBrackets . " ", $or);
+        }
+        if(!empty($this->where)) {
+            $this->where .= " ". $outsideBrackets ." (". $or . ")";
+        }
+        return $this;
+    }
+
+    /**
+     * 创建插入表的SQL
+     */
+    final function createInsertSQL($table)
+    {
+        $sql = sprintf($this->_query['INSERT'], $table, join(",", $this->fileds['k']), join("', '", $this->fileds['v']));
+        $this->cleanData();
+        return $sql;
+    }
+
+    /**
+     *
+     * 插入数据到指定表中
+     * @param String $table
+     */
+    final function insertRow($table)
+    {
+        $this->modelSQL = $sql = $this->createInsertSQL($table);
+        $this->setQuery($sql);
+        return $this->lastInsertId();
+    }
+
+    /**
+     * 创建replace object SQL
+     *
+     * @param string $table 表名
+     * @return string
+     */
+    final function createReplaceSQL($table)
+    {
+        $sql = sprintf($this->_query['REPLACE'], $table, join(",", $this->fileds['k']), join("', '", $this->fileds['v']));
+        $this->cleanData();
+        return $sql;
+    }
+
+    /**
+     *
+     * Replace方法
+     * @param String $table
+     */
+    final function replaceRow($table)
+    {
+        $this->modelSQL = $sql = $this->createReplaceSQL($table);
+        return $this->exec($sql);
+    }
+
+    /**
+     *
+     * 查询一行
+     * @param String $table
+     */
+    final function selectRow($table)
+    {
+        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        $this->cleanData();
+        return $this->getRow($sql);
+    }
+
+
+    /**
+     *
+     * 查询一行
+     * @param String $table
+     */
+    final function selectOne($table)
+    {
+        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        return $this->getOne($sql);
+    }
+
+    /**
+     * 创建SELECT SQL
+     */
+    final function createSelectSQL($table)
+    {
+
+        if(stristr($table, '.') == false
+            && stristr($table, '`') == false
+            && stristr($table, ' ') == false
+        ) {
+            $table = '`'. $table .'`';
+        }
+        $sql = sprintf($this->_query['SELECT'], ((trim($this->fields) != '') ? $this->fields : "*"), $table) . $this->join . $this->where . $this->groupBy . $this->orderBy . $this->limit;
+        $this->cleanData();
+        return $sql;
+    }
+
+    /**
+     *
+     * 查询所有
+     * @param String $table 数据表名称
+     * @return Array
+     */
+    final function selectAll($table)
+    {
+        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        return $this->getAll($sql);
+    }
+
+    /**
+     * 返回resource资源
+     * @param string $table 数据表名称
+     */
+    final function rs($table)
+    {
+        $this->modelSQL = $sql = sprintf($this->_query['SELECT'], ((trim($this->fields) != '') ? $this->fields : "*"), $table) . $this->join . $this->where . $this->groupBy . $this->orderBy . $this->limit;
+        $this->cleanData();
+        return $this->setQuery($sql);
+    }
+
+    /**
+     * 将指定字段减指定值
+     *
+     * @param array $data 数据
+     * @return $this
+     */
+    final function downsetCounter($data)
+    {
+        if (is_array($data)) {
+            foreach ($data AS $k => $value) {
+                $this->setArray[] = $k . "=" . $k . '-' . $value;
+            }
+        }
+        $this->set(null);
+        return $this;
+    }
+
+    /**
+     * 将指定字段加指定值
+     *
+     * @param $data
+     * @return $this
+     */
+    final function upsetCounter($data)
+    {
+        if (is_array($data)) {
+            foreach ($data AS $k => $value) {
+                $this->setArray[] = $k . "=" . $k . '+' . $value;
+            }
+        }
+        $this->set(null);
+        return $this;
+    }
+
+    /**
+     * 更新数据时候用,方法同setData
+     * @param Array $data
+     */
+    final function set($data)
+    {
+        return $this->setData($data);
+    }
+
+    /**
+     *
+     * 更新数据时候用
+     * @param Array $data
+     * @return $this
+     */
+    final function setData($data)
+    {
+        if (is_array($data)) {
+            $set = array();
+            foreach ($data AS $k => $value) {
+                $set[] = $k . "='" . $this->setQuote($value) . "'";
+            }
+            if (sizeof($this->setArray) > 0) {
+                $this->set = " " . join(", ", $set) . ", " . join(",", $this->setArray);
+            } else {
+                $this->set = " " . join(", ", $set);
+            }
+        } else {
+            if (sizeof($this->setArray) > 0) {
+                $this->set = join(",", $this->setArray);
+            } else {
+                $this->set = "";
+            }
+        }
+        return $this;
+    }
+    /**
+     *
+     * 执行更新操作
+     * @param $table
+     * @return Int 返回影响的行数
+     */
+    final function updateRows($table)
+    {
+        $this->modelSQL = $sql = sprintf($this->_query['UPDATE'], $table) . $this->set . $this->where . $this->limit;
+        $this->cleanData();
+        return $this->exec($sql);
+    }
+
+    /**
+     *
+     * 执行删除操作
+     * @param String $table
+     */
+    final function deleteRows($table)
+    {
+        $this->modelSQL = $sql = sprintf($this->_query['DELETE'], $table, $this->where) . $this->limit;
+        $this->cleanData();
+        return $this->exec($sql);
+    }
+
+    /**
+     * 执行Model过程中保存的相关信息
+     *
+     * @param String $option
+     * @return Mix
+     */
+    final function querySQL($option = '')
+    {
+        $allow = array('_queryTimes', '_querySeconds', '_errorInfo', '_exeSQL');
+        if (in_array($option, $allow)) {
+            return $this->{$option};
+        }
+        return 0;
+    }
+
+    /**
+     * 将结果编码一下
+     * @param String $word
+     * @return String|multitype:
+     */
+    public function setQuote($word)//过滤sql字符
+    {
+        if (ini_get("magic_quotes_gpc")) {
+            return $word;
+        }
+        return is_array($word) ? array_map('addslashes', $word) : addslashes($word);
+    }
+
+    /**
+     * 获取错误码
+     */
+    public function getCode()
+    {
+        return $this->response->getCode();
+    }
+
+    /**
+     * 获取错误信息
+     */
+    public function getMessage()
+    {
+        if ($this->response->isError()) {
+            return $this->response->getMessage();
+        }
+    }
+
+    /**
+     * 返回response对象
+     *
+     * @return Bool
+     */
+    public function getResponse()
+    {
+        return $this->response;
+    }
+
+    /**
+     * 转换字符创
+     *
+     * @param $str
+     * @return array|string
+     */
+    public function iconv($str)
+    {
+        if (is_array($str)) {
+            return array_map(function ($n) {
+                return toUtf8($n);
+            }, $str);
+        }
+        return toUtf8($str);
+    }
+
+    /**
+     * 如果不存在指定的方法则调用提示错误
+     *
+     * @param String $name
+     * @param Mix $args
+     * @return Mix
+     */
+    public function __call($method, $argvs)
+    {
+        if (isset($this->_modelAlias[$method])) {
+            if (method_exists($this, $this->_modelAlias[$method])) {
+                return call_user_func_array(array($this, $this->_modelAlias[$method]), $argvs);
+            }
+            \Qii::setError(false, __LINE__, 1506, 'Alias ' . get_called_class() . '->' . $method . '()');
+        }
+        \Qii::setError(false, __LINE__, 1506, get_called_class() . '->' . $method . '()');
+    }
+}

+ 826 - 788
src/Driver/Base.php

@@ -1,43 +1,80 @@
 <?php
 
 namespace Qii\Driver;
-
+/**
+ * Class Base
+ * @package Qii\Driver
+ * 使用方法
+ * class base extends \Qii\Driver\Model {
+ *      public function __construct()
+ *      {
+ *          parent::__construct();
+ *      }
+ *      public function demo()
+ *      {
+ *           $this->db->fields("*")->join(array("leftJoin", array('table' => 'ad_site', 'alias' => 'b', 'on' => 'a.uid = b.uid')))->where(array('a.create_at:greater' => 1))->limit(10)->groupBy(array('a.uid', 'a.create_at'))->orderBy(array('a.uid' => 'desc'))->selectAll('user a');
+ *           $this->db->where(array('uid' => 1))->set(array('create_at:plus' => time(), 'status' => 1))->update('user');
+ *           $this->db->updateObject('user', array('create_at:plus' => time(), 'status' => 1), array('uid' => 1));
+ *           $this->db->where(array('uid:greater' => 1))->delete('user');
+ *           $this->db->deleteObject('user', array('uid' => 1));
+ *           $this->db->where(array('uid:greater' => 1))->like("email like '%test@test.com%'")->selectAll('user');
+ *           $this->db->where(array('uid:greater' => 1))->where("or")->like(array('email' => 'test@testcom'))->selectAll('user');
+ *           $this->db->where(array('uid:greater' => 1, 'or', 'email:like' => 'test@test.com'))->selectAll('user');
+ *           $this->db->where(array('uid:greater' => 1))->where("OR")->like(array('email' => 'test@test.com'))->selectAll('user');
+ *           $this->db->where(array('name' => 'antsnet'))->exclude(array('email' => 'test@test.com', 'status' => 1))->selectAll('user');
+ *           $this->db->where(array('name' => 'antsnet'))->or(array('email' => 'test@test.com', 'status' => 1))->selectAll('user');
+ *           $this->db->or(array('email' => 'test@test.com', 'status' => 1))->selectAll('user');
+ *           $this->db->join(array("leftJoin", array("table" => 'table', 'alias' => 'a', 'on' => 'a.id=b.id')));
+ *           $this->db->join(" LEFT JOIN table c on c.id=a.id")->selectAll('use a');
+ *           $this->db->where(array('email:unequal' => 'test@test.com'))->in(array('uid:in' => array('1,2,3'), 'status' => array(1)))->selectAll('user');
+ *           $this->db->where(array(array('email:unequal' => 'test@test.com'), array('uid:in' => array('1,2,3'), 'status:in' => array(1))))->selectAll('user');
+ *      }
+ * }
+ */
 class Base
 {
-    const VERSION = '1.2';
-    public $cache;
-    public $language;
+    const VERSION = '1.3';
+    use traitDatabase;
+    use traitCache;
+    //query 方法
     protected $_query = array(
         "INSERT" => "INSERT INTO %s(%s) VALUES('%s')",
         "REPLACE" => "REPLACE %s (%s) VALUES('%s')",
-        "SELECT" => "SELECT %s FROM %s",
-        "LEFT_JOIN" => " LEFT JOIN %s ON %s",
-        "RIGHT_JOIN" => " RIGHT JOIN %s ON %s",
+        "SELECT" => "SELECT %s FROM `%s` %s",
         "UPDATE" => "UPDATE %s SET ",
         "DELETE" => "DELETE FROM %s %s",
         "WHERE" => " WHERE %s",
         "OR" => " `%s` = '%s' ",
-        "LIKE" => " `%s` LIKE '%s'",
         "ORDER" => " ORDER BY %s %s",
         "GROUP" => " GROUP BY %s",
         "LIMIT" => " LIMIT %d, %d"
     );
-    private $setArray = array();
+    //load类
+    public $load;
+    //cache类
+    public $cache;
+    //语言包
+    public $language;
+    //响应内容
+    public $response;
+    //执行的sql语句
     public $modelSQL = "";
-    protected $fields;
+
+    public $operateVal = array('or', 'and', 'like');//连接条件操作;
+    public $operateTable = array('leftJoin', 'rightJoin', 'innerJoin');//链接表的操作
+    public $faultTolerant = true;
+
+    public $whereCondition = array();
+    public $joinCondition = array();
+
+    public $fields = "*";
+    public $sets = array();
     protected $groupBy;
     protected $limit;
     protected $orderBy;
-    public $load;
-    public $where = null;
-    public $join = null;
-    /**
-     * @var string $response Response对象
-     */
-    public $response;
 
-    //方法对应的别名
-    protected $_modelAlias = array('selectRows' => 'selectAll', 'select' => 'selectRow', 'getOne' => 'selectOne', 'getRow' => 'selectRow', 'getAll' => 'selectAll', 'remove' => 'deleteRows');
+    protected $_modelAlias = array('updateRows' => 'update', 'selectRows' => 'selectAll', 'select' => 'selectRow', 'getOne' => 'selectOne', 'getRow' => 'selectRow', 'getAll' => 'selectAll', 'remove' => 'deleteRows');
+
 
     public function __construct()
     {
@@ -45,1056 +82,1057 @@ class Base
         $this->load = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Autoloader\Loader');
         $this->response = new \Qii\Driver\Response();
     }
-
     /**
-     * 获取数据库中所有的数据表
-     * @return array
+     * 获取所有数据
+     *
+     * @param $table
+     * @param null $where
+     * @return mixed
+     * @throws \Exception
      */
-    public function getAllDatabases()
+    public function selectAll($table, $where = null)
     {
-        $sql = "SHOW DATABASES";
-        $rs = $this->setQuery($sql);
-
-        $database = array();
-        while ($row = $rs->fetch()) {
-            $database[] = $row['Database'];
+        if(is_array($where) && count($where) > 0)
+        {
+            $this->where($where);
         }
-        return $database;
+        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        return $this->getAll($sql);
     }
-
     /**
-     * 数据库中是否包含指定库
-     * @param string $database 数据库名
-     * @return bool
+     * 返回resource资源
+     * @param string $table 数据表名称
      */
-    public function hasDatabase($database)
+    final function rs($table)
     {
-        if (!$database) return false;
-        $sql = "SHOW DATABASES LIKE '" . $database . "'";
-        $rs = $this->setQuery($sql);
-        while ($row = $rs->fetch()) {
-            $val = array_values($row);
-            if (in_array($database, $val)) {
-                return true;
-            }
-        }
-        return false;
+        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        return $this->setQuery($sql);
     }
-
     /**
-     * 获取当前数据库中所有的表
-     * @param null|string $database 数据库
-     * @return array
+     * 查询一行
+     * @param $table
+     * @param null $where
+     * @return mixed
+     * @throws \Exception
      */
-    public function getAllTables($database = null)
+    public function selectRow($table, $where = null)
     {
-        if ($database) {
-            $this->setQuery('USE ' . $database);
-        }
-        $sql = "SHOW TABLES";
-        $rs = $this->setQuery($sql);
-        $tables = array();
-        while ($row = $rs->fetch()) {
-            if (is_array($row)) {
-                foreach ($row AS $val) {
-                    $tables[] = $val;
-                }
-            }
+        if(is_array($where) && count($where) > 0)
+        {
+            $this->where($where);
         }
-        return $tables;
+        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        return $this->getRow($sql);
     }
-
     /**
-     * 获取指定数据表的所有字段
-     * @param string $table 表名
-     * @param string $database 数据库名
-     * @param string $autoIncr 自动增长的序号
-     * @return array
+     *
+     * 查询一列
+     * @param String $table
      */
-    public function getTableInfo($table, $database = null, $autoIncr = null)
+    final function selectOne($table)
     {
-        if (!$database) $database = $this->currentDB;
-        $sql = "SELECT * from information_schema.COLUMNS where table_name = '" . $table . "' and table_schema = '" . $database . "'";
-        $data = ['fields' => [],
-            'rules' => [
-                'pri' => [], 'required' => []
-            ]
-        ];
-
-        $rs = $this->setQuery($sql);
-        while ($row = $rs->fetch()) {
-            $data['fields'][] = $row['COLUMN_NAME'];
-            if ($row['EXTRA']) {
-                $data['rules']['extra'][$row['EXTRA']][] = $row['COLUMN_NAME'];
-            }
-            if ($row['COLUMN_KEY'] == 'PRI') {
-                $data['rules']['pri'][] = $row['COLUMN_NAME'];
-                $data['rules']['required'][] = $row['COLUMN_NAME'];
-            }
-            if ($row['IS_NULLABLE'] == 'NO') {
-                $data['rules']['required'][] = $row['COLUMN_NAME'];
-            }
-            if (in_array($row['DATA_TYPE'], ['varchar', 'char'])) {
-                $data['rules']['maxlength'][$row['COLUMN_NAME']] = $row['CHARACTER_MAXIMUM_LENGTH'];
-            }
-            if (in_array($row['DATA_TYPE'], ['mediumtext', 'TINYTEXT', 'text', 'longtext'])) {
-                $data['rules']['text'][] = $row['COLUMN_NAME'];
-            }
-            if (in_array($row['DATA_TYPE'], ['bigint', 'int', 'smallint', 'tinyint', 'integer'])) {
-                preg_match('/[\d]{1,}/', $row['COLUMN_TYPE'], $matches);
-                $data['rules']['int'][$row['COLUMN_NAME']] = $matches[0];
-                $data['rules']['number'][] = $row['COLUMN_NAME'];
-            }
-            if (in_array($row['DATA_TYPE'], ['float', 'double', 'decimal'])) {
-                $data['rules']['float'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
-            }
-            if (in_array($row['DATA_TYPE'], ['timestamp', 'datatime'])) {
-                $data['rules']['timestamp'][] = $row['COLUMN_NAME'];
-            }
-            if (in_array($row['DATA_TYPE'], ['enum', 'set'])) {
-                $data['rules']['sets'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
-            }
-            if (isset($row['COLUMN_DEFAULT'])) {
-                $data['rules']['default'][$row['COLUMN_NAME']] = $row['COLUMN_DEFAULT'];
-            }
-        }
-        $data['sql'] = $this->getTableSQL($table, $database, $autoIncr);
-        return $data;
+        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        return $this->getOne($sql);
     }
 
     /**
-     * 从括号中获取指定的值
-     * @param string $str 需要获取的内容
-     * @return array
+     * 插入数据
+     * @param $table
+     * @param $dataArray
+     * @return int
+     * @throws \Qii\Exceptions\InvalidFormat
      */
-    public function getValueFromBrackets($str)
+    final function insertObject($table, $dataArray)
     {
-        preg_match("/(?:\()(.*)(?:\))/i", $str, $matches);
-        $str = $matches[1];
-        $a = explode(",", $str);
-        for ($i = 0; $i < count($a); $i++) {
-            $this->removeQuote($a[$i]);//从字符串中去除单引号
+        if (empty($table)) {
+            throw new \Qii\Exceptions\InvalidParams(_i('%s is invalid', 'table'), __LINE__);
+        }
+        $replaceObj = $this->createInsertReplaceObj($dataArray);
+        if(empty($replaceObj['fields']) || empty($replaceObj['values']))
+        {
+            throw new \Qii\Exceptions\Variable(_i('Invalid %s format', 'data'), __LINE__);
         }
-        return $a;
+        $this->modelSQL = $sql = "INSERT INTO " . $this->getTable($table) . "(`" . join("`, `", $replaceObj['fields']) . "`) VALUES('" . join("', '", $replaceObj['values']) . "')";
+        $rs = $this->setQuery($sql);
+        $this->setError();
+        return $this->AffectedRows($rs);
     }
-
     /**
-     * 去除双引号
-     * @param string $str 去除双引号
+     *
+     * Replace Object
+     * @param String $table
+     * @param Array|Object $dataArray
      */
-    public function removeQuote(&$str)
+    final function replaceObject($table, $dataArray)
     {
-        if (preg_match("/^\'/", $str)) {
-            $str = substr($str, 1, strlen($str) - 1);
+        if (empty($table)) {
+            throw new \Qii\Exceptions\InvalidParams(_i('%s is invalid', 'table'), __LINE__);
         }
-        if (preg_match("/\'$/", $str)) {
-            $str = substr($str, 0, strlen($str) - 1);
+        $replaceObj = $this->createInsertReplaceObj($dataArray);
+        if(empty($replaceObj['fields']) || empty($replaceObj['values']))
+        {
+            throw new \Qii\Exceptions\Variable(_i('Invalid %s format', 'data'), __LINE__);
         }
-        return $str;
+        $this->modelSQL = $sql = "REPLACE INTO " . $this->getTable($table) . "(`" . join("`, `", $replaceObj['fields']) . "`) VALUES('" . join("', '", $replaceObj['values']) . "')";
+        $rs = $this->setQuery($sql);
+        $this->setError();
+        return $this->AffectedRows($rs);
     }
 
     /**
-     * 查询数据库中是否有指定的表
-     * @param string $tableName 表名
-     * @param null|string $database 数据库
-     * @return bool
+     * 创建插入或替换的内容
+     *
+     * @param $dataArray
+     * @return array
+     * @throws \Qii\Exceptions\InvalidFormat
      */
-    public function hasTable($tableName, $database = null)
+    protected function createInsertReplaceObj($dataArray)
     {
-        if ($database) {
-            $this->setQuery('USE ' . $database);
-        }
-        $sql = "SHOW TABLES LIKE '" . $tableName . "'";
-        $rs = $this->setQuery($sql);
-
-        $tables = array();
-        while ($row = $this->fetch($rs)) {
-            if (is_array($row)) {
-                foreach ($row AS $val) {
-                    if ($val == $tableName) return true;
+        if (sizeof($dataArray) > 0 || get_object_vars($dataArray) > 0) {
+            $keys = array();
+            $values = array();
+            foreach ($dataArray AS $key => $value) {
+                $keys[] = $key;
+                if (is_array($value)) {
+                    throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
                 }
+                $values[] = $this->setQuote($value);
             }
+            return array('fields' => $keys, 'values' => $values);
         }
-        return false;
+        return array('fields' => array(), 'values' => array());
     }
-
     /**
-     * 获取创建表的SQL语句
-     * @param string $tableName 表名
-     * @param null|string $database 数据库
-     * @param int|null $autoIncr 自增长的值,null的话就不使用
+     * 更新表中指定数据 结合set、where等方法是用
+     *
+     * @param string $table
      * @return string
+     * @throws \Exception
      */
-    public function getTableSQL($tableName, $database = null, $autoIncr = null)
-    {
-        if ($database) {
-            $this->setQuery('USE ' . $database);
-        }
-        $row = $this->getRow("SHOW CREATE TABLE `" . $tableName . "`");
-        if (!$row) {
-            throw new \Exception('数据表不存在', __LINE__);
-        }
-        $sql = $row['Create Table'];
-        if ($autoIncr === null) {
-            return $sql;
-        }
-        return preg_replace("/AUTO_INCREMENT=[\d]{1,}/", "AUTO_INCREMENT=" . intval($autoIncr), $sql);
-    }
-
-    /**
-     * 通过数据表名称获取规则
-     * @param string $table 表名
-     * @param string $database 数据库名
-     */
-    public function buildRulesForTable($table, $database = null)
+    public function update($table)
     {
-        if (!$database) $database = $this->currentDB;
-        $tableInfo = $this->getTableInfo($table, $database);
-        $rules = new \Qii\Base\Rules();
-        $rules->addFields($tableInfo['fields']);
-        if ($tableInfo['rules']['required']) {
-            $rules->addForceValidKey($tableInfo['rules']['required']);
-        }
-        if (isset($tableInfo['rules']['number'])) {
-            foreach ($tableInfo['rules']['number'] as $key => $value) {
-                $rules->addRules($value, 'number', true, $value . '字段必须是数字');
-            }
+        if(!$table) {
+            throw new \Qii\Exceptions\InvalidParams(_i('%s is invalid', '表名'), __LINE__);
         }
-        if (isset($tableInfo['rules']['maxlength'])) {
-            foreach ($tableInfo['rules']['maxlength'] as $key => $value) {
-                $rules->addRules($key, 'maxlength', $value, $key . '字段内容长度不能大于' . $value . '个字符');
-            }
-        }
-        if (isset($tableInfo['rules']['timestamp'])) {
-            foreach ($tableInfo['rules']['timestamp'] as $key => $value) {
-                $rules->addRules($value, 'datetime', true, $value . '字段必须为日期格式');
-            }
+        $set = join(",", $this->sets);
+        $this->sets = array();
+        if(count($this->whereCondition) > 0 && $this->isOperator($this->whereCondition[0]))
+        {
+            array_shift($this->whereCondition);
         }
-        return $rules;
-    }
+        $where = count($this->whereCondition) > 0 ? " WHERE ". join(" ", $this->whereCondition) : "";
+        $this->whereCondition = array();
 
-    final public function getAlias($alias)
-    {
-        return isset($this->_modelAlias[$alias]) ? $this->_modelAlias[$alias] : null;
+        $alias = $this->getTableAlias($table);
+        $this->modelSQL = $sql = sprintf($this->_query['UPDATE'], "`". $alias['name'] ."` ". $alias['alias']) . $set. $where;
+        return $this->exec($sql);
     }
-
     /**
-     * 设置Cache
+     * 更新表的数据,同时可以使用update方法达到同样的效果
      *
-     * @param String $cache
-     * @param Array $policy
+     * @param $table
+     * @param $dataArray
+     * @param array $keys
+     * @return string
+     * @throws \Exception
      */
-    final public function setCache($cache, $policy)
-    {
-        \Qii\Autoloader\Import::requires(Qii_DIR . DS . 'Qii' . DS . 'Cache.php');
-        $this->cache = \Qii\Autoloader\Psr4::loadClass('\Qii\Cache', $cache)->initialization($policy);//载入cache类文件
+    final function updateObject($table, $dataArray, $keys = array()){
+        if(!$table) {
+            throw new \Qii\Exceptions\InvalidParams(_i('%s is invalid', '表名'), __LINE__);
+        }
+        return $this->set($dataArray)->where($keys)->update($table);
     }
 
     /**
-     * 缓存内容
+     * 删除表中的数据,结合where方法使用
      *
-     * @param String $id
-     * @param Array $value
-     * @return Bool
+     * @param string $table 表名
+     * @return string
+     * @throws \Exception
      */
-    final public function cache($id, $value)
+    final function delete($table)
     {
-        return $this->cache->set($id, $value);
-    }
+        if(!$table) {
+            throw new \Exception('未指定更新的表名', __LINE__);
+        }
+        $where = count($this->whereCondition) > 0 ? " WHERE ". join(" ", $this->whereCondition) : "";
+        $this->whereCondition = array();
 
-    /**
-     * 获取缓存的类
-     */
-    final public function getCache()
-    {
-        return $this->cache;
+        $this->modelSQL = $sql = sprintf($this->_query['DELETE'], $table, $where);
+
+        return $sql;
     }
 
     /**
-     * 获取缓存内容
+     * 删除表中数据
      *
-     * @param String $id
-     * @return Array
+     * @param string $table 表名
+     * @param null $where
+     * @return string
+     * @throws \Exception
      */
-    final public function getCacheData($id)
+    final function deleteObject($table, $where = null)
     {
-        return $this->cache->get($id);
+        if(!$table) {
+            throw new \Qii\Exceptions\InvalidParams(_i('%s is invalid', '表名'), __LINE__);
+        }
+        return $this->where($where)->delete($table);
     }
-
     /**
-     * 获取表的名称
-     * @param String $table
-     * @return String
+     * like语句
+     * @param mix $arr
+     * @return $this
      */
-    public function getTable($table)
+    final function like($arr)
     {
-        list($database, $tableName) = array_pad(explode('.', $table), 2, '');
-
-        if ($tableName) {
-            $tableName = stristr($tableName, '`') || stristr($tableName, " ") ? $tableName : '`'. $tableName .'`';
-            return "`{$database}`.`{$tableName}`";
+        if(!is_array($arr)) {
+            if(!empty($arr)) {
+                $this->where($arr);
+            }
+            return $this;
         }
-        $table = stristr($table, '`') || stristr($tableName, " ")  ? $table : '`'. $table .'`';
-        return $table;
-    }
-
-    public function setLanguage()
-    {
-        $this->language = \Qii\Autoloader\Psr4::loadClass('Qii\Language\Loader');
+        foreach($arr as $key => $val) {
+            $arr[$key .":like"] = $val;
+            unset($arr[$key]);
+        }
+        $this->where($arr);
+        return $this;
     }
 
     /**
      *
-     * Insert Object
-     * @param String $table
-     * @param Array|Object $dataArray
+     * Limit函数,如果省略第二个参数则第一个为0,第二个参数值取第一个
+     * @param int $limit
+     * @param int $offset
      */
-    final function insertObject($table, $dataArray)
+    final function limit($limit, $offset = 0)
     {
-        if (empty($table)) {
-            return -1;
+        $this->limit = null;
+        if($limit === '' || $limit === null) {
+            throw new \Qii\Exceptions\InvalidParams(_i('%s is invalid', 'Limit'), __LINE__);
         }
-        if (sizeof($dataArray) > 0 || (is_object($dataArray) && get_object_vars($dataArray)) > 0) {
-            $keys = array();
-            $values = array();
-            foreach ($dataArray AS $key => $value) {
-                $keys[] = $key;
-                if (is_array($value)) {
-                    throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
-                }
-                $values[] = $this->setQuote($value);
+        if ($limit !== '') {
+            if (!$offset) {
+                $this->limit = sprintf($this->_query["LIMIT"], 0, $limit);
+            } else {
+                $this->limit = sprintf($this->_query["LIMIT"], $limit, $offset);
             }
-
-            $this->modelSQL = $sql = "INSERT INTO " . $this->getTable($table) . "(`" . join("`, `", $keys) . "`) VALUES('" . join("', '", $values) . "')";
-            $this->setQuery($sql);
-            $this->cleanData();
-            $this->setError();
-            return $this->lastInsertId();
         }
-        return -2;
+        return $this;
     }
 
     /**
-     * 左连表
+     * sql中的set条件
      *
-     * @param string $table 表名
-     * @param string $on on条件
+     * @param array $set
+     * @param null $res
+     * @param string $defaultOperator
      * @return $this
      */
-    final function leftJoinObject($table, $on)
+    final public function set($set, &$res = null, $defaultOperator = 'equal')
     {
-        if(empty($table) || empty($on)) return $this;
+        if(!is_array($set))
+        {
+            if(!empty($set))
+            {
+                $this->sets[] = $set;
+            }
+            return $this;
+        }
+        if(count($set) == 0) {
+            return $this;
+        }
+        $operator = array("equal" => "%s`%s` = '%s'", "plus" => "%s`%s` = %s`%s`+%s", "minus" => "%s`%s` = %s`%s`-%s", "multiply" => "%s`%s` = %s`%s`*%s", "divide" => "%s`%s` = %s`%s`/%s");
+        foreach($set as $key => $val)
+        {
+            $alias = $this->getFieldAlias($key);
+            $operate = $this->getFieldOperator($alias['name']);
+            if($operate['operator'] == '') {
+                $operate['operator'] = $defaultOperator;
+            }
+            if($operate['operator'] == 'equal') {
+                $this->sets[] = sprintf($operator[$operate['operator']], $alias['alias'], $operate['field'], $val);
+            }else{
+                $this->sets[] = sprintf($operator[$operate['operator']], $alias['alias'], $operate['field'], $alias['alias'], $operate['field'], $val);
+            }
 
-        $this->join .= sprintf($this->_query['LEFT_JOIN'], $table, $on);
+        }
         return $this;
     }
 
     /**
-     * 右连表
-     *
-     * @param string $table 表名
-     * @param string $on on条件
+     * set 字段加
+     * @param $set
      * @return $this
      */
-    final function rightJoinObject($table, $on)
+    public function upsetCounter($set)
     {
-        if(empty($table) || empty($on)) return $this;
-
-        $this->join .= sprintf($this->_query['RIGHT_JOIN'], $table, $on);
-        return $this;
+        if(!is_array($set))
+        {
+            if(!empty($set))
+            {
+                $this->sets[] = $set;
+            }
+            return $this;
+        }
+        if(count($set) == 0) {
+            return $this;
+        }
+        foreach ($set as $key => $val) {
+            if(substr($key, -5) == ':plus') {
+                continue;
+            }
+            $set[$key . ":plus"] = $val;
+            unset($set[$key]);
+        }
+        return $this->set($set);
     }
 
     /**
-     *
-     * Replace Object
-     * @param String $table
-     * @param Array|Object $dataArray
+     * set 字段减
+     * @param $set
+     * @return $this
      */
-    final function replaceObject($table, $dataArray)
+    public function downsetCounter($set)
     {
-        if (empty($table)) {
-            return -1;
+        if(!is_array($set)) {
+            if(!empty($set)) {
+                $this->sets[] = $set;
+            }
+            return $this;
         }
-        if (sizeof($dataArray) > 0 || get_object_vars($dataArray) > 0) {
-            $keys = array();
-            $values = array();
-            foreach ($dataArray AS $key => $value) {
-                $keys[] = $key;
-                if (is_array($value)) {
-                    throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
-                }
-                $values[] = $this->setQuote($value);
+        if(count($set) == 0) {
+            return $this;
+        }
+        foreach ($set as $key => $val) {
+            if(substr($key, -6) == ':minus') {
+                continue;
             }
-            $this->modelSQL = $sql = "REPLACE INTO " . $this->getTable($table) . "(`" . join("`, `", $keys) . "`) VALUES('" . join("', '", $values) . "')";
-            $rs = $this->setQuery($sql);
-            $this->cleanData();
-            $this->setError();
-            return $this->AffectedRows($rs);
+            $set[$key . ":minus"] = $val;
+            unset($set[$key]);
         }
-        return -2;
+        return $this->set($set);
     }
-
     /**
-     *
-     * Update data
-     * @param String $table
-     * @param Array|Objct $dataArray
-     * @param Array $keys
+     * where条件
+     * @param $where where语句
+     * @param null $res
+     * @return $this
      */
-    final function updateObject($table, $dataArray, $keys = array())
+    public function where($where, &$res = null)
     {
-        if (empty($table) || !is_array($keys)) {
-            return -1;
-        }
-        if (sizeof($dataArray) > 0 || get_object_vars($dataArray) > 0) {
-            $values = array();
-            $where = array();
-            foreach ($dataArray AS $key => $value) {
-                if (is_array($value)) {
-                    throw new \Qii\Exceptions\InvalidFormat(_i('Invalid %s format', $key), __LINE__);
-                }
-                $value = $this->setQuote($value);
-                if (in_array($key, $keys)) {
-                    $where[] = "`{$key}` = '" . $value . "'";
-                } else {
-                    $values[] = "`{$key}` = '" . $value . "'";
+        if(!is_array($where)) {
+            if(!empty($where))
+            {
+                if(!empty($this->whereCondition) && !$this->isOperator($where)) {
+                    $this->whereCondition[] = "and";
                 }
-            }
-            //$keys为key => value的方式,就直接用keys
-            if (empty($where) && count($keys) > 0) {
-                foreach ($keys as $key => $value) {
-                    $value = $this->setQuote($value);
-                    $where[] = "`{$key}` = '" . $value . "'";
+                if($this->isOperator($where)) {
+                    $this->whereCondition[] = $where;
+                }else{
+                    $this->whereCondition[] = "(". $where . ")";
                 }
             }
-            $whereSQL = $this->where;
-            if (sizeof($where) > 0) {
-                $whereSQL = $this->where ? $this->where . " AND (" . join(" AND ", $where) . ")" : " WHERE " . join(" AND ", $where);
-            }
-            $this->modelSQL = $sql = "UPDATE " . $this->getTable($table) . " SET " . join(", ", $values) . $whereSQL;
-            $rs = $this->setQuery($sql);
-            $this->cleanData();
-            $this->setError();
-            return $this->AffectedRows($rs);
+            return $this;
         }
-        return 0;
+        if(count($where) == 0) {
+            return $this;
+        }
+        $slices = $this->groupContents($where);
+        $this->handleCondition($slices, $res);
+        return $this;
     }
 
     /**
-     *
-     * 删除数据
-     * @param String $table
-     * @param Array $keys
+     * OR 条件
+     * @param $where
+     * @param string $defaultOperater
+     * @param null $res
+     * @return $this
+     * @throws \Exception
      */
-    final function deleteObject($table, $keys = array())
+    public function orTerms($where, $defaultOperater = 'or', &$res = null)
     {
-        if (empty($table)) {
-            return -1;
-        }
-        $where = array();
-        if (sizeof($keys) > 0 || (is_a($keys, 'stdclass') && get_object_vars($keys))) {
-            foreach ($keys AS $k => $v) {
-                $where[] = "`{$k}` = '" . $this->setQuote($v) . "'";
+        if(!is_array($where))
+        {
+            if($where != '') {
+                if(!empty($this->whereCondition) && !$this->isOperator($where)) {
+                    $this->whereCondition[] = $defaultOperater;
+                }
+                $this->whereCondition[] = "(". $where . ")";
             }
+            return $this;
         }
-        $whereSQL = $this->where;
-        if (sizeof($where) > 0) {
-            $whereSQL = $this->where ? $this->where . " AND (" . join(" AND ", $where) . ")" : " WHERE " . join(" AND ", $where);
+        if(count($where) == 0) {
+            return $this;
         }
-        $this->modelSQL = $sql = "DELETE FROM " . $this->getTable($table) . " " . $whereSQL;
-        $rs = $this->query($sql);
-        $this->cleanData();
-        $this->setError();
-        return $this->AffectedRows($rs);
+        $this->handleCondition(array(array($defaultOperater, $where)), $res);
+        return $this;
     }
 
-    /**
-     * 需要清除的数据
-     *
-     * @return array
-     */
-    final function cleanOptions()
+    public function in($where, $defaultOperater = 'or', &$res = null)
     {
-        return array('fields', 'where', 'groupBy', 'orderBy', 'limit', 'setArray', 'join');
+        if(!is_array($where))
+        {
+            if($where != '') {
+                if(!empty($this->whereCondition) && !$this->isOperator($where)) {
+                    $this->whereCondition[] = $defaultOperater;
+                }
+                $this->whereCondition[] = "(". $where . ")";
+            }
+            return $this;
+        }
+        if(count($where) == 0) {
+            return $this;
+        }
+
+        foreach ($where as $key => $val) {
+            if(substr($key, - 3) == ':in') {
+                continue;
+            }
+            $where[$key . ":in"] = $val;
+            unset($where[$key]);
+        }
+        $this->handleCondition(array(array('and', $where)), $res);
+        return $this;
     }
 
     /**
-     * 清除数据
+     * 不包含
      *
+     * @param mix $where 条件
+     * @return $this
      */
-    final function cleanData()
+    public function exclude($where)
     {
-        $array = $this->cleanOptions();
-        foreach ($array AS $k) {
-            if (is_array($this->$k)) {
-                $this->$k = array();
-            } else {
-                $this->$k = null;
+        if(!is_array($where))
+        {
+            return $this->where($where);
+        }
+        if(count($where) == 0) {
+            return $this;
+        }
+        foreach($where as $key => $value) {
+            if($this->getFieldOperator($key)['operator'] == '') {
+                $where[$key . ":unequal"] = $value;
+                unset($where[$key]);
             }
         }
+        return $this->where($where);
     }
 
     /**
+     * join语句
      *
-     * 查询的字段
-     * @param String $fields
+     * @param mix $val
+     * @param reference $res 用于返回值
+     * @return $this
+     * @throws \Exception
      */
-    final function fields($fields = "*")
-    {
-        $this->fields = null;
-        if (empty($fields)) $fields = "*";
-        if (is_array($fields)) {
-            foreach($fields as $key => $val)
-            {
-                $alias = explode('.', $val);
-                if(count($alias) > 1)
-                {
-                    $fields[$key] = $alias[0] . ".`".join(".", array_slice($alias, 1))."`";
-                }
+    public function join($val, &$res = null) {
+        if(!is_array($val)) {
+            if(!empty($val)) {
+                $this->joinCondition[] = $val;
             }
-            $fields = join(',', $fields);
+            return $this;
         }
-        $this->fields = $fields;
+        if(count($val) == 0) {
+            return $this;
+        }
+        $slices = $this->groupContents($val);
+        $this->handleTableJoin($slices, 'leftJoin', $res);
         return $this;
     }
 
     /**
-     *
-     * GROUP BY方法
-     * @param String $fields
+     * left join
+     * @param $table
+     * @param $on
+     * @return $this
+     * @throws \Exception
      */
-    final function groupBy($fields)
+    final function leftJoinObject($table, $on)
     {
-        $this->groupBy = null;
-        if (!empty($fields)) {
-            $fields = is_array($fields) ? join(', ', $fields) : $fields;
-            $this->groupBy = sprintf($this->_query['GROUP'], $fields);
-        }
-        return $this;
+        $alias = $this->getTableAlias($table);
+        return $this->join(" LEFT JOIN ". $this->getTable($alias['name']) . " " . $alias['alias'] ."  ON ". $on);
     }
 
     /**
-     *
-     * 插入数据用
-     * @param Array $array
+     * GROUP BY
+     * @param mix $group
+     * @return $this
      */
-    final function dataArray($array)
+    public function groupBy($group)
     {
-        $this->fileds = null;
-        if (is_array($array)) {
-            $tmpArray = array();
-            foreach ($array AS $k => $v) {
-                $tmpArray['k'][] = $this->setQuote($k);
-                $tmpArray['v'][] = $this->setQuote($v);
+        if(!is_array($group))
+        {
+            if(!empty($group))
+            {
+                $this->groupBy = stristr($group, 'GROUP BY') === false?  "GROUP BY ". $group: $group;
             }
-            $this->fileds = $tmpArray;
+            return $this;
+        }
+        if(count($group) == 0) {
+            return $this;
+        }
+        foreach($group as $index => $val)
+        {
+            $alias = $this->getFieldAlias($val);
+            $group[$index] = $alias['alias'] . "`". $alias['name'] ."`";
         }
+        $this->groupBy = " GROUP BY ". join(",", $group);
         return $this;
     }
 
     /**
+     * Order by
      *
-     * Order By函数
-     * @param String $field
-     * @param String $orderBy
+     * @param mix $order
+     * @return $this
+     * @throws \Exception
      */
-    final function orderBy($field, $orderBy)
+    public function orderBy($order)
     {
-        if (!empty($field)) return $this;
-
-        if ($this->orderBy != '') {
-            $this->orderBy .= $field . ' ' . $orderBy;
-        } else {
-            $this->orderBy = sprintf($this->_query['ORDER'], $field, $orderBy);
+        if(!is_array($order))
+        {
+            if(!empty($order)) {
+                $this->orderBy = stristr($order, 'ORDER BY') === false ? "ORDER BY ". $order: $order;
+            }
+            return $this;
         }
-    }
+        if(count($order) == 0) {
+            return $this;
+        }
+        $allowSortOff = array('asc', 'desc');
+        $orderBy = array();
+        $i = 0;
+        $countOrder = count($order);
+        foreach($order as $key => $sort)
+        {
+            if(!in_array(strtolower($sort), $allowSortOff) && $countOrder == $i)
+            {
+                throw new \Qii\Exceptions\InvalidParams(_i('%s is invalid', 'sort'), __LINE__);
+            }
+            $alias = $this->getFieldAlias($key);
 
-    /**
-     * 多个order by条件
-     */
-    final function orderByArr($map)
-    {
-        if (empty($map)) return $this;
-        foreach ($map AS $val) {
-            $this->orderBy($val['field'], $val['orderBy']);
+            $orderBy[] = $alias['alias'] . "`". $alias['name'] ."` ". $sort;
+            $i++;
         }
+        $this->orderBy = " ORDER BY ". join(",", $orderBy);
         return $this;
     }
 
     /**
-     * order by
-     * @param string order by
+     * Order by sql
+     *
+     * @param string $orderBy
+     * @return $this
+     * @throws \Exception
      */
-    final function orderByStr($orderBy)
+    public function orderByStr($orderBy)
     {
-        if (!$orderBy) return $this;
-        $this->orderBy = $orderBy;
-        return $this;
+        return $this->orderBy($orderBy);
     }
-
     /**
+     * 过滤值
      *
-     * Limit函数,如果省略第二个参数则第一个为0,第二个参数值取第一个
-     * @param Int $limit
-     * @param Int $offset
+     * @param mix $word
+     * @return array|string
      */
-    final function limit($limit, $offset = 0)
+    final function setQuote($word)
     {
-        $this->limit = null;
-        if ($limit !== '') {
-            if (!$offset) {
-                $this->limit = sprintf($this->_query["LIMIT"], 0, $limit);
-            } else {
-                $this->limit = sprintf($this->_query["LIMIT"], $limit, $offset);
-            }
+        if (ini_get("magic_quotes_gpc")) {
+            return $word;
         }
-        return $this;
+        return is_array($word) ? array_map('addslashes', $word) : addslashes($word);
     }
-
     /**
-     * 创建Like查询条件
-     * @param string | array $like like的条件
+     *
+     * 查询的字段
+     * @param String $fields
      */
-    final function like($like)
+    final function fields($fields = "*")
     {
-        if (empty($like)) return $this;
-        $likeArray = array();
-        if ($like && !is_array($like)) {
-            $likeArray[] = $like;
-        } else {
-            foreach ($like AS $key => $val) {
-                if(stristr($key, '.')) {
-                    $likeArray[] = sprintf("%s LIKE '%s'", $key, "%" . $this->setQuote($val) . "%");
-                }else{
-                    $likeArray[] = sprintf($this->_query['LIKE'], $key, "%" . $this->setQuote($val) . "%");
+        $this->fields = null;
+        if (empty($fields)) $fields = "*";
+        if (is_array($fields)) {
+            if(count($fields) == 0) {
+                $fields = '*';
+            }else{
+                foreach($fields as $key => $val)
+                {
+                    $alias = explode('.', $val);
+                    if(count($alias) > 1)
+                    {
+                        $fields[$key] = $alias[0] . ".`".join(".", array_slice($alias, 1))."`";
+                    }
                 }
+                $fields = join(',', $fields);
             }
         }
-        if (count($likeArray) > 0) {
-            $likeSQL = join(" OR ", $likeArray);
-            if (!$this->where) {
-                $this->where = sprintf($this->_query["WHERE"], $likeSQL);
-            } else {
-                $this->where .= ' AND (' . $likeSQL . ')';
-            }
-        }
+        $this->fields = $fields;
         return $this;
     }
     /**
-     * 不包含的条件
-     * @param array $where 条件
-     * @return $this
+     * 清空Data数据
      */
-    final function exclude($where)
+    final public function clearCondition()
     {
-        if (empty($where)) return $this;
-        $whereArray = array();
-        if ($where && !is_array($where)) {
-            $whereArray[] = $where;
-        } else {
-            foreach ($where AS $key => $val) {
-            	$whereArray[] = sprintf("%s != '%s'", $key, $this->setQuote($val));
-            }
-        }
-        if (count($whereArray) > 0) {
-            $whereSQL = join(" AND ", $whereArray);
-            if (!$this->where) {
-                $this->where = sprintf($this->_query["WHERE"], $whereSQL);
-            } else {
-                $this->where .= ' AND (' . $whereSQL . ')';
-            }
-        }
-        return $this;
+        $this->fields = '*';
+        $this->whereCondition = array();
+        $this->joinCondition = array();
+        $this->groupBy = "";
+        $this->orderBy = "";
+        $this->limit = null;
+        $this->sets = array();
     }
 
     /**
-     * 传的条件为数组
-     * @param  Array $where 条件
-     * @return Object       对象本身
+     * 获取错误码
      */
-    final function whereArray($where)
+    final public function getCode()
     {
-        $this->where = null;
-        if (!empty($where)) {
-            $whereArray = array();
-            foreach ($where AS $k => $v) {
-                $v = $this->setQuote($v);
-                if(stristr($k, '.')) {
-                    $whereArray[] = " {$k} = '{$v}'";
-                }else{
-                    $whereArray[] = " `{$k}` = '{$v}'";
-                }
-            }
-            if (sizeof($whereArray) > 0) {
-                $whereSQL = join(" AND ", $whereArray);
-                if (!$this->where) {
-                    $this->where = sprintf($this->_query["WHERE"], $whereSQL);
-                } else {
-                    $this->where .= " AND (" . $whereSQL . ")";
-                }
-            }
-        }
-        return $this;
+        return $this->response->getCode();
     }
 
     /**
-     *
-     * WHERE 子句
-     * @param String $where
+     * 获取错误信息
      */
-    final function where($where)
+    final public function getMessage()
     {
-        if (is_array($where)) return $this->whereArray($where);
-        $this->where = null;
-        if (!empty($where)) {
-            $this->where = sprintf($this->_query["WHERE"], $where);
+        if ($this->response->isError()) {
+            return $this->response->getMessage();
         }
-        return $this;
-    }
-    /**
-     * 操作where条件语句
-     *
-     * @param $and
-     * @param string $insideBrackets or条件里边的操作符
-     * @param string $outsideBrackets 链接or条件的操作符
-     * @return $this
-     */
-    final function and($and, $insideBrackets = "OR", $outsideBrackets = "AND") {
-        return $this->or($and, $insideBrackets, $outsideBrackets);
-    }
-    /**
-     * 操作where条件语句
-     *
-     * @param $or
-     * @param string $insideBrackets or条件里边的操作符
-     * @param string $outsideBrackets 链接or条件的操作符
-     * @return $this
-     */
-    final function andStr($or, $insideBrackets = "AND", $outsideBrackets = "OR") {
-        return $this->orStr($or, $insideBrackets, $outsideBrackets);
     }
+
     /**
-     * 操作where条件语句
+     * 返回response对象
      *
-     * @param $or
-     * @param string $insideBrackets or条件里边的操作符
-     * @param string $outsideBrackets 链接or条件的操作符
-     * @return $this
+     * @return Bool
      */
-    final function or($or, $insideBrackets = "AND", $outsideBrackets = "OR")
+    public function getResponse()
     {
-        if(empty($or)) return $this;
-        $orCond = array();
-        if(is_array($or)) {
-            foreach($or as $key => $val) {
-                $orCond[] = sprintf($this->_query['OR'], $key, $this->setQuote($val));
-            }
-        }
-        else
-        {
-            $orCond[] = $or;
-        }
-        if(!empty($this->where)) {
-            $this->where .= " ". $outsideBrackets. "  (". join(" ". $insideBrackets . " ", $orCond) .")";
-        }else{
-            $this->where = " WHERE (". join(" ". $insideBrackets . " ", $orCond) .")";
-        }
-        return $this;
-    }
-    /**
-     * 操作where条件语句
-     *
-     * @param $or
-     * @param string $insideBrackets or条件里边的操作符
-     * @param string $outsideBrackets 链接or条件的操作符
-     * @return $this
-     */
-    final function orStr($or, $insideBrackets = "AND", $outsideBrackets = "OR") {
-        if(empty($or)) return $this;
-        if(is_array($or)) {
-            $or = join(" ". $insideBrackets . " ", $or);
-        }
-        if(!empty($this->where)) {
-            $this->where .= " ". $outsideBrackets ." (". $or . ")";
-        }
-        return $this;
+        return $this->response;
     }
 
     /**
-     * 创建插入表的SQL
+     * 转换字符创
+     *
+     * @param $str
+     * @return array|string
      */
-    final function createInsertSQL($table)
+    final public function iconv($str)
     {
-        $sql = sprintf($this->_query['INSERT'], $table, join(",", $this->fileds['k']), join("', '", $this->fileds['v']));
-        $this->cleanData();
-        return $sql;
+        if (is_array($str)) {
+            return array_map(function ($n) {
+                return toUtf8($n);
+            }, $str);
+        }
+        return toUtf8($str);
     }
 
     /**
+     * 执行Model过程中保存的相关信息
      *
-     * 插入数据到指定表中
-     * @param String $table
+     * @param String $option
+     * @return Mix
      */
-    final function insertRow($table)
+    final function querySQL($option = '')
     {
-        $this->modelSQL = $sql = $this->createInsertSQL($table);
-        $this->setQuery($sql);
-        return $this->lastInsertId();
+        $allow = array('_queryTimes', '_querySeconds', '_errorInfo', '_exeSQL');
+        if (in_array($option, $allow)) {
+            return $this->{$option};
+        }
+        return 0;
     }
-
     /**
-     * 创建replace object SQL
+     * 通过where\set\limit等方法自动生成SQL语句
      *
-     * @param string $table 表名
+     * @param string $table 必填
      * @return string
+     * @throws \Exception
      */
-    final function createReplaceSQL($table)
+    public function createSelectSQL($table)
     {
-        $sql = sprintf($this->_query['REPLACE'], $table, join(",", $this->fileds['k']), join("', '", $this->fileds['v']));
-        $this->cleanData();
-        return $sql;
-    }
+        if(!$table) {
+            throw new \Qii\Exceptions\InvalidParams(_i('%s is invalid', '表名'), __LINE__);
 
-    /**
-     *
-     * Replace方法
-     * @param String $table
-     */
-    final function replaceRow($table)
-    {
-        $this->modelSQL = $sql = $this->createReplaceSQL($table);
-        return $this->exec($sql);
-    }
+        }
+        $aliases = $this->getTableAlias($table);
 
-    /**
-     *
-     * 查询一行
-     * @param String $table
-     */
-    final function selectRow($table)
-    {
-        $this->modelSQL = $sql = $this->createSelectSQL($table);
-        $this->cleanData();
-        return $this->getRow($sql);
-    }
+        $fields = (trim($this->fields) != '') ? $this->fields : "*";
+        //$this->fields = '*';
 
+        if(count($this->whereCondition) > 0 && $this->isOperator($this->whereCondition[0])) {
+            array_shift($this->whereCondition);
+        }
+        $where = count($this->whereCondition) > 0 ? " WHERE ". join(" ", $this->whereCondition) : "";
+        //$this->whereCondition = array();
 
-    /**
-     *
-     * 查询一行
-     * @param String $table
-     */
-    final function selectOne($table)
-    {
-        $this->modelSQL = $sql = $this->createSelectSQL($table);
-        return $this->getOne($sql);
-    }
+        $join = count($this->joinCondition) > 0 ? join("\n", $this->joinCondition) : "";
+        //$this->joinCondition = array();
 
-    /**
-     * 创建SELECT SQL
-     */
-    final function createSelectSQL($table)
-    {
+        $groupBy = " ". $this->groupBy;
+        //$this->groupBy = "";
+
+        $orderBy = " ". $this->orderBy;
+        //$this->orderBy = "";
+
+        $limit = $this->limit;
+        //$this->limit = null;
 
-        if(stristr($table, '.') == false
-            && stristr($table, '`') == false
-            && stristr($table, ' ') == false
-        ) {
-            $table = '`'. $table .'`';
-        }
-        $sql = sprintf($this->_query['SELECT'], ((trim($this->fields) != '') ? $this->fields : "*"), $table) . $this->join . $this->where . $this->groupBy . $this->orderBy . $this->limit;
-        $this->cleanData();
+        $sql = sprintf($this->_query['SELECT'], $fields, $aliases['name'], $aliases['alias']) . $join . $where . $groupBy . $orderBy . $limit;
+        $this->clearCondition();
         return $sql;
     }
-
     /**
+     * 获取操作符
      *
-     * 查询所有
-     * @param String $table 数据表名称
-     * @return Array
+     * @param string $field 字段
+     * @return array
      */
-    final function selectAll($table)
+    protected function getFieldOperator($field)
     {
-        $this->modelSQL = $sql = $this->createSelectSQL($table);
-        return $this->getAll($sql);
-    }
+        $operator = explode(":", $field);
+        if(count($operator) == 1) {
+            return array('operator' => '', 'field' => $field);
+        }
+        $operate = array_pop($operator);
+        $field = join(":", $operator);
 
-    /**
-     * 返回resource资源
-     * @param string $table 数据表名称
-     */
-    final function rs($table)
-    {
-        $this->modelSQL = $sql = sprintf($this->_query['SELECT'], ((trim($this->fields) != '') ? $this->fields : "*"), $table) . $this->join . $this->where . $this->groupBy . $this->orderBy . $this->limit;
-        $this->cleanData();
-        return $this->setQuery($sql);
+        return array('operator' => $operate, 'field' => $field);
     }
-
     /**
-     * 将指定字段减指定值
+     * 获取字段别名
      *
-     * @param array $data 数据
-     * @return $this
+     * @param string $name
+     * @param string $connector
+     * @return array
      */
-    final function downsetCounter($data)
+    protected function getFieldAlias($name, $connector = ".")
     {
-        if (is_array($data)) {
-            foreach ($data AS $k => $value) {
-                $this->setArray[] = $k . "=" . $k . '-' . $value;
-            }
+        $aliases = explode('.', $name);
+        if(count($aliases) == 1) {
+            return array('alias' => '', 'name' => $name);
         }
-        $this->set(null);
-        return $this;
+
+        return array('alias' => $aliases[0] . $connector, 'name' => join(".", array_slice($aliases, 1)));
     }
 
     /**
-     * 将指定字段加指定值
+     * 获取表的别名
      *
-     * @param $data
-     * @return $this
+     * @param string $name 名字
+     * @return array
      */
-    final function upsetCounter($data)
+    protected function getTableAlias($name)
     {
-        if (is_array($data)) {
-            foreach ($data AS $k => $value) {
-                $this->setArray[] = $k . "=" . $k . '+' . $value;
-            }
+        //去掉table前后的``符号
+        $name = str_replace('`', '', $name);
+        $aliases = explode(' ', $name);
+        if(count($aliases) == 1) {
+            return array('alias' => '', 'name' => $name);
         }
-        $this->set(null);
-        return $this;
+        $res = array();
+        $res['alias'] = array_pop($aliases);
+        $res['name'] = join(" ", array_slice($aliases, -1));
+        return $res;
     }
-
-    /**
-     * 更新数据时候用,方法同setData
-     * @param Array $data
-     */
-    final function set($data)
-    {
-        return $this->setData($data);
-    }
-
     /**
+     * 把条件根据『链接字符串,『字段:值』』等内容分组
      *
-     * 更新数据时候用
-     * @param Array $data
-     * @return $this
+     *
+     * $whereGroup = array(
+     *   ['id' => 1, 'name' => '名字'],
+     *   'or',
+     *   ['status' => 1, 'create_at:greater' => '22222'],//
+     *   'or',//链接字段与字段之间的操作符
+     *   'like',//使用在字段与值之间的操作符,可以省略
+     *   'and',//字段1与字段2之间的操作符
+     *   'or',//字段2与字段3之间的操作符
+     *   '...',//字段n与字段n+1之间的操作符
+     *   //字段n与字段n+1之间的操作符可以省略
+     *   //子数组之间的操作符优先于上边的操作符
+     *   ['email' => 'antsnet@163.com', "and", 'nickname' => 'antsnet'],
+     *   ['uid' => 1],
+     *   'and',
+     *   ['name' => 'ss'],
+     *   'and',
+     *   'and',
+     *   'update_at=1',
+     *   );
+     * @param $group
+     * @return array [['or/and', 'like/equal/...', ['字段1' => '值1', '字段2' => '值2']],[...]]
      */
-    final function setData($data)
+    protected function groupContents($group)
     {
-        if (is_array($data)) {
-            $set = array();
-            foreach ($data AS $k => $value) {
-                $set[] = $k . "='" . $this->setQuote($value) . "'";
-            }
-            if (sizeof($this->setArray) > 0) {
-                $this->set = " " . join(", ", $set) . ", " . join(",", $this->setArray);
-            } else {
-                $this->set = " " . join(", ", $set);
+        $slices = array();
+        //如果是一维数组就直接操作值,不检查操作符
+        if(count($group) == count($group, 1)) {
+            $slices[] = array($group);
+            return $slices;
+        }
+        $count = count($group);
+        $tmpWhere = array();
+        //最后一次是否是赋值
+        $lastIsValue = null;
+        $groupCount = count($group);
+        foreach($group as $index => $val)
+        {
+            $isOperator = $this->isOperator($val);//如果是操作符,上一个不是操作符就清空tmpWhere,并放入slices
+            $isValue = !$isOperator;
+            /*if($isOperator) {
+                $hasOperator = true;
+            }*/
+            if($lastIsValue && $isOperator)
+            {
+                $slices[] = $tmpWhere;
+                $tmpWhere = array();
+                $tmpWhere[] = $val;
             }
-        } else {
-            if (sizeof($this->setArray) > 0) {
-                $this->set = join(",", $this->setArray);
-            } else {
-                $this->set = "";
+            else if($count - 1 == $index)
+            {
+                $tmpWhere[] = $val;
+                $slices[] = $tmpWhere;
+            }else {
+                $tmpWhere[] = $val;
             }
+            $lastIsValue = $isValue;
         }
-        return $this;
+        return $slices;
     }
     /**
+     * 判断是否是操作符号
      *
-     * 执行更新操作
-     * @param $table
-     * @return Int 返回影响的行数
+     * @param $val 值
+     * @return bool
      */
-    final function updateRows($table)
+    protected function isOperator($val)
     {
-        $this->modelSQL = $sql = sprintf($this->_query['UPDATE'], $table) . $this->set . $this->where . $this->limit;
-        $this->cleanData();
-        return $this->exec($sql);
+        if(is_array($val)) {
+            return false;
+        }
+        if(!is_array($val)) {
+            $val = strtolower($val);
+        }
+        return in_array($val, $this->operateVal) || in_array($val, $this->operateTable);
     }
 
     /**
+     * 是否是操作表
      *
-     * 执行删除操作
-     * @param String $table
+     * @param mix $val 值
+     * @return bool
      */
-    final function deleteRows($table)
+    protected function isOperateTable($val)
     {
-        $this->modelSQL = $sql = sprintf($this->_query['DELETE'], $table, $this->where) . $this->limit;
-        $this->cleanData();
-        return $this->exec($sql);
+        if(is_array($val)) {
+            return false;
+        }
+        return in_array($val, $this->operateTable);
     }
 
     /**
-     * 执行Model过程中保存的相关信息
+     * where条件子句组合
      *
-     * @param String $option
-     * @return Mix
+     * @param array $values ['字段1' => '值1', '字段2' => '值2', ...]
+     * @param $defaultOperate 默认字句的链接方式
+     *  ..... 额外的参数,用于字段与字段之间的连接
+     * @return string
+     * @throws \Exception
      */
-    final function querySQL($option = '')
+    protected function handleSubCondition($values, $defaultOperate = 'equal')
     {
-        $allow = array('_queryTimes', '_querySeconds', '_errorInfo', '_exeSQL');
-        if (in_array($option, $allow)) {
-            return $this->{$option};
+        $extraParams = array();
+        if(func_num_args() > 2)
+        {
+            $extraParams = array_slice(func_get_args(), 2);
         }
-        return 0;
-    }
+        $where = array();
+        $operator = array('equal' => "%s`%s` = '%s'",'in' => "%s`%s` in (%s)", 'unequal' => "%s`%s` != '%s'", 'greater' => "%s`%s` > '%s'", 'greaterEqual' => "%s`%s` >= '%s'", 'less' => "%s`%s` < '%s'", 'lessEqual' => "%s`%s` <= '%s'", 'like' => "`%s%s` like '%%%s%%'");
+        $lastIsOperator = false;
+        $lastIsValue = null;
+        $i = 0;
+        foreach($values as $key => $val)
+        {
+            $isOperator = $this->isOperator($val);//如果是操作符,上一个不是操作符就清空tmpWhere,并放入slices
+            $isValue = !$isOperator;
+            if($lastIsValue && $isOperator)//如果当前是操作符,上一个是值,就将操作符加入到条件中
+            {
+                $where[] = $val;
+                $lastIsValue = $isValue;
+                $lastIsOperator = $isOperator;
+                continue;
+            }
+            //如果上一次是操作符,这次又是操作符,就是用当前的操作符,去掉上一个操作符
+            if($lastIsOperator && $isOperator)
+            {
+                if(!$this->faultTolerant) throw new \Qii\Exceptions\InvalidParams(_i('Unsupported operator'), __LINE__);
+                array_pop($where);
+                $where[] = $val;
+                continue;
+            }
+            if($lastIsValue && $isValue)//需要添加操作符
+            {
+                $where[] = count($extraParams) > 0 && isset($extraParams[$i-1]) ? $extraParams[$i-1] : "and";
+            }
 
-    /**
-     * 将结果编码一下
-     * @param String $word
-     * @return String|multitype:
-     */
-    public function setQuote($word)//过滤sql字符
-    {
-        if (ini_get("magic_quotes_gpc")) {
-            return $word;
+            //$aliases = explode(".", $key);
+            $aliases = $this->getFieldAlias($key);
+            $alias = $aliases['alias'];
+            $operate = $this->getFieldOperator($aliases['name']);
+            $opt = $operate['operator'] ? $operate['operator'] : $defaultOperate;
+            $name =  $operate['field'];
+            if($opt == 'in' && is_array($val))
+            {
+                $where[] = sprintf($operator[$opt], $alias, $name, "'". join("','", $val) . "'");
+            }else{
+                $where[] = sprintf($operator[$opt], $alias, $name, $this->setQuote($val));
+            }
+            $lastIsValue = $isValue;
+            $lastIsOperator = $isOperator;
+            $i++;
         }
-        return is_array($word) ? array_map('addslashes', $word) : addslashes($word);
-    }
 
-    /**
-     * 获取错误码
-     */
-    public function getCode()
-    {
-        return $this->response->getCode();
+        return join(" ", $where);
     }
 
     /**
-     * 获取错误信息
+     * 处理table join
+     * @param array $slices [['leftJoin', ['table' => '表名', 'alias' => 'a', 'on' => 'a.id = b.id']]]
+     * @param string $defaultJoin
+     * @param null $res
+     * @return $this
+     * @throws \Exception
      */
-    public function getMessage()
+    protected function handleTableJoin($slices, $defaultJoin = 'leftJoin', &$res = null)
     {
-        if ($this->response->isError()) {
-            return $this->response->getMessage();
+        foreach ($slices as $v)
+        {
+            if(count($v) == 0) {
+                throw new \Exception('连接表操作失败,格式:"leftJoin/rightJoin/innerJoin", ["table" => "表名", "alias" => "b", "on" => "a.id=b.id"]', __LINE__);
+            }
+            if(count($v) == 1 && !$this->isOperateTable($v[0]))
+            {
+                array_unshift($v, $defaultJoin);
+            }
+            $joinOperator = array(
+                "leftJoin" => " LEFT JOIN %s ON %s",
+                "rightJoin" => " RIGHT JOIN %s ON %s",
+                "innerJoin" => " INNER JOIN %s ON %s"
+            );
+            if(!$this->isOperateTable($v[0]))
+            {
+                throw new \Exception('连接表操作失败,格式:"leftJoin/rightJoin/innerJoin", ["table" => "表名", "alias" => "b", "on" => "a.id=b.id"]', __LINE__);
+            }
+
+            $joinCondition = sprintf($joinOperator[$v[0]], $v[1]['table'] . ' '. $v[1]['alias'], $v[1]['on']);
+            if(!empty($this->join) && is_array($this->join))
+            {
+                $this->joinCondition = array_merge($this->join, array($joinCondition));
+            }
+            else
+            {
+                $this->joinCondition[] = $joinCondition;
+            }
+            $res[] = $joinCondition;
         }
+        unset($joinCondition);
+        return $this;
     }
 
     /**
-     * 返回response对象
-     *
-     * @return Bool
+     * 处理 where 条件
+     * @param array $condition
+     * @param null $res
+     * @return $this
+     * @throws \Exception
      */
-    public function getResponse()
+    protected function handleCondition($condition, &$res = null)
     {
-        return $this->response;
-    }
+        if(!is_array($condition))
+        {
+            return $this;
+        }
+        $count = count($condition);
+        $whereCondition = array();
+        for($i = 0; $i < $count; $i++)
+        {
+            $v = $condition[$i];
+            //如果有两个及上的操作符
+            //默认第一个为连接其他条件的操作符,第二个位字段和值之间的操作符, 从第三个开始即为字段与字段之间的连接符
+            //最里层的字段与值之间的操作符优先级最高
 
-    /**
-     * 转换字符创
-     *
-     * @param $str
-     * @return array|string
-     */
-    public function iconv($str)
-    {
-        if (is_array($str)) {
-            return array_map(function ($n) {
-                return toUtf8($n);
-            }, $str);
+            //例如 1: 'or/and','like','or', 'and', ['uid' => 1, 'name' => '名字', 'status' => 激活];
+            //结果 1:or/and (uid like '%1%' or name like '%名字%' and status like '%激活%')
+
+            //例如 2: 'or/and','like','or', 'and', ['uid' => 1, 'name' => '名字', 'status:equal' => 激活];
+            //结果 2:or/and (uid like '%1%' or name like '%名字%' and status = '激活')
+
+            $operateCondition = array();
+            $values = array();
+            $countCondition = count($v);
+            $handleTable = false;
+            for($j = 0; $j < $countCondition; $j++)
+            {
+                $handleTable = false;
+                if($this->isOperateTable($v[$j]))
+                {
+                    /*
+                    $operateCondition[] = $v[$j];
+                    $joinTable[$v[$j]] = $this->handleTableJoin($v);
+                    */
+                    //如果是操作数据表就直接退出循环单独处理
+                    $handleTable = true;
+                    break;
+                }
+                if($this->isOperator($v[$j]))
+                {
+                    $operateCondition[] = $v[$j];
+                    continue;
+                }
+                if(!$this->isOperator($v[$j]))
+                {
+                    if(!is_array($v[$j])) {
+                        $whereCondition[] = $v[0];
+                        $whereCondition[] = "(". $v[1] . ")";
+                        break;
+                    }
+                    $values = is_array($v[$j]) ? array_merge($values, $v[$j]) : array_merge($values, array($v[$j]));
+                }
+            }
+            if($handleTable)
+            {
+                continue;
+            }
+            if(count($operateCondition) > 0 && count($values) > 0)
+            {
+                $whereCondition[] = array_shift($operateCondition);
+            }
+            if(count($values) > 0) {
+                if(count($operateCondition) > 0) {
+                    array_unshift($operateCondition, $values);
+                    $whereCondition[] = "(". call_user_func_array(array($this, 'handleSubCondition'), $operateCondition) .")";
+                }else{
+                    $whereCondition[] = "(". $this->handleSubCondition($values) .")";
+                }
+            }
         }
-        return toUtf8($str);
+        if(!empty($this->whereCondition))
+        {
+            $lastCondition = $this->whereCondition[count($this->whereCondition) - 1];
+            if(!$this->isOperator($whereCondition[0]) && !$this->isOperator($lastCondition)) {
+                $this->whereCondition = array_merge($this->whereCondition, array('and'));
+            }
+            $this->whereCondition = array_merge($this->whereCondition, $whereCondition);
+        }
+        else
+        {
+            $this->whereCondition = $whereCondition;
+        }
+        $res = $whereCondition;
+        unset($whereCondition);
+        return $this;
     }
 
     /**

+ 49 - 0
src/Driver/traitCache.php

@@ -0,0 +1,49 @@
+<?php
+namespace Qii\Driver;
+
+trait traitCache
+{
+    public $cache;
+    /**
+     * 设置Cache
+     *
+     * @param String $cache
+     * @param Array $policy
+     */
+    final public function setCache($cache, $policy)
+    {
+        \Qii\Autoloader\Import::requires(Qii_DIR . DS . 'Qii' . DS . 'Cache.php');
+        $this->cache = \Qii\Autoloader\Psr4::loadClass('\Qii\Cache', $cache)->initialization($policy);//载入cache类文件
+    }
+
+    /**
+     * 缓存内容
+     *
+     * @param String $id
+     * @param Array $value
+     * @return Bool
+     */
+    final public function cache($id, $value)
+    {
+        return $this->cache->set($id, $value);
+    }
+
+    /**
+     * 获取缓存的类
+     */
+    final public function getCache()
+    {
+        return $this->cache;
+    }
+
+    /**
+     * 获取缓存内容
+     *
+     * @param String $id
+     * @return Array
+     */
+    final public function getCacheData($id)
+    {
+        return $this->cache->get($id);
+    }
+}

+ 249 - 0
src/Driver/traitDatabase.php

@@ -0,0 +1,249 @@
+<?php
+namespace Qii\Driver;
+
+trait traitDatabase
+{
+
+    /**
+     * 获取数据库中所有的数据表
+     * @return array
+     */
+    public function getAllDatabases()
+    {
+        $sql = "SHOW DATABASES";
+        $rs = $this->setQuery($sql);
+
+        $database = array();
+        while ($row = $rs->fetch()) {
+            $database[] = $row['Database'];
+        }
+        return $database;
+    }
+
+    /**
+     * 数据库中是否包含指定库
+     * @param string $database 数据库名
+     * @return bool
+     */
+    public function hasDatabase($database)
+    {
+        if (!$database) return false;
+        $sql = "SHOW DATABASES LIKE '" . $database . "'";
+        $rs = $this->setQuery($sql);
+        while ($row = $rs->fetch()) {
+            $val = array_values($row);
+            if (in_array($database, $val)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 获取当前数据库中所有的表
+     * @param null|string $database 数据库
+     * @return array
+     */
+    public function getAllTables($database = null)
+    {
+        if ($database) {
+            $this->setQuery('USE ' . $database);
+        }
+        $sql = "SHOW TABLES";
+        $rs = $this->setQuery($sql);
+        $tables = array();
+        while ($row = $rs->fetch()) {
+            if (is_array($row)) {
+                foreach ($row AS $val) {
+                    $tables[] = $val;
+                }
+            }
+        }
+        return $tables;
+    }
+
+    /**
+     * 获取指定数据表的所有字段
+     * @param string $table 表名
+     * @param string $database 数据库名
+     * @param string $autoIncr 自动增长的序号
+     * @return array
+     */
+    public function getTableInfo($table, $database = null, $autoIncr = null)
+    {
+        if (!$database) $database = $this->currentDB;
+        $sql = "SELECT * from information_schema.COLUMNS where table_name = '" . $table . "' and table_schema = '" . $database . "'";
+        $data = ['fields' => [],
+            'rules' => [
+                'pri' => [], 'required' => []
+            ]
+        ];
+
+        $rs = $this->setQuery($sql);
+        while ($row = $rs->fetch()) {
+            $data['fields'][] = $row['COLUMN_NAME'];
+            if ($row['EXTRA']) {
+                $data['rules']['extra'][$row['EXTRA']][] = $row['COLUMN_NAME'];
+            }
+            if ($row['COLUMN_KEY'] == 'PRI') {
+                $data['rules']['pri'][] = $row['COLUMN_NAME'];
+                $data['rules']['required'][] = $row['COLUMN_NAME'];
+            }
+            if ($row['IS_NULLABLE'] == 'NO') {
+                $data['rules']['required'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], ['varchar', 'char'])) {
+                $data['rules']['maxlength'][$row['COLUMN_NAME']] = $row['CHARACTER_MAXIMUM_LENGTH'];
+            }
+            if (in_array($row['DATA_TYPE'], ['mediumtext', 'TINYTEXT', 'text', 'longtext'])) {
+                $data['rules']['text'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], ['bigint', 'int', 'smallint', 'tinyint', 'integer'])) {
+                preg_match('/[\d]{1,}/', $row['COLUMN_TYPE'], $matches);
+                $data['rules']['int'][$row['COLUMN_NAME']] = $matches[0];
+                $data['rules']['number'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], ['float', 'double', 'decimal'])) {
+                $data['rules']['float'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
+            }
+            if (in_array($row['DATA_TYPE'], ['timestamp', 'datatime'])) {
+                $data['rules']['timestamp'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], ['enum', 'set'])) {
+                $data['rules']['sets'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
+            }
+            if (isset($row['COLUMN_DEFAULT'])) {
+                $data['rules']['default'][$row['COLUMN_NAME']] = $row['COLUMN_DEFAULT'];
+            }
+        }
+        $data['sql'] = $this->getTableSQL($table, $database, $autoIncr);
+        return $data;
+    }
+
+    /**
+     * 从括号中获取指定的值
+     * @param string $str 需要获取的内容
+     * @return array
+     */
+    public function getValueFromBrackets($str)
+    {
+        preg_match("/(?:\()(.*)(?:\))/i", $str, $matches);
+        $str = $matches[1];
+        $a = explode(",", $str);
+        for ($i = 0; $i < count($a); $i++) {
+            $this->removeQuote($a[$i]);//从字符串中去除单引号
+        }
+        return $a;
+    }
+
+    /**
+     * 去除双引号
+     * @param string $str 去除双引号
+     */
+    public function removeQuote(&$str)
+    {
+        if (preg_match("/^\'/", $str)) {
+            $str = substr($str, 1, strlen($str) - 1);
+        }
+        if (preg_match("/\'$/", $str)) {
+            $str = substr($str, 0, strlen($str) - 1);
+        }
+        return $str;
+    }
+
+    /**
+     * 查询数据库中是否有指定的表
+     * @param string $tableName 表名
+     * @param null|string $database 数据库
+     * @return bool
+     */
+    public function hasTable($tableName, $database = null)
+    {
+        if ($database) {
+            $this->setQuery('USE ' . $database);
+        }
+        $sql = "SHOW TABLES LIKE '" . $tableName . "'";
+        $rs = $this->setQuery($sql);
+
+        $tables = array();
+        while ($row = $this->fetch($rs)) {
+            if (is_array($row)) {
+                foreach ($row AS $val) {
+                    if ($val == $tableName) return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 获取创建表的SQL语句
+     * @param string $tableName 表名
+     * @param null|string $database 数据库
+     * @param int|null $autoIncr 自增长的值,null的话就不使用
+     * @return string
+     */
+    public function getTableSQL($tableName, $database = null, $autoIncr = null)
+    {
+        if ($database) {
+            $this->setQuery('USE ' . $database);
+        }
+        $row = $this->getRow("SHOW CREATE TABLE `" . $tableName . "`");
+        if (!$row) {
+            throw new \Exception('数据表不存在', __LINE__);
+        }
+        $sql = $row['Create Table'];
+        if ($autoIncr === null) {
+            return $sql;
+        }
+        return preg_replace("/AUTO_INCREMENT=[\d]{1,}/", "AUTO_INCREMENT=" . intval($autoIncr), $sql);
+    }
+
+    /**
+     * 通过数据表名称获取规则
+     * @param string $table 表名
+     * @param string $database 数据库名
+     */
+    public function buildRulesForTable($table, $database = null)
+    {
+        if (!$database) $database = $this->currentDB;
+        $tableInfo = $this->getTableInfo($table, $database);
+        $rules = new \Qii\Base\Rules();
+        $rules->addFields($tableInfo['fields']);
+        if ($tableInfo['rules']['required']) {
+            $rules->addForceValidKey($tableInfo['rules']['required']);
+        }
+        if (isset($tableInfo['rules']['number'])) {
+            foreach ($tableInfo['rules']['number'] as $key => $value) {
+                $rules->addRules($value, 'number', true, $value . '字段必须是数字');
+            }
+        }
+        if (isset($tableInfo['rules']['maxlength'])) {
+            foreach ($tableInfo['rules']['maxlength'] as $key => $value) {
+                $rules->addRules($key, 'maxlength', $value, $key . '字段内容长度不能大于' . $value . '个字符');
+            }
+        }
+        if (isset($tableInfo['rules']['timestamp'])) {
+            foreach ($tableInfo['rules']['timestamp'] as $key => $value) {
+                $rules->addRules($value, 'datetime', true, $value . '字段必须为日期格式');
+            }
+        }
+        return $rules;
+    }
+    /**
+     * 获取表的名称
+     * @param String $table
+     * @return String
+     */
+    public function getTable($table)
+    {
+        list($database, $tableName) = array_pad(explode('.', $table), 2, '');
+
+        if ($tableName) {
+            $tableName = stristr($tableName, '`') || stristr($tableName, " ") ? $tableName : '`'. $tableName .'`';
+            return "`{$database}`.`{$tableName}`";
+        }
+        $table = stristr($table, '`') || stristr($tableName, " ")  ? $table : '`'. $table .'`';
+        return $table;
+    }
+}

+ 17 - 0
src/Exceptions/InvalidParams.php

@@ -0,0 +1,17 @@
+<?php
+namespace Qii\Exceptions;
+
+class InvalidParams extends Errors
+{
+    const VERSION = '1.2';
+
+    /**
+     * 显示错误
+     *
+     * @param Object $e Exception
+     */
+    public static function getError($e)
+    {
+
+    }
+}

+ 1 - 1
src/Exceptions/Unsupport.php → src/Exceptions/Unsupported.php

@@ -1,7 +1,7 @@
 <?php
 namespace Qii\Exceptions;
 
-class Unsupport extends Errors
+class Unsupported extends Errors
 {
 	const VERSION = '1.2';
 

+ 3 - 1
src/Language/i18n/CN/exception.php

@@ -13,5 +13,7 @@ return array(
 	'qii execute footer' => '<p style="text-align:center;color:#9c9ea1;"><small>服务器软件:%s , 页面执行 %s seconds, 内存使用量 %s. 作者: %s 邮箱地址 : %s</small></p>',
 	'Please set rules first' => '请先设置规则',
 	'Invalid %s format' => '%s 格式错误',
-	'Unsupport method' => '不支持%s方法',
+	'%s is invalid' => '%s 参数不正确',
+	'Unsupported method %s' => '不支持%s方法',
+    'Unsupported operator' => '不支持的操作类型',
 );

+ 16 - 14
src/Language/i18n/EN/exception.php

@@ -1,17 +1,19 @@
 <?php
 return array(
-	'Welcome to Qii!' => 'Welcome to Qii!',
-	'Show Message' => 'Show Message',
-	'Throw Exception' => 'Throw Exception',
-	'The page you are looking at is being generated dynamically by Qii' => '<small style="color:#9c9ea1;">The page you are looking at is being generated dynamically by Qii</small>',
-	'Error information' => 'Error information',
-	'Error file' => 'Error file :%s',
-	'Error code' => 'Error code:%s',
-	'Error line' => 'Error line :%s',
-	'Error description' => 'Error description :%s',
-	'Trace as below' => 'Trace as below :',
-	'qii execute footer' => '<p style="text-align:center;color:#9c9ea1;"><small>%s , Page rendered in %s seconds, Use memory %s. Author: %s Email : %s</small></p>',
-	'Please set rules first' => 'Please set rules first',
-	'Invalid %s format' => 'Invalid %s format',
-	'Unsupport method' => 'Unsupport %s method',
+    'Welcome to Qii!' => 'Welcome to Qii!',
+    'Show Message' => 'Show Message',
+    'Throw Exception' => 'Throw Exception',
+    'The page you are looking at is being generated dynamically by Qii' => '<small style="color:#9c9ea1;">The page you are looking at is being generated dynamically by Qii</small>',
+    'Error information' => 'Error information',
+    'Error file' => 'Error file :%s',
+    'Error code' => 'Error code:%s',
+    'Error line' => 'Error line :%s',
+    'Error description' => 'Error description :%s',
+    'Trace as below' => 'Trace as below :',
+    'qii execute footer' => '<p style="text-align:center;color:#9c9ea1;"><small>%s , Page rendered in %s seconds, Use memory %s. Author: %s Email : %s</small></p>',
+    'Please set rules first' => 'Please set rules first',
+    'Invalid %s format' => 'Invalid %s format',
+    '%s is invalid' => '%s is invalid',
+    'Unsupported method %s' => 'Unsupported method %s',
+    'Unsupported operator' => '不支持的操作类型',
 );

+ 1 - 1
src/Request/Url.php

@@ -16,7 +16,7 @@ class Url
     {
         $allow = array('Normal', 'Middle', 'Short');
         if (!in_array($rewriteRule, $allow)) {
-            throw new \Qii\Exceptions\Unsupport("链接模式错误,链接格式只能为 '<u><font color=\"green\">" . join("', '", $allow) . "</font></u>',当前模式为 '<font color=\"red\">" . $rewriteRule . "</font>'", __LINE__);
+            throw new \Qii\Exceptions\Unsupported("链接模式错误,链接格式只能为 '<u><font color=\"green\">" . join("', '", $allow) . "</font></u>',当前模式为 '<font color=\"red\">" . $rewriteRule . "</font>'", __LINE__);
         }
         $className = 'Qii\Request\Url\\' . $rewriteRule;
         $this->request = \Qii\Autoloader\Psr4::getInstance()->loadClass($className, $rewriteRule);

+ 1 - 1
src/Request/Url/Base.php

@@ -377,7 +377,7 @@ abstract class Base
     public function checkMode($mode)
     {
         if (!in_array($mode, $this->_allowMode)) {
-            throw new \Qii\Exceptions\Unsupport("链接模式错误,链接格式只能为 '<u><font color=\"green\">" . join("', '", $this->_allowMode) . "</font></u>',当前模式为 '<font color=\"red\">" . $mode . "</font>'", __LINE__);
+            throw new \Qii\Exceptions\Unsupported("链接模式错误,链接格式只能为 '<u><font color=\"green\">" . join("', '", $this->_allowMode) . "</font></u>',当前模式为 '<font color=\"red\">" . $mode . "</font>'", __LINE__);
         }
     }
     /**

+ 1 - 1
src/View/Loader.php

@@ -15,7 +15,7 @@ class Loader
 	{
 		if(!in_array($engine, $this->allow))
 		{
-			throw new \Qii\Exceptions\Unsupport(\Qii::i('Unsupport method', $engine));
+			throw new \Qii\Exceptions\Unsupported(\Qii::i('Unsupported method', $engine));
 		}
 		$class = '\Qii\View\\'. ucwords($engine);
 		return $this->view = new $class();