Kaynağa Gözat

update mysql model

zjh 2 ay önce
ebeveyn
işleme
325c63a957

+ 4 - 0
src/Base/Action.php

@@ -15,6 +15,10 @@ class Action extends Controller
             return $this->controller->$name;
         }
     }
+    public function getMiddleware()
+    {
+        return [];
+    }
 
     public function __call($method, $args)
     {

+ 0 - 2
src/Base/Dispatcher.php

@@ -104,7 +104,6 @@ class Dispatcher
         }
         /**middleWare**/
         $this->getMiddleWare($this->controllerCls)->gatherMiddleware();
-
         $next = array_reduce($this->requestMiddleWare,function ($carry, $item){
             return function () use ($carry, $item){
                 return _loadClass($item)->handle(\Qii::getInstance()->request, $carry);
@@ -127,7 +126,6 @@ class Dispatcher
         $this->controllerCls->controllerId = $controller;
         $this->controllerCls->actionId = $action;
         $realAction = $action . Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX);
-
         //查看是否设置了当前action的对应关系,如果设置了就走对应关系里边的,否则走当前类中的
         if ($this->controllerCls->actions
             && isset($this->controllerCls->actions[$action])

+ 35 - 790
src/Driver/Base.php

@@ -2,10 +2,13 @@
 namespace Qii\Driver;
 use controller\error;
 use Qii\Autoloader\Psr4;
+use Qii\Driver\Trait\Cache;
+use Qii\Driver\Trait\Database;
 use Qii\Exceptions\InvalidFormat;
 use Qii\Exceptions\InvalidParams;
 use Qii\Exceptions\TableException;
 use Qii\Exceptions\Variable;
+use Qii\Driver\Trait\SQL;
 
 /**
  * Class Base
@@ -41,21 +44,9 @@ use Qii\Exceptions\Variable;
 class Base
 {
     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 %s",
-        "UPDATE" => "UPDATE %s SET ",
-        "DELETE" => "DELETE FROM %s %s",
-        "WHERE" => " WHERE %s",
-        "OR" => " `%s` = '%s' ",
-        "ORDER" => " ORDER BY %s %s",
-        "GROUP" => " GROUP BY %s",
-        "LIMIT" => " LIMIT %d, %d"
-    );
+    use Database;
+    use Cache;
+    use SQL;
     //load类
     public $load;
     //cache类
@@ -64,8 +55,6 @@ class Base
     public $language;
     //响应内容
     public $response;
-    //执行的sql语句
-    public $modelSQL = "";
     /**
      * @var string sql 引用
      */
@@ -95,10 +84,7 @@ class Base
     public $whereCondition = array();
     public $joinCondition = array();
 
-    public $fields = "*";
-    public $sets = array();
     protected $groupBy;
-    protected $limit;
     protected $orderBy;
 
     protected $_modelAlias = array('updateRows' => 'update', 'selectRows' => 'selectAll', 'select' => 'selectRow', 'getOne' => 'selectOne', 'getRow' => 'selectRow', 'getAll' => 'selectAll', 'remove' => 'delete', 'deleteRows' => 'delete');
@@ -124,7 +110,7 @@ class Base
         {
             $this->where($where);
         }
-        $sql = $this->createSelectSQL($table);
+        $sql = $this->selectSQL($table);
         return $this->getAll($sql);
     }
     /**
@@ -133,7 +119,7 @@ class Base
      */
     final function rs($table)
     {
-        $sql = $this->createSelectSQL($table);
+        $sql = $this->selectSQL($table);
         return $this->setQuery($sql);
     }
     /**
@@ -149,7 +135,7 @@ class Base
         {
             $this->where($where);
         }
-        $sql = $this->createSelectSQL($table);
+        $sql = $this->selectSQL($table);
         return $this->getRow($sql);
     }
 
@@ -178,7 +164,7 @@ class Base
             }
             throw new TableException("表名必须是字符串加下划线,目标字符为". gettype($table));
         }
-        $sql = $this->createSelectSQL($table);
+        $sql = $this->selectSQL($table);
         return $this->getOne($sql);
     }
 
@@ -190,27 +176,6 @@ class Base
     public function getOne($sql) {
         return false;
     }
-
-    /**
-     * 格式化插入值,新增null值插入
-     *
-     * @param $arr
-     * @return array|mixed
-     */
-    protected function formatInsertObject($arr) {
-        if(is_array($arr)) {
-            $values = array();
-            foreach ($arr as $val) {
-                if(strtoupper(gettype($val)) == 'NULL') {
-                    $values[] = 'null';
-                    continue;
-                }
-                $values[] = "'". $val . "'";
-            }
-            return $values;
-        }
-        return $arr;
-    }
     /**
      * 插入数据
      * @param $table
@@ -220,19 +185,10 @@ class Base
      */
     final function insertObject($table, $dataArray)
     {
-        if (empty($table)) {
-            throw new InvalidParams(_i('%s is invalid', 'table'), __LINE__);
-        }
-        $replaceObj = $this->createInsertReplaceObj($dataArray);
-        if(empty($replaceObj['fields']) || empty($replaceObj['values']))
-        {
-            throw new Variable(_i('Invalid %s format', 'data'), __LINE__);
-        }
-        // 针对 null 值单独处理,并将值的两端加上单引号 '
-        $values = $this->formatInsertObject($replaceObj['values']);
-        $this->executeSQL = $this->modelSQL = $sql = "INSERT INTO " . $this->getTable($table) . "(`" . join("`, `", $replaceObj['fields']) . "`) VALUES(". join(',', $values) . ")";
-
+        $sql = $this->insertSQL($table, $dataArray);
+        $this->startTime($sql);
         $this->setQuery($sql);
+        $this->endTime($sql);
         $this->setError();
         return $this->lastInsertId();
     }
@@ -244,53 +200,11 @@ class Base
      */
     final function replaceObject($table, $dataArray)
     {
-        if (empty($table)) {
-            throw new InvalidParams(_i('%s is invalid', 'table'), __LINE__);
-        }
-        $replaceObj = $this->createInsertReplaceObj($dataArray);
-        if(empty($replaceObj['fields']) || empty($replaceObj['values']))
-        {
-            throw new Variable(_i('Invalid %s format', 'data'), __LINE__);
-        }
-        // 针对 null 值单独处理,并将值的两端加上单引号 '
-        $values = $this->formatInsertObject($replaceObj['values']);
-
-        $this->executeSQL = $this->modelSQL = $sql = "REPLACE INTO " . $this->getTable($table) . "(`" . join("`, `", $replaceObj['fields']) . "`) VALUES(". join(',', $values) . ")";
+        $sql = $this->replaceSQL($table, $dataArray);
         $rs = $this->setQuery($sql);
         $this->setError();
         return $this->AffectedRows($rs);
     }
-
-    /**
-     * 创建插入或替换的内容
-     *
-     * @param $dataArray
-     * @return array
-     * @throws InvalidFormat
-     */
-    protected function createInsertReplaceObj($dataArray)
-    {
-        if(gettype($dataArray) == 'object') {
-            $dataArray = get_object_vars($dataArray);
-        }
-        if (sizeof($dataArray) > 0) {
-            $keys = array();
-            $values = array();
-            foreach ($dataArray AS $key => $value) {
-                $keys[] = $key;
-                if (is_array($value)) {
-                    throw new InvalidFormat(_i('Invalid %s format', $key), __LINE__);
-                }
-                if(strtoupper(gettype($value)) == 'NULL') {
-                    $values[] = null;
-                }else{
-                    $values[] = $this->setQuote($value);
-                }
-            }
-            return array('fields' => $keys, 'values' => $values);
-        }
-        return array('fields' => array(), 'values' => array());
-    }
     /**
      * 更新表中指定数据 结合set、where等方法是用
      *
@@ -300,21 +214,11 @@ class Base
      */
     public function update($table)
     {
-        if(!$table) {
-            throw new InvalidParams(_i('%s is invalid', '表名'), __LINE__);
-        }
-        $set = join(",", $this->sets);
-        $this->sets = array();
-        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();
-
-        $alias = $this->getTableAlias($table);
-        $this->executeSQL = $this->modelSQL = $sql = sprintf($this->_query['UPDATE'], $alias['name'] . $alias['alias']) . $set. $where;
-        return $this->exec($sql);
+        $sql = $this->updateSQL($table);
+        $this->startTime($sql);
+        $res = $this->exec($sql);
+        $this->endTime($sql);
+        return $res;
     }
     /**
      * 更新表的数据,同时可以使用update方法达到同样的效果
@@ -326,9 +230,6 @@ class Base
      * @throws \Exception
      */
     final function updateObject($table, $dataArray, $where = array()){
-        if(!$table) {
-            throw new InvalidParams(_i('%s is invalid', '表名'), __LINE__);
-        }
         return $this->set($dataArray)->where($where)->update($table);
     }
 
@@ -341,15 +242,11 @@ class Base
      */
     final function delete($table)
     {
-        if(!$table) {
-            throw new \Exception('未指定更新的表名', __LINE__);
-        }
-        $where = count($this->whereCondition) > 0 ? " WHERE ". join(" ", $this->whereCondition) : "";
-        $this->whereCondition = array();
-
-        $alias = $this->getTableAlias($table);
-        $this->executeSQL = $this->modelSQL = $sql = sprintf($this->_query['DELETE'], $alias['name'], $where);
-        return $this->exec($sql);
+        $sql = $this->deleteSQL($table);
+        $this->startTime($sql);
+        $res = $this->exec($sql);
+        $this->endTime($sql);
+        return $res;
     }
 
     /**
@@ -367,135 +264,6 @@ class Base
         }
         return $this->where($where)->delete($table);
     }
-    /**
-     * like语句
-     * @param mix $arr
-     * @return $this
-     */
-    final function like($arr)
-    {
-        if(!is_array($arr)) {
-            if(!empty($arr)) {
-                $this->where($arr);
-            }
-            return $this;
-        }
-        foreach($arr as $key => $val) {
-            $arr[$key .":like"] = $val;
-            unset($arr[$key]);
-        }
-        $this->where($arr);
-        return $this;
-    }
-    /**
-     * like语句
-     * @param mix $arr
-     * @return $this
-     */
-    final function llike($arr)
-    {
-        if(!is_array($arr)) {
-            if(!empty($arr)) {
-                $this->where($arr);
-            }
-            return $this;
-        }
-        foreach($arr as $key => $val) {
-            $arr[$key .":llike"] = $val;
-            unset($arr[$key]);
-        }
-        $this->where($arr);
-        return $this;
-    }
-    /**
-     * like语句
-     * @param mix $arr
-     * @return $this
-     */
-    final function rlike($arr)
-    {
-        if(!is_array($arr)) {
-            if(!empty($arr)) {
-                $this->where($arr);
-            }
-            return $this;
-        }
-        foreach($arr as $key => $val) {
-            $arr[$key .":rlike"] = $val;
-            unset($arr[$key]);
-        }
-        $this->where($arr);
-        return $this;
-    }
-
-    /**
-     *
-     * Limit函数,如果省略第二个参数则第一个为0,第二个参数值取第一个
-     * @param int $limit
-     * @param int $offset
-     */
-    final function limit($limit, $offset = null)
-    {
-        $this->limit = null;
-        if($limit === '' || $limit === null) {
-            throw new InvalidParams(_i('%s is invalid', 'Limit'), __LINE__);
-        }
-        if ($limit !== '') {
-            if ($offset === null) {
-                $this->limit = sprintf($this->_query["LIMIT"], 0, $limit);
-            } else {
-                $this->limit = sprintf($this->_query["LIMIT"], $limit, $offset);
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * sql中的set条件
-     *
-     * @param array $set
-     * @param null $res
-     * @param string $defaultOperator
-     * @return $this
-     */
-    final public function set($set, &$res = null, $defaultOperator = 'equal')
-    {
-        if(!is_array($set))
-        {
-            if(!empty($set))
-            {
-                $this->sets[] = $set;
-            }
-            return $this;
-        }
-        if(count($set) == 0) {
-            return $this;
-        }
-        $operator = array("equal" => "%s`%s` = '%s'", "unequal" => "%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)
-        {
-            if(strtoupper(gettype($val)) != 'NULL') {
-                $val = $this->setQuote($val);
-            }
-            $alias = $this->getFieldAlias($key);
-            $operate = $this->getFieldOperator($alias['name']);
-            if($operate['operator'] == '') {
-                $operate['operator'] = $defaultOperator;
-            }
-            $opt = $operator[$operate['operator']];
-            if(strtoupper(gettype($val)) == 'NULL') {
-                $val = 'NULL';
-                $opt = str_replace("'", '', $opt);
-            }
-            if($operate['operator'] == 'equal') {
-                $this->sets[] = sprintf($opt, $alias['alias'], $operate['field'], $val);
-            }else{
-                $this->sets[] = sprintf($opt, $alias['alias'], $operate['field'], $alias['alias'], $operate['field'], $val);
-            }
-        }
-
-        return $this;
-    }
 
     /**
      * set 字段加
@@ -519,7 +287,7 @@ class Base
             if(substr($key, -5) == ':plus') {
                 continue;
             }
-            $set[$key . ":plus"] = $val;
+            $set[$key . ":incr"] = $val;
             unset($set[$key]);
         }
         return $this->set($set);
@@ -545,104 +313,12 @@ class Base
             if(substr($key, -6) == ':minus') {
                 continue;
             }
-            $set[$key . ":minus"] = $val;
+            $set[$key . ":decr"] = $val;
             unset($set[$key]);
         }
         return $this->set($set);
     }
 
-    /**
-     * 处理where条件
-     *
-     * @param $where
-     * @return $this|array
-     * @throws \Exception
-     */
-    public function handleWhereFields($where) {
-        if(!is_array($where)) {
-            return $where;
-        }
-        $fields = [];
-        foreach ($where as $key => $val) {
-            //如果是操作符,直接放入操作符中
-            if(is_integer($key) && $this->isOperator($val)) {
-                $fields[] = $val;
-                continue;
-            }
-            $arr = explode(':', $key);
-            $len = count($arr);
-            $maxLen = 1;
-            $opt = '';
-            if(!$this->isExpression($arr[$len - 1])) {
-                $maxLen = 0;
-            }else{
-                $opt = ':' .$arr[$len - 1];
-            }
-            if($len > $maxLen) {
-                $arr1 = array_slice($arr, 0, count($arr) - $maxLen);
-                if(is_array($val)) {
-                    $arr2 = [];
-                    foreach ($val as $k1 => $v1) {
-                        $keyArr = explode(':', $k1);
-                        $lenKey = count($keyArr);
-                        if($lenKey > 2) {
-                            $opt1 = $keyArr[$lenKey-1];
-                            $keyArrSlice = array_slice($keyArr, 0, $lenKey-1);
-                            foreach ($keyArrSlice as $k2 => $v2) {
-                                $arr2[$v2 .':'. $opt1] = $v1;
-                                if($k2 < $lenKey-2) {
-                                    $arr2[] = 'or';
-                                }
-                            }
-                        }
-                    }
-                    if(count($arr2) > 0) {
-                        $fields[] = $arr2;
-                        continue;
-                    }
-                }
-                $tmp = [];
-                foreach ($arr1 as $key1) {
-                    $tmp[$key1 . $opt] = $val;
-                }
-                if(count($tmp) > 0) {
-                    $fields[] = $tmp;
-                }
-            }
-        }
-        return $fields;
-    }
-    /**
-     * where条件
-     * @param array $where where语句
-     * @param null $res
-     * @return $this
-     */
-    public function where($where, &$res = null)
-    {
-        if(!is_array($where)) {
-            if(!empty($where))
-            {
-                if(!empty($this->whereCondition) && !$this->isOperator($where)) {
-                    $this->whereCondition[] = "and";
-                }
-                if($this->isOperator($where)) {
-                    $this->whereCondition[] = $where;
-                }else{
-                    $this->whereCondition[] = "(". $where . ")";
-                }
-            }
-            return $this;
-        }
-        if(count($where) == 0) {
-            return $this;
-        }
-        $where = $this->handleWhereFields($where);
-        $slices = $this->groupContents($where);
-        $this->handleCondition($slices, $res);
-        return $this;
-    }
-
     /**
      * OR 条件
      * 用法:
@@ -659,52 +335,9 @@ class Base
      * @return $this
      * @throws \Exception
      */
-    public function orTerms($where, $defaultOperater = 'or', &$res = null)
+    public function orTerms($where)
     {
-        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;
-        }
-        $extra = [];
-        foreach ($where as $key => $val) {
-            $fields = explode(':', $key);
-            $len = count($fields);
-            $min = 2;
-            $opt = '';
-            if($this->isExpression($fields[$len - 1])) {
-                $min = 3;
-                $opt = ':'. $fields[$len - 1];
-            }
-            if($len >= $min) {
-                $arr = array_slice($fields, 0, ($opt != '' ? $len - 1 : $len));
-                foreach ($arr as $key1 => $field) {
-                    $extra[$field . $opt] = $val;
-                    if($key1 < count($arr) - 1) {
-                        $extra[] = 'OR';
-                    }
-                }
-                unset($where[$key]);
-            }
-        }
-        if(count($where) > 0) {
-            $this->handleCondition(array(array($defaultOperater, $where)), $res);
-        }
-        if(count($extra) > 0) {
-            $this->handleCondition(array(array($defaultOperater, $extra)), $res);
-            /*foreach ($extra as $key => $val) {
-                $this->handleCondition(array(array($defaultOperater, [$key => $val])), $res);
-            }*/
-        }
-        return $this;
+        return $this->or($where);
     }
 
     /**
@@ -738,9 +371,7 @@ class Base
             $where[$key . ":in"] = $val;
             unset($where[$key]);
         }
-        $where = $this->handleWhereFields($where);
-        $this->handleCondition(array(array('and', $where)), $res);
-        return $this;
+        return $this->where($where);
     }
 
     /**
@@ -760,36 +391,13 @@ class Base
         }
         foreach($where as $key => $value) {
             if($this->getFieldOperator($key)['operator'] == '') {
-                $where[$key . ":unequal"] = $value;
+                $where[$key . ":neq"] = $value;
                 unset($where[$key]);
             }
         }
         return $this->where($where);
     }
 
-    /**
-     * join语句
-     *
-     * @param mix $val
-     * @param reference $res 用于返回值
-     * @return $this
-     * @throws \Exception
-     */
-    public function join($val, &$res = null, $joinType = 'leftJoin') {
-        if(!is_array($val)) {
-            if(!empty($val)) {
-                $this->joinCondition[] = $val;
-            }
-            return $this;
-        }
-        if(count($val) == 0) {
-            return $this;
-        }
-        $slices = $this->groupContents($val);
-        $this->handleTableJoin($slices, $joinType, $res);
-        return $this;
-    }
-
     /**
      * left join
      * @param $table
@@ -799,8 +407,7 @@ class Base
      */
     final function leftJoinObject($table, $on)
     {
-        $alias = $this->getTableAlias($table);
-        return $this->join(" LEFT JOIN ". $this->getTable($alias['name']) . " " . $alias['alias'] ."  ON ". $on);
+        return $this->join($table, $on);
     }
 
     /**
@@ -810,23 +417,7 @@ class Base
      */
     public function groupBy($group)
     {
-        if(!is_array($group))
-        {
-            if(!empty($group))
-            {
-                $this->groupBy = stristr($group, 'GROUP BY') === false?  "GROUP BY ". $group: $group;
-            }
-            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);
+        $this->group($group);
         return $this;
     }
 
@@ -839,32 +430,7 @@ class Base
      */
     public function orderBy($order)
     {
-        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 InvalidParams(_i('%s is invalid', 'sort'), __LINE__);
-            }
-            $alias = $this->getFieldAlias($key);
-
-            $orderBy[] = $alias['alias'] . "`". $alias['name'] ."` ". $sort;
-            $i++;
-        }
-        $this->orderBy = " ORDER BY ". join(",", $orderBy);
+        $this->order($order);
         return $this;
     }
 
@@ -877,71 +443,14 @@ class Base
      */
     public function orderByStr($orderBy)
     {
-        return $this->orderBy($orderBy);
-    }
-    /**
-     * 过滤值
-     *
-     * @param string|array $word
-     * @return array|string
-     */
-    final function setQuote($word)
-    {
-        if (ini_get("magic_quotes_gpc")) {
-            return $word;
-        }
-        if(in_array(gettype($word), array("object", "resource","resource (closed)"))) {
-            throw new \Exception('期待参数为数组或字符串,获取到的是:'. gettype($word)."(". json_encode($word) .")");
-        }
-        return is_array($word) ? array_map('addslashes', $word) : addslashes($word);
-    }
-    /**
-     *
-     * 查询的字段
-     * @param string|array $fields
-     * @return $this
-     */
-    final function fields($fields = "*", $append = false)
-    {
-        if (empty($fields) && !$append) $fields = "*";
-        if (is_array($fields)) {
-            if(count($fields) == 0) {
-                $fields = $append ? '' : '*';
-            }else{
-                foreach($fields as $key => $val)
-                {
-                    $alias = explode('.', $val);
-                    if(count($alias) > 1)
-                    {
-                        if(strpos("*", $alias[1]) !== false) {
-                            $fields[$key] = $val;
-                            continue;
-                        }
-                        $fields[$key] = $alias[0] . ".`".join(".", array_slice($alias, 1))."`";
-                    }
-                }
-                $fields = join(',', $fields);
-            }
-        }
-        if($append) {
-            if($fields != "") $this->fields .= ','. $fields;
-        }else{
-            $this->fields = $fields;
-        }
-        return $this;
+        return $this->order($orderBy);
     }
     /**
      * 清空Data数据
      */
     final public function cleanCondition()
     {
-        $this->fields = '*';
-        $this->whereCondition = array();
-        $this->joinCondition = array();
-        $this->groupBy = "";
-        $this->orderBy = "";
-        $this->limit = null;
-        $this->sets = array();
+        $this->clean();
     }
 
     /**
@@ -1013,47 +522,6 @@ class Base
         $this->executeSQL = &$sql;
         return $this;
     }
-    /**
-     * 通过where\set\limit等方法自动生成SQL语句
-     *
-     * @param string $table 必填
-     * @return string
-     * @throws \Exception
-     */
-    public function createSelectSQL($table)
-    {
-        if(!$table) {
-            throw new InvalidParams(_i('%s is invalid', '表名'), __LINE__);
-
-        }
-        $aliases = $this->getTableAlias($table);
-
-        $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();
-
-        $join = count($this->joinCondition) > 0 ? join("\n", $this->joinCondition) : "";
-        //$this->joinCondition = array();
-
-        $groupBy = " ". $this->groupBy;
-        //$this->groupBy = "";
-
-        $orderBy = " ". $this->orderBy;
-        //$this->orderBy = "";
-
-        $limit = $this->limit;
-        //$this->limit = null;
-
-        $sql = sprintf($this->_query['SELECT'], $fields, $aliases['name'], $aliases['alias']) . $join . $where . $groupBy . $orderBy . $limit;
-        $this->cleanCondition();
-        $this->executeSQL = $this->modelSQL = $sql;
-        return $sql;
-    }
     /**
      * 获取操作符
      *
@@ -1088,49 +556,6 @@ class Base
         return array('alias' => $aliases[0] . $connector, 'name' => join(".", array_slice($aliases, 1)));
     }
 
-    /**
-     * 获取表的别名
-     *
-     * @param string $name 名字
-     * @return array
-     */
-    protected function getTableAlias($name)
-    {
-        if (!$this->verifyTable($name)) {
-            if (gettype($name) == 'string') {
-                throw new TableException("表名不能包含怪字符且不能以数字开头,获取到的是". $name);
-            }
-            throw new TableException("表名必须是字符串加下划线,目标字符为". gettype($name));
-        }
-        //去掉table前后的``符号
-        $name = str_replace('`', '', $name);
-        $aliases = explode(' ', $name);
-        //检查表名中时候含数据库名,有数据表名的时候需要单独处理
-        $hasDatabaseName = false;
-        if(stristr($name, '.')) {
-            $hasDatabaseName = true;
-        }
-        if(count($aliases) == 1) {
-            if($hasDatabaseName) {
-                $names = explode(".", $name);
-                $name = $names[0] . ".`". $names[1] . "`";
-            }else{
-                $name = "`". $name ."`";
-            }
-            return array('alias' => '', 'name' => $name);
-        }
-        $res = array();
-        $res['alias'] = array_pop($aliases);
-        $res['name'] = join(" ", array_slice($aliases, -1));
-        if($hasDatabaseName) {
-            $names = explode(".", $res['name']);
-            $res['name'] = $names[0] . ".`". $names[1] . "`";
-        }else{
-            $res['name'] = "`". $res['name'] ."`";
-        }
-        return $res;
-    }
-
     /**
      * 把条件根据『链接字符串,『字段:值』』等内容分组
      *
@@ -1276,85 +701,6 @@ class Base
         return in_array($val, $this->operateTable);
     }
 
-    /**
-     * where条件子句组合
-     *
-     * @param array $values ['字段1' => '值1', '字段2' => '值2', ...]
-     * @param string $defaultOperate 默认字句的链接方式
-     *  ..... 额外的参数,用于字段与字段之间的连接
-     * @return string
-     * @throws \Exception
-     */
-    protected function handleSubCondition($values, $defaultOperate = 'equal')
-    {
-        $extraParams = array();
-        if(func_num_args() > 2)
-        {
-            $extraParams = array_slice(func_get_args(), 2);
-        }
-        $where = array();
-        $operator = $this->shortExpression;
-        $lastIsOperator = false;
-        $lastIsValue = null;
-        $i = 0;
-        foreach($values as $key => $val)
-        {
-            $isOperator = preg_match("/^[0-9].*/", $key) && $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 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";
-            }
-
-            //$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')
-            {
-                if(is_array($val)) {
-                    $where[] = sprintf($operator[$opt], $alias, $name, "'". join("','", $val) . "'");
-                }else{
-                    $where[] = sprintf($operator[$opt], $alias, $name, $val);
-                }
-            }else{
-                if(!isset($operator[$opt])) {
-                    throw new \Exception("Unknow operator " . $opt, __LINE__);
-                }
-                // between and 不做转换
-                $val = $val;
-                if($opt != 'between') {
-                    $val = $this->setQuote($val);
-                }
-                if($opt == 'between' && is_array($val)) {
-                    $val = "'". join("' AND '", $val) . "'";
-                }
-                $where[] = sprintf($operator[$opt], $alias, $name, $val);
-            }
-            $lastIsValue = $isValue;
-            $lastIsOperator = $isOperator;
-            $i++;
-        }
-        return join(" ", $where);
-    }
-
     /**
      * 处理table join
      * @param array $slices [['leftJoin', ['table' => '表名', 'alias' => 'a', 'on' => 'a.id = b.id']]]
@@ -1399,107 +745,6 @@ class Base
         return $this;
     }
 
-    /**
-     * 处理 where 条件
-     * @param array $condition
-     * @param null $res
-     * @return $this
-     * @throws \Exception
-     */
-    protected function handleCondition($condition, &$res = null)
-    {
-        if(!is_array($condition))
-        {
-            return $this;
-        }
-        $count = count($condition);
-        $whereCondition = array();
-        for($i = 0; $i < $count; $i++)
-        {
-            $v = $condition[$i];
-            if(!is_array($v) && $this->isOperator($v)) {
-                $whereCondition[] = ' '.$v.' ';
-                continue;
-            }
-            //如果有两个及上的操作符
-            //默认第一个为连接其他条件的操作符,第二个位字段和值之间的操作符, 从第三个开始即为字段与字段之间的连接符
-            //最里层的字段与值之间的操作符优先级最高
-
-            //例如 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]))
-                {
-                    if(empty($operateCondition)) {
-                        continue;
-                    }
-                    $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) .")";
-                }
-            }
-        }
-        if(!empty($this->whereCondition))
-        {
-            $lastCondition = $this->whereCondition[count($this->whereCondition) - 1];
-            if(count($whereCondition) > 0 && !$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;
-    }
-
     /**
      * 验证数据表名是否符合规范
      * 表名不能以数字开头,

+ 0 - 525
src/Driver/Easy.php

@@ -1,525 +0,0 @@
-<?php
-/**
- * 简易数据库操作类
- *
- * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-12-10 14:35
- *
- * usage:
- * $user = (new \Qii\Driver\Easy())->_initialize();
- * $user->setRules(new \Qii\Driver\Rules($rules));
- * $user->setPrivateKey(array());
- * $user->uid = 1;
- * $user->email = 'antsnet@163.com';
- * $user->nick = 'Jinhui Zhu';
- * $user->add_time = time();
- * $user->update_time = time();
- * 保存数据
- * $user->_save();
- * 检查指定数据是否存在,以privateKey为准
- * $user->_exist();
- * 删除指定数据,以privateKey为准
- * $user->_remove()
- * 更新数据,以privateKey为准
- * $user->_update();
- * if($user->isError())
- * {
- *     //todo 如果执行操作有问题,错误详情 $user->getErrors()
- * }
- * else
- * {
- *     //todo 对返回结果进行处理
- * }
- *
- * //获取所有
- * $user->_getRowsByEmail('antsnet@163.com');
- * $user->_getRowByFileds($this->_privateKey);
- * $user->_getRowsByFileds($this->_privateKey);
- * $user->getEmailByUid(1);
- * $user->_getAllByUid(1);
- */
-namespace Qii\Driver;
-
-use Qii\Exceptions\Errors;
-use Qii\Exceptions\TableException;
-
-class Easy
-{
-	const VERSION = '1.2';
-	/**
-	 * @var Fields $fields
-	 */
-	private $fields = null;
-	/**
-	 * 数据表主键
-	 * @var array $privateKeys
-	 */
-	private $privateKeys = array();
-	/**
-	 * 保存或更新的时候验证的规则
-	 * @var array $rules
-	 */
-	private $easyRules = array();
-	/**
-	 * @var string $databaseName 数据库名称
-	 * 如果没有指定数据库名称将使用当前连接的数据库
-	 */
-	private $databaseName;
-	/**
-	 * @var string $tableName 表名,
-	 * 如果要指定操作的数据库名需要将数据库名和表名合在一起,如:database.table
-	 */
-	private $tableName = '';
-	/**
-	 * @var book $isInstance 是否实例化对象了
-	 */
-	private $isInstance = false;
-	/**
-	 * @var array $_response 操作出错保存数据到此数组
-	 */
-	private $_response;
-	/**
-	 * @var bool  是否需要重置privateKeys
-	 */
-	private $needResetPrivatekey = true;
-	
-	private $db;
-
-	public function __construct()
-	{
-		$this->db = (new \Qii\Driver\Model())->db;
-		$this->clean();
-		return $this;
-	}
-
-	/**
-	 * 初始化数据库对象
-	 *
-	 */
-	final public function _initialize()
-	{
-		$this->isInstance = true;
-		$this->clean();
-		return $this;
-	}
-
-	/**
-	 * 设置表字段
-	 *
-	 * @param array $fields
-	 * @return $this
-	 */
-	final public function setFields(array $fields)
-	{
-		$this->fields = new Fields($fields);
-		return $this;
-	}
-
-	/**
-	 * 设置主键
-	 *
-	 * @param array|string $privateKeys
-	 */
-	final public function setPrivateKey(array $privateKeys)
-	{
-		if(count($privateKeys) == 0) return $this;
-		$this->needResetPrivatekey = false;
-		$this->privateKeys = $privateKeys;
-		return $this;
-	}
-
-	/**
-	 * 重置主键,主要用于查询、更新、删除操作
-	 *
-	 * @param string | null $opt
-	 * @return array
-	 */
-	final public function resetPrivateKey($opt = null)
-	{
-		if ($this->needResetPrivatekey && $opt) {
-			$valid = $this->easyRules->getOperateValidFields($opt);
-			if (!empty($valid)) $this->privateKeys = array_values($valid);
-		}
-		return $this->privateKeys;
-	}
-
-	/**
-	 * 设置规则
-	 * @param array $rules {_save:{}, _update:{}, _remove:{}}
-	 */
-	final public function setRules(\Qii\Driver\Rules $rules)
-	{
-		$this->setFields($rules->getFields());
-		$this->tableName = $rules->getTableName();
-		$this->databaseName = $rules->getDatabase();
-		if (!$this->privateKeys) $this->privateKeys = $rules->getPrivateKey();
-		$this->easyRules = $rules;
-		return $this;
-	}
-
-	/**
-	 * 设置表字段
-	 *
-	 * @param $name
-	 * @param $val
-	 * @return $this
-	 */
-	public function __set($name, $val)
-	{
-		$this->fields->$name = $val;
-		return $this;
-	}
-
-	/**
-	 * 批量设置字段的值
-	 * @param array $data
-	 * @return $this
-	 */
-	public function setFieldsVal(array $data)
-	{
-		foreach ($data AS $name => $val) {
-			$this->fields->$name = $val;
-		}
-		return $this;
-	}
-
-	/**
-	 * 获取当前使用的rules的字段
-	 *
-	 * @return mixed
-	 */
-	public function getFields()
-	{
-		return $this->easyRules->getFields();
-	}
-	/**
-	 * 获取当前使用的fields的值
-	 *
-	 * @return mixed
-	 */
-	public function getValues()
-	{
-		return $this->fields->getValueAsArray();
-	}
-
-	/**
-	 * 如果没有调用parent::__construct()方法就报错
-	 *
-	 */
-	public function checkInstance()
-	{
-		if (!$this->isInstance) {
-			$this->_response = Response::Fail('checkInstance', array('msg' => \Qii::i(1507, 'parent::__construct()'), 'code' => __LINE__));
-			throw new TableException(\Qii::i(1507, 'parent::__construct()'), __LINE__);
-		}
-		return $this;
-	}
-
-	/**
-	 * 重置Fields及相关条件
-	 *
-	 */
-	final protected function clean()
-	{
-		$this->fields = null;
-		$this->privateKeys = array();
-		$this->easyRules = array();
-		$this->tableName = '';
-		$this->_response = new Response();
-		return $this;
-	}
-
-	/**
-	 * 验证保存的数据
-	 *
-	 * @param $rules
-	 * @return bool
-	 */
-	final protected function validateFields($rules)
-	{
-		if (empty($rules)) return true;
-		$validateCls = _loadClass('\Qii\Library\Validate');
-		$result = $validateCls->verify($this->fields->getValues(), $rules, $this->easyRules->getInvalidMessage());
-		if ($result === true) {
-			return true;
-		}
-		$error = $validateCls->getErrors();
-		$this->_response = Response::FailValidate('validate', array('_result' => $error['msg'], 'fields' => array('field' => $error['field'], 'message' => $error['msg'])));
-		return false;
-	}
-
-	/**
-	 * 获取用户表
-	 */
-	final public function getTableName()
-	{
-		if (!$this->tableName) throw new Errors(\Qii::i(1510), true);
-		return $this->databaseName ? $this->databaseName . '.' . $this->tableName : $this->tableName;
-	}
-
-	/**
-	 * 对指定字段执行指定方法 同时校验值的有效性
-	 *
-	 * @param String $func
-	 * @param String $field
-	 * @param String $val
-	 * @return Object
-	 */
-	final public function func($func, $key, $val)
-	{
-		$rule = $this->getValidateField($key);
-		//如果字段需要用到函数编码字符,如果没有通过验证就不将值放入fields中
-
-		$validateCls = _loadClass('Qii\Library\Validate');
-		$result = $validateCls->verify(array($key => $val), array($key => $rule), $this->easyRules->getInvalidMessage());
-		if ($result === true) {
-			$this->fields->$key = $func($val);
-			return $this;
-		}
-		$error = $validateCls->getErrors();
-		$this->_response = Response::FailValidate('validate', array('_result' => $error['msg'], 'fields' => array('field' => $error['field'], 'message' => $error['msg'])));
-		return $this;
-	}
-
-	/**
-	 * 检查数据是否已经存在,并返回一行,只能根据主键查询
-	 *
-	 * @return \Qii\Driver\Response
-	 */
-	final public function _exist()
-	{
-		$this->checkInstance();
-		if (!$this->privateKeys) {
-			$this->_response = Response::FAIL('privateKey', \Qii::i(1513));
-			return $this->_response;
-		}
-		$where = array();
-		foreach ($this->privateKeys AS $key) {
-			$rule = $this->getValidateField($key);
-			if (count($rule) > 0 && !$this->validateFields(array($key => $rule))) {
-				return $this->_response;
-			}
-			if ($this->fields->hasField($key)) $where[] = "`{$key}` = '" . $this->db->setQuote($this->fields->getField($key)) . "'";
-		}
-		$result = $this->db->limit(1)->where(join(' AND ', $where))->select($this->getTableName());
-		if(!$result)
-		{
-			$result = array();
-		}
-		if ($this->db->isError()) {
-			$this->_response = $this->db->getResponse();
-		}
-		return $this->_response = Response::Success('_exist', array('_result' => $result));
-	}
-
-	/**
-	 * 获取主键对应的值
-	 * @return array
-	 */
-	final protected function getPrivateValue()
-	{
-		$data = array();
-		foreach ($this->privateKeys AS $key) {
-			$data[$key] = $this->fields->getField($key);
-		}
-		return $data;
-	}
-
-	/**
-	 * 保存数据
-	 *
-	 * @return string 如果是自动增长的行返回插入数据的id
-	 */
-	final public function _save()
-	{
-		$this->checkInstance();
-		if (!$this->validateFields($this->easyRules->getRulesByOperate('save'))) return $this->_response;
-		$this->resetPrivateKey('save');
-		if ($this->privateKeys && count($this->_exist()->getResult()) > 0) {
-			$this->_response = Response::Exist('_save', array('_result' => \Qii::i(1511, join(',', $this->getPrivateValue()))));
-			return $this->_response;
-		}
-		$result = $this->db->insertObject($this->getTableName(), $this->fields->getValueAsArray());
-		if ($this->db->isError()) {
-			return $this->db->getResponse();
-		}
-		return $this->_response = Response::Success('_save', array_merge($this->fields->getValueAsArray(), array('_result' => $result)));
-	}
-
-	/**
-	 * 更新数据
-	 *
-	 * @return int  更新数据影响的行数
-	 */
-	final public function _update()
-	{
-		$this->checkInstance();
-		if (!$this->validateFields($this->easyRules->getRulesByOperate('update'))) return $this->_response;
-		$this->resetPrivateKey('update');
-		if (count($this->_exist()->getResult()) == 0) {
-			return $this->_response = Response::NotExist('_update', \Qii::i(1512, join(',', $this->getPrivateValue())));
-		}
-        $values = $this->fields->getValueAsArray();
-        $where = [];
-        foreach ($this->privateKeys as $field) {
-            $where[$field] = $values[$field];
-            unset($values[$field]);
-        }
-		$result = $this->db->updateObject($this->getTableName(), $this->fields->getValueAsArray(), $where);
-		if ($this->db->isError()) {
-			return $this->_response = $this->db->getResponse();
-		}
-		return $this->_response = Response::Success('_update', array('_result' => $result));
-	}
-
-	/**
-	 * 删除数据
-	 * @return int 删除数据影响的行数
-	 */
-	final public function _remove()
-	{
-		$this->checkInstance();
-		if (!$this->validateFields($this->easyRules->getRulesByOperate('remove'))) return $this->_response;
-		$this->resetPrivateKey('remove');
-		if (count($this->_exist()->getResult()) == 0) {
-			return $this->_response = Response::NotExist('_remove', \Qii::i(1512, join(',', $this->getPrivateValue())));
-		}
-		$result = $this->db->deleteObject($this->getTableName(), $this->fields->getValueAsArray());
-		if ($this->db->isError()) {
-			return $this->_response = $this->db->getResponse();
-		}
-		return $this->_response = Response::Success('_remove', array('_result' => $result));
-	}
-
-	/**
-	 * 获取操作数据返回的错误
-	 */
-	final public function getErrors()
-	{
-		if ($this->_response) {
-			if (!$this->_response->isError()) return false;
-			return $this->_response;
-		}
-		return $this->db->getError();
-	}
-
-	/**
-	 * 是否有错误
-	 */
-	final public function isError()
-	{
-		if ($this->_response) {
-			return $this->_response->isError();
-		}
-		return $this->db->isError();
-	}
-
-	/**
-	 * 获取response对象
-	 */
-	final public function getResponse()
-	{
-		return $this->_response;
-	}
-
-	/**
-	 * 使用此方法用于查询某一条数据的某一个字段
-	 * @useage getXxxByXxx
-	 *     getNameById:通过id获取name的值; getEmailById:通过id获取email;
-	 *     _getRowById:返回所有字段; _getRowsById:通过id获取所有匹配的数据
-	 * 备注:以_开头的才会去走getRow, getRows方法去取所有字段,目前仅支持All, Row, Rows这几个方法
-	 * @param  String $method [description]
-	 * @param  Mix $args 请求的参数
-	 * @return Mix         [description]
-	 */
-	final public function __call($method, $args)
-	{
-		$this->checkInstance();
-		$selectType = 'normal';
-		if (substr($method, 0, 1) == '_') {
-			$selectType = 'system';
-			$method = substr($method, 1);
-		}
-		preg_match('/^(get)(.*)(By)(.*)/', $method, $matches);
-
-		if ($matches && count($matches) == 5 && $matches[1] == 'get') {
-			//大写字母匹配下划线,字段中统一用小写字母,在查询的时候使用驼峰结构
-			//如:getEmailAddressByUserId 通过user_id查询email_address
-			$field = strtolower(preg_replace('/(?<!^)([A-Z])/', '_$1', $matches[2]));
-
-			if (isset($this->_relationMap[$field])) $field = $this->_relationMap[$field];
-			$method = 'selectRow';
-			if ($field == 'rows' && $selectType == 'system') $method = 'selectRows';
-			if ($field == 'row' && $selectType == 'system') $method = 'selectRow';
-			if (in_array($field, array('all', 'row', 'rows')) && $selectType == 'system') {
-				$field = '*';
-			}
-			$value = $this->db->setQuote(array_shift($args));
-			$name = strtolower(strtolower(preg_replace('/(?<!^)([A-Z])/', '_$1', $matches[4])));
-			$whereArray = array();
-			if ($selectType == 'system' && $name == 'fields') {
-				foreach ($value AS $val) {
-					$whereArray[$val] = $this->fields->isField($val) ? $this->fields->getField($val) : '';
-				}
-			} else {
-				if (!$this->fields->isField($name)) $this->fields->$name = $value;
-				$whereArray[$name] = $this->fields->getField($name);
-			}
-			foreach ($whereArray AS $key => $val) {
-				$rule = $this->getValidateField($key);
-				if (count($rule) > 0 && !$this->validateFields(array($key => $rule))) {
-					return $this->_response;
-				}
-			}
-			$result = $this->db->fields($field)->whereArray($whereArray)->$method($this->getTableName());
-			if ($this->db->isError()) {
-				return $this->_response = $this->db->getResponse();
-			}
-			return $this->_response = Response::Success($method, array('_result' => $result));
-		}
-		//exec{$method}
-		preg_match('/^(exec)(.*)/', $method, $matches);
-
-		if ($matches && count($matches) == 3) {
-			$alias = lcfirst($matches[2]);
-			if (method_exists($this->db, $alias)) {
-				$result = $this->db->{$matches[2]}($this->getTableName(), $this->getFields());
-				if ($this->db->isError()) {
-					return $this->_response = $this->db->getResponse();
-				}
-				return $this->_response = Response::Success($matches[2], array('_result' => $result));
-			}
-			if ($this->db->getAlias($method) && method_exists($this->db, $this->db->getAlias($method))) {
-				$this->db->whereArray($this->getFields());
-				$result = $this->db->{$this->db->getAlias($method)}($this->getTableName());
-				if ($this->db->isError()) {
-					return $this->_response = $this->db->getResponse();
-				}
-				return $this->_response = Response::Success($this->db->getAlias($method), array('_result' => $result));
-			}
-		}
-		//访问方法的别名
-		if ($this->db->getAlias($method)) {
-			if (method_exists($this->db, $this->db->getAlias($method))) {
-				$result = call_user_func_array(array($this->db, $this->db->getAlias($method)), $args);
-				if ($this->db->isError()) {
-					return $this->_response = $this->db->getResponse();
-				}
-				return $this->_response = Response::Success($this->db->getAlias($method), array('_result' => $result));
-			}
-			$this->_response = Response::UndefinedMethod('__call', $this->db->getAlias($method));
-			\Qii::setError(false, __LINE__, 1106, 'Model', 'Alias ' . $this->db->getAlias($method) . ' does not exist.', print_r($args, true));
-		}
-		$this->_response = Response::UndefinedMethod('__call', $method);
-		\Qii::setError(false, __LINE__, 1106, 'Model', $method, print_r($args, true));
-	}
-
-	/**
-	 * 获取单个字段的验证规则
-	 * @param  String $fieldName 字段名
-	 * @return Array
-	 */
-	protected function getValidateField($fieldName)
-	{
-		return $this->easyRules->getRulesByField($fieldName);
-	}
-}

+ 0 - 420
src/Driver/EasyDrive.php

@@ -1,420 +0,0 @@
-<?php
-/**
- * 简易数据库操作类
- *
- * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-12-10 14:35
- *
- * usage:
- *
- *
- */
-namespace Qii\Driver;
-
-use Qii\Exceptions\InvalidParams;
-
-/**
- * 用法 :
- * 首先需要创建 _ormRules 文件 rules/user.php
-    use Qii\Base\Rules;
-    class user extends Rules {
-        public $table = 'user';
-        pubic function fields(){
-           return ['uid', 'nickname', 'password'];
-        }
-        public function constants() {
-            $this->addRequiredFields(
-                ['id', '用户ID不能为空'],
-                ['nickname', '昵称不能为空'],
-                ['password', '密码不能为空'],
-            );
-
-            $this->addNumberFields(
-                ['uid', '用户ID必须是数字']
-            );
-            $this->addSafeFields(
-                ['nickname', '昵称格式不正确,不能包含怪字符']
-            );
-            $this->addPasswordFields(
-                ['password', '密码格式不正确']
-            );
-        }
-    }
-    use Qii\Driver\EasyDrive;
-
-    class user extends EasyDrive {
-
-        public $_ormRules = 'rules\user';
-        public function __construct()
-        {
-            parent::__construct();
-        }
-    }
-
-    $user = new user();
-    $user->uid = 1;
-    $user->nickname = 'admin';
-    $user->password = md5('asdfadsfasdadfadf');
-    $response = $user->save();
-
-    $user->setPrivatekey(['uid']);
-    $response = $user->exist();
-
-    if($response->isError()) {
-        return ['code' => $response->getCode(), 'msg' => $response->getMessage()]
-   }
-   if($response->count() > 0) {
-        return $response->getResult();
-   }
- *
- * @method EasyORM setQueryFields(array $fields)
- * @method void cleanQueryFields()
- * @method void cleanValues()
- * @method EasyORM setLimit(int $start, int $end)
- * @method EasyORM cleanLimit()
- * @method EasyORM  cleanCondition()
- * @method EasyORM cleanFieldsVal()
- */
-class EasyDrive {
-    /**
-     * 数据表验证规则
-     * @var string
-     */
-    public $_ormRules = '';
-    /**
-     * 本方法
-     * @var EasyORM
-     */
-    protected $_easyORM;
-    /**
-     * 数据库操作类
-     * @var mixed
-     */
-    protected $db;
-    /**
-     * 验证器
-     * @var mixed
-     */
-    public $_validator;
-    private $_message = [];
-    /**
-     * @param string $rules 规则类名
-     * @throws InvalidParams
-     */
-    public function __construct($rules = ''){
-        if ($this->_ormRules == '') {
-            throw new InvalidParams('_ormRules is null');
-        }
-
-        if($rules != '') {
-            $this->_ormRules = $rules;
-        }
-
-        $rules = new $this->_ormRules();
-        $this->_easyORM = new EasyORM($rules);
-
-        $this->db = $this->getDB();
-        $this->_validator = _library("Validate");
-    }
-
-    /**
-     * 返回消息提示
-     *
-     * @return void
-     */
-    public function getMessage() {
-        return $this->_message;
-    }
-    /**
-     * 验证字段
-     *
-     * @return bool
-     */
-    public function verify() {
-        return true;
-    }
-    /**
-     * 清除数据
-     *
-     * @return EasyORM
-     */
-    final public function clean() {
-        return $this->_easyORM->clean();
-    }
-
-    /**
-     * 获取DB属性
-     * @return mixed
-     */
-    public function getDB() {
-        return $this->_easyORM->getDB();
-    }
-
-    /**
-     * 获取规则
-     *
-     * @return mixed
-     */
-    public function getRules() {
-        return $this->_easyORM->getRules();
-    }
-
-    /**
-     * has field
-     * @param string $key
-     * @return mixed
-     */
-    public function hasField($key) {
-        return $this->_easyORM->fields->hasField($key);
-    }
-    /**
-     * 获取所有的字段
-     *
-     * @return mixed
-     */
-    public function getFields() {
-        return $this->_easyORM->getFields();
-    }
-
-    /**
-     * 获取指定字段的值
-     *
-     * @param string $field
-     * @return mixed
-     */
-    public function getField($field) {
-        return $this->_easyORM->getFieldValue($field);
-    }
-
-    /**
-     * 设置表名,将rules暴露到外边
-     *
-     * @param string $table 表名
-     * @return mixed
-     */
-    public function setTable($table) {
-        $this->_easyORM->setTable($table);
-        return $this;
-    }
-
-    /**
-     * 返回表名
-     *
-     * @return mixed
-     */
-    public function getTable() {
-        return $this->_easyORM->getTable();
-    }
-
-    /**
-     * 获取字段及值 stdClass
-     *
-     * @return mixed
-     */
-    public function getValues() {
-        return $this->_easyORM->getValues();
-    }
-
-    /**
-     * 获取字段及值 array
-     * @return mixed
-     */
-    public function getValuesAsArray() {
-        return $this->_easyORM->getValueAsArray();
-    }
-
-    /**
-     * 验证数组中的数据
-     *
-     * @param array $values 需要验证的数组
-     * @return mixed
-     */
-    public function verifyFields($values) {
-        return $this->_easyORM->getRules()->verifyFields($values);
-    }
-
-    public function __set($name, $value) {
-        $this->_easyORM->fields->$name = $value;
-    }
-
-    public function __isset($name){
-        return isset($this->_easyORM->fields->$name);
-    }
-
-    public function __unset($name) {
-        if(isset($this->_easyORM->fields->$name)) unset($this->_easyORM->fields->$name);
-    }
-    /**
-     * getter
-     * @param string $name
-     * @return void
-     */
-    public function __get($name) {
-        return $this->_easyORM->getFieldValue($name);
-    }
-    /**
-     * 设置主键
-     *
-     * @param array $array 数组形式
-     * @return EasyORM
-     */
-    final public function setPrivateKey($array) {
-        $this->_easyORM->setPrivateKey($array);
-        return $this;
-    }
-
-    /**
-     * 设置where条件
-     *
-     * @param array $args
-     * @return $this
-     */
-    final public function where($args) {
-        $this->_easyORM->where($args);
-        return $this;
-    }
-
-    /**
-     * 清除 where 条件
-     * @return $this
-     */
-    final public function cleanWhere() {
-        $this->_easyORM->cleanWhere();
-        return $this;
-    }
-    /**
-     * 清除主键
-     *
-     * @return $this
-     */
-    final public function cleanPrivateKey() {
-        $this->_easyORM->cleanPrivateKey();
-        return $this;
-    }
-
-    /**
-     * 设置排除的内容
-     *
-     * @param array $array
-     * @return $this
-     */
-    final public function setExclude($array) {
-        $this->_easyORM->setExcluded($array);
-        return $this;
-    }
-
-    /**
-     * 清除排除选项
-     *
-     * @return $this
-     */
-    final public function cleanExclude() {
-        $this->_easyORM->cleanExcluded();
-        return $this;
-    }
-    /**
-     * like([['key' => 'value'], ...]->count() like([['key' => 'value'], ...]->lists()
-     * @param $values
-     * @return Qii\Driver\Response
-     */
-    final public function like($values = array()) {
-        return $this->_easyORM->like($values);
-    }
-    /**
-     * 获取指定条件返回数据的行数
-     *
-     * @return Qii\Driver\Response
-     */
-    final public function count() {
-        return $this->_easyORM->count();
-    }
-    /**
-     * update
-     * @return Qii\Driver\Response
-     */
-    final public function update(){
-        return $this->_easyORM->update();
-    }
-    /**
-     * 删除指定数据
-     *
-     * @return Response
-     */
-    final public function remove() {
-        return $this->_easyORM->remove();
-    }
-
-    /**
-     * 更新字段,与update的区别是只验更新字段的值,不验证update设定的字段
-     *
-     * @return mixed|Response
-     */
-    final public function updateFields(){
-        return $this->_easyORM->updateFields();
-    }
-
-    /**
-     * lists
-     *
-     * @return mixed
-     */
-    final public function lists() {
-        return $this->_easyORM->lists();
-    }
-    /**
-     * 设置order by
-     * @param $orderBy
-     * @return $this
-     */
-    final public function setOrderBy($orderBy) {
-        return $this->_easyORM->setOrderBy($orderBy);
-    }
-
-    /**
-     * 分组
-     * @param array $groupBy 分组字段数组
-     * @return EasyORM
-     */
-    final public function setGroupBy($groupBy) {
-        return $this->_easyORM->setGroupBy($groupBy);
-    }
-
-    /**
-     * 清除 group by
-     * @return EasyORM
-     */
-    final public function cleanGroupBy() {
-        return $this->_easyORM->cleanGroupBy();
-    }
-    /**
-     * @return Qii\Driver\Response|mixed
-     */
-    final public function save() {
-        return $this->_easyORM->save();
-    }
-
-    /**
-     * incr 某一个字段
-     * @return mixed|Qii\Driver\Response
-     */
-    final public function incr() {
-        return $this->_easyORM->incr();
-    }
-    /**
-     * 检查数据是否已经存在,并返回一行,只能根据主键查询
-     *
-     * @return Response
-     */
-    final public function exist() {
-        return $this->_easyORM->exist();
-    }
-    /**
-     * __call 自动调用_easyORM中的方法
-     *
-     * @param string $method
-     * @param mixed $args
-     * @return mixed
-     */
-    public function __call($method, $args) {
-        return call_user_func_array(array($this->_easyORM, $method), $args);
-    }
-}

+ 0 - 845
src/Driver/EasyORM.php

@@ -1,845 +0,0 @@
-<?php
-namespace Qii\Driver;
-
-use Qii\Exceptions\InvalidParams;
-use stdClass;
-
-/**
- * 使用方法
- *
- *
- */
-final class EasyORM {
-    protected $_easyORM = array();
-
-    /**
-     * @throws InvalidParams
-     */
-    public function __construct(\Qii\Base\Rules $rules) {
-        $this->_easyORM = new stdClass();
-        $this->clean();
-        $this->cleanCondition();
-        $this->_easyORM->db = \Qii::getInstance("\Qii\Driver\Model")->db;
-        $this->setRules($rules);
-        $this->setFields($rules->fields());
-        $this->setResponse(new Response());
-    }
-
-    /**
-     * 获取db属性
-     *
-     * @return mixed
-     */
-    final public function getDB() {
-        return $this->_easyORM->db;
-    }
-
-    /**
-     * 设置验证规则
-     *
-     * @param \Qii\Base\Rules $rules
-     * @return void
-     */
-    final public function setRules(\Qii\Base\Rules $rules) {
-        $this->_easyORM->rules = $rules;
-        return $this;
-    }
-
-    /**
-     * 返回 rules
-     *
-     * @return mixed
-     */
-    final public function getRules() {
-        return $this->_easyORM->rules;
-    }
-
-    /**
-     * 设置需要操作的表名称
-     *
-     * @param string $table 表名
-     * @return mixed
-     */
-    final public function setTable($table) {
-        $this->_easyORM->rules->setTable($table);
-        return $this;
-    }
-
-    /**
-     * 获取表名
-     * 
-     * @return mixed
-     */
-    final public function getTable() {
-        return $this->_easyORM->rules->getTable();
-    }
-    /**
-     * 设置表字段
-     *
-     * @param array $fields
-     * @return void
-     * @throws
-     */
-    final public function setFields($fields = array()) {
-        if(!is_array($fields)) {
-            throw new InvalidParams("数据表字段不能为空");
-        }
-        $this->_easyORM->fields = new Fields($fields);
-        return $this;
-    }
-
-    /**
-     * 设置查询的 Fields
-     * @param array|string $fields
-     * @return $this
-     */
-    final public function setQueryFields($fields) {
-        if(!$fields) return $this;
-        if(is_array($fields)) {
-            $this->_easyORM->queryFields = join(",", $fields);
-        }else{
-            $this->_easyORM->queryFields = $fields;
-        }
-        return $this;
-    }
-
-    /**
-     * 清除 fields
-     * @return void
-     */
-    final public function cleanQueryFields() {
-        $this->_easyORM->queryFields = '*';
-        return $this;
-    }
-
-    /**
-     * @param array $args [[key, $value],...]
-     * @return EasyORM
-     */
-    final public function where($args) {
-        if(!is_array($args)) {
-            return $this;
-        }
-        $this->_easyORM->where = array();
-        foreach ($args as $key => $val) {
-            $explode = explode(":", $key)[0];
-            if($this->_easyORM->fields->hasField($explode)) {
-                $this->_easyORM->where[$key] = $val;
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * 清除where条件
-     * @return $this
-     */
-    final public function cleanWhere() {
-        $this->_easyORM->where = array();
-        return $this;
-    }
-
-    /**
-     * 清除like
-     *
-     * @return $this
-     */
-    final public function cleanLike() {
-        $this->_easyORM->like = array();
-        return $this;
-    }
-    /**
-     * 获取所有字段
-     *
-     * @return mixed
-     */
-    public function getFields() {
-        return $this->_easyORM->fields->getFields();
-    }
-
-    /**
-     * 设置表字段
-     *
-     * @param $name
-     * @param $val
-     * @return $this
-     */
-    public function __set($name, $val)
-    {
-        if($this->_easyORM->fields->hasField($name)) {
-            $this->_easyORM->fields->$name = $val;
-        } else {
-            $this->_easyORM->$name = $val;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 获取field属性
-     * @param string $name
-     * @return void
-     */
-    public function __get($name) {
-        if($this->_easyORM->fields->hasField($name)) return $this->_easyORM->fields->$name;
-        if(isset($this->_easyORM->$name)) return $this->_easyORM->$name;
-        return false;
-    }
-    /**
-     * isset
-     * @param string $name isset的key
-     * @return bool
-     */
-    public function __isset($name) {
-        if($this->_easyORM->fields->hasField($name)) return isset($this->_easyORM->fields->$name);
-        if($this->_easyORM->$name) return true;
-        return false;
-    }
-    /**
-     * unset
-     * @param  sting $name unset的key
-     * @return void
-     */
-    public function __unset($name) {
-        if(isset($this->_easyORM->fields->$name)) unset($this->_easyORM->fields->$name);
-    }
-    /**
-     * 获取字段的值
-     * @param string $field 字段名称
-     * @return mixed
-     */
-    public function getFieldValue($field) {
-        return $this->_easyORM->fields->getField($field);
-    }
-
-    /**
-     * 获取所有字段和值
-     *
-     * @return mixed
-     */
-    public function getValues() {
-        return $this->_easyORM->fields->getValues();
-    }
-
-    /**
-     * 返回所有设置的值
-     *
-     * @return mixed
-     */
-    final public function getValueAsArray() {
-        return $this->_easyORM->fields->getValueAsArray();
-    }
-    /**
-     * @param Response $response
-     * @return void
-     */
-    final public function setResponse(Response $response) {
-        $this->_easyORM->response = $response;
-        return $response;
-    }
-
-    /**
-     * @return EasyORM
-     */
-    final public function clean(){
-        $this->_easyORM->limit = array();
-        $this->_easyORM->response = null;
-        $this->_easyORM->privateKeys = array();
-        $this->_easyORM->where = array();
-        $this->_easyORM->like = array();
-        $this->_easyORM->exclude = array();
-        $this->_easyORM->orderBy = array();
-        $this->_easyORM->queryFields = '*';
-        $this->_easyORM->groupBy = array();
-        return $this;
-    }
-
-    /**
-     * 清空所有的条件和字段的值
-     *
-     * @return EasyORM
-     */
-    final public function cleanCondition() {
-        $this->cleanPrivateKey();
-        $this->cleanWhere();
-        $this->cleanLike();
-        $this->cleanLimit();
-        $this->cleanExcluded();
-        $this->cleanQueryFields();
-        $this->cleanOrderBy();
-        $this->cleanGroupBy();
-        return $this;
-    }
-
-    /**
-     * 清除所有设置了字段的值
-     *
-     * @return EasyORM
-     */
-    final public function cleanFieldsVal(){
-        $this->_easyORM->fields->cleanAllFieldsVal();
-        return $this;
-    }
-
-    /**
-     * 批量设置值
-     *
-     * @param $values
-     * @return EasyORM
-     */
-    final public function setValues($values) {
-        if(!is_array($values)) return $this;
-        foreach ($values as $key => $value) {
-            $this->_easyORM->fields->hasField($key) && $this->_easyORM->fields->$key = $value;
-        }
-        return $this;
-    }
-    /**
-     * 设置 private key,主键必须有设置值,否则不接收
-     * @param array|string $keys
-     * @return EasyORM
-     */
-    final public function setPrivateKey($keys = array())
-    {
-        if(empty($keys)) {
-            return $this;
-        }
-        if(!is_array($keys)) {
-            $this->_easyORM->fields->hasField($keys) && $this->_easyORM->privateKeys[] = $keys;
-            return $this;
-        }
-        foreach ($keys as $key) {
-            $this->_easyORM->fields->hasField($key) && $this->_easyORM->privateKeys[] = $key;
-        }
-        return $this;
-    }
-
-    /**
-     * 返回当前设置的主键
-     *
-     * @return mixed
-     */
-    final public function getPrivateKey() {
-        return $this->_easyORM->privateKeys;
-    }
-
-    /**
-     * 移除主键
-     *
-     * @param array|string $keys
-     * @return EasyORM
-     */
-    final public function removePrivateKey($keys = array()) {
-        if(!is_array(key)) {
-            if(isset($this->_easyORM->privateKeys[$keys])) unset($this->_easyORM->privateKeys[$keys]);
-            return $this;
-        }
-        foreach ($keys as $key) {
-           if(isset($this->_easyORM->privateKeys[$key])) unset($this->_easyORM->privateKeys[$key]);
-        }
-        return $this;
-    }
-    /**
-     * 获取主键对应的值
-     * @return array
-     */
-    final protected function getPrivateValue() {
-        $data = array();
-        foreach ($this->_easyORM->privateKeys AS $key) {
-            $data[$key] = $this->_easyORM->fields->getField($key);
-        }
-        return $data;
-    }
-
-    /**
-     * 清除主键
-     *
-     * @return EasyORM
-     */
-    final public function cleanPrivateKey() {
-        $this->_easyORM->privateKeys = array();
-        return $this;
-    }
-
-    /**
-     * 设置排除的数据列
-     *
-     * @param array $values 值
-     * @return EasyORM
-     */
-    final public function setExcluded($values = array()){
-        if(!is_array($values)) {
-            return $this;
-        }
-        foreach ($values as $key => $value) {
-            $this->_easyORM->fields->hasField($key) && $this->_easyORM->exclude[$key] = $value;
-        }
-        return $this;
-    }
-
-    /**
-     * 清除排除选项
-     *
-     * @return EasyORM
-     */
-    final public function cleanExcluded() {
-        $this->_easyORM->exclude = array();
-        return $this;
-    }
-
-    /**
-     * 设置limit限制
-     *
-     * @param int $start limit start
-     * @param int $size size
-     * @return EasyORM
-     */
-    final public function setLimit($start, $size = 20) {
-        $this->_easyORM->limit = [$start, $size];
-        return $this;
-    }
-
-    /**
-     * 清除limit限制
-     * @return EasyORM
-     */
-    final public function cleanLimit() {
-        $this->_easyORM->limit = array();
-        return $this;
-    }
-
-    /**
-     * @return Qii\Driver\Response|mixed
-     */
-    final public function save() {
-        $this->_easyORM->rules->addForceValidKey($this->_easyORM->rules->getValidFieldsForSave());
-        $this->_easyORM->rules->addValues($this->_easyORM->fields->getValueAsArray());
-        $verify = $this->_easyORM->rules->verify();
-        if(!$verify['valid']) {
-            return Response::FailValidate('validate', array('_result' => \Qii::i($verify['code'], $verify['msg'])
-            , 'fields' => array('field' => $verify['data'], 'message' => $verify['errorInfo']), 'message' => $verify['msg']));
-        }
-        if (($this->_easyORM->privateKeys || $this->_easyORM->exclude || $this->_easyORM->where) && $this->exist()->count() > 0) {
-            return Response::Exist('save', array('_result' => \Qii::i(1511, join(',', $this->getPrivateValue()))));
-        }
-        $map = $this->_easyORM->rules->getValues();
-        $result = $this->_easyORM->db->insertObject($this->_easyORM->rules->getTable(), $map);
-        if($this->_easyORM->db->isError()) {
-            return $this->_easyORM->db->getResponse();
-        }
-        return Response::Success('save', array('_result' => $result));
-    }
-
-    /**
-     * like([['key' => 'value'], ...]->count() like([['key' => 'value'], ...]->lists()
-     * @param $values
-     * @return EasyORM
-     */
-    final public function like($values = array()) {
-        //未指定like字段
-        if(!is_array($values)) {
-            return $this;
-        }
-        $query = array();
-        foreach ($values as $key => $value) {
-            if(!$this->_easyORM->fields->hasField($key)) {
-                continue;
-            }
-            $query[$key] = $value;
-        }
-        $this->_easyORM->like = $query;
-        return $this;
-    }
-
-    /**
-     * 获取指定条件返回数据的行数
-     *
-     * @return Qii\Driver\Response
-     */
-    final public function count() {
-        $query = $this->getValueAsArray();
-        if($this->_easyORM->where && is_array($this->_easyORM->where)) {
-            foreach ($this->_easyORM->where as $key => $value) {
-                $query[$key] = $value;
-            }
-        }
-        //字段值作为where条件, 仅list和count用
-        $value = $this->getValueAsArray();
-        foreach ($value as $key => $val) {
-            $query[$key] = $val;
-        }
-        $countFields = ' COUNT(1) as count';
-        if($this->_easyORM->queryFields != "*") {
-            $countFields = $this->_easyORM->queryFields;
-        }
-        $result = $this->_easyORM->db
-            ->fields($countFields)
-            ->limit(1)
-            ->where($query)
-            ->like($this->_easyORM->like)
-            ->exclude($this->_easyORM->exclude)
-            ->groupBy($this->_easyORM->groupBy)
-            ->selectOne($this->_easyORM->rules->getTable());
-        if ($this->_easyORM->db->isError()) {
-            return $this->_easyORM->db->getResponse();
-        }
-        return Response::Success('exist', array('_result' => $result));
-    }
-    /**
-     * 更新数据
-     *
-     * @return Qii\Driver\Response
-     */
-    final public function update() {
-        $this->_easyORM->rules->addForceValidKey($this->_easyORM->rules->getValidFieldsForUpdate());
-        $this->_easyORM->rules->addValues($this->_easyORM->fields->getValueAsArray());
-        $verify = $this->_easyORM->rules->verify();
-        if(!$verify['valid']) {
-            return Response::FailValidate('validate', array('_result' => \Qii::i($verify['code'], $verify['msg'])
-            , 'fields' => array('field' => $verify['data'], 'message' => $verify['errorInfo']), 'message' => $verify['msg']));
-        }
-        if (($this->_easyORM->privateKeys || $this->_easyORM->exclude) && $this->exist()->count() == 0) {
-            return  Response::NotExist('update', array('_result' => \Qii::i(1512, join(',', $this->getPrivateValue()))));
-        }
-        $where = $this->getWhereCondition();
-        //merge like 字段
-        if($this->_easyORM->like) {
-            $where = array_merge($this->_easyORM->like, $where);
-        }
-        $map = $this->_easyORM->rules->getValues();
-        $result = $this->_easyORM->db->updateObject($this->_easyORM->rules->getTable(), $map, $where);
-        if ($this->_easyORM->db->isError()) {
-            return $this->_easyORM->db->getResponse();
-        }
-        return Response::Success('_update', array('_result' => $result));
-    }
-
-    /**
-     * 指定字段的值 + step
-     *
-     * $attr = new EasyDrive();
-     * $attr->visit = 1;
-     * $attr->where(['uid' => 1])->incr();
-     *
-     * @return mixed|Qii\Driver\Response
-     */
-    final public function incr() {
-        $value = $this->_easyORM->fields->getValueAsArray();
-        if(!is_array($value) || count($value) == 0) {
-            return Response::FailUpdate('_incr', array('_result' => '未指定incr的key'));
-        }
-        $incrFields = array();
-        $privateKeys = $this->getPrivateKey();
-        foreach ($value as $key => $step) {
-            //去掉private的值
-            if(in_array($key, $privateKeys)) continue;
-            if($step == 0) continue;
-            if($step < 0) {
-                $incrFields[$key .":minus"] = $step * -1;
-                continue;
-            }
-            $incrFields[$key .':plus'] = $step;
-        }
-        if(count($incrFields) == 0){
-            return Response::FailUpdate('_incr', array('_result' => '未指定incr的步长'));
-        }
-        $fieldsAndValues = $this->getWhereCondition();
-        $result = $this->_easyORM->db
-            ->set($incrFields)
-            ->where($fieldsAndValues)
-            ->like($this->_easyORM->like)
-            ->exclude($this->_easyORM->exclude)
-            ->update($this->_easyORM->rules->getTable());
-
-        if ($this->_easyORM->db->isError()) {
-            return $this->_easyORM->db->getResponse();
-        }
-        return Response::Success('_incr', array('_result' => $result));
-    }
-
-    /**
-     * 更新数据只验证传过来的参数是否正确
-     *
-     * @return mixed|Qii\Driver\Response
-     */
-    final public function updateFields() {
-        $values = $this->_easyORM->fields->getValueAsArray();
-        $this->_easyORM->rules->addForceValidKey(array_keys($values));
-        $this->_easyORM->rules->addValues($values);
-        $verify = $this->_easyORM->rules->verify();
-        if(!$verify['valid']) {
-            return Response::FailValidate('validate', array('_result' => \Qii::i($verify['code'], $verify['msg'])
-            , 'fields' => array('field' => $verify['data'], 'message' => $verify['errorInfo']), 'message' => $verify['msg']));
-        }
-        if (($this->_easyORM->privateKeys || $this->_easyORM->exclude) && $this->exist()->count() == 0) {
-            return Response::NotExist('update', array('_result' => \Qii::i(1512, join(',', $this->getPrivateValue()))));
-        }
-        $where = $this->getWhereCondition();
-        //merge like 字段
-        if($this->_easyORM->like) {
-            $where = array_merge($this->_easyORM->like, $where);
-        }
-        $map = $this->_easyORM->rules->getValues();
-        $result = $this->_easyORM->db->updateObject($this->_easyORM->rules->getTable(), $map, $where);
-        if ($this->_easyORM->db->isError()) {
-            return $this->_easyORM->db->getResponse();
-        }
-        return Response::Success('_update', array('_result' => $result));
-    }
-    /**
-     * 返回所有数据
-     *
-     * @return mixed
-     */
-    final public function lists() {
-        if($this->_easyORM->limit && count($this->_easyORM->limit) > 0) {
-            $this->_easyORM->db->limit($this->_easyORM->limit[0], $this->_easyORM->limit[1]);
-        }
-        $fieldsAndValues = $this->getWhereCondition();
-        //字段值作为where条件, 仅list和count用
-        $value = $this->getValueAsArray();
-        foreach ($value as $key => $val) {
-            $fieldsAndValues[$key] = $val;
-        }
-        $result = $this->_easyORM->db
-            ->fields($this->_easyORM->queryFields)
-            ->where($fieldsAndValues)
-            ->like($this->_easyORM->like)
-            ->exclude($this->_easyORM->exclude)
-            ->groupBy($this->_easyORM->groupBy)
-            ->orderBy($this->_easyORM->orderBy)
-            ->selectRows($this->getTable());
-        if ($this->_easyORM->db->isError()) {
-            return $this->_easyORM->db->getResponse();
-        }
-        return Response::Success('lists', array('_result' => $result));
-    }
-
-    /**
-     * 设置order by
-     * @param $orderBy
-     * @return EasyORM
-     */
-    final public function setOrderBy($orderBy) {
-        if(!$orderBy) {
-            return $this;
-        }
-        //@todo 验证一下 orderBy 字段
-        if(!is_array($orderBy)) {
-            $this->_easyORM->orderBy[] = $orderBy;
-        }else{
-            $this->_easyORM->orderBy = array_merge($this->_easyORM->orderBy, $orderBy);
-        }
-        return $this;
-    }
-
-    /**
-     * 清除order by 字段
-     *
-     * @return EasyORM
-     */
-    final public function cleanOrderBy() {
-        $this->_easyORM->orderBy = array();
-        return $this;
-    }
-
-    /**
-     * 设置group by 条件
-     * @param $groupBy
-     * @return $this
-     */
-    final public function setGroupBy($groupBy = array()) {
-        if(!$groupBy) {
-            return $this;
-        }
-        $this->_easyORM->groupBy = $groupBy;
-        return $this;
-    }
-
-    /**
-     * 清除 gorup 条件
-     * @return $this
-     */
-    public function cleanGroupBy() {
-        $this->_easyORM->groupBy = array();
-        return $this;
-    }
-    /**
-     * 删除指定数据
-     *
-     * @return \Qii\Driver\Response
-     */
-    final public function remove() {
-        if(!$this->_easyORM->privateKeys &&  !$this->_easyORM->exclude && !$this->_easyORM->where) {
-            return Response::FAIL('privateKey', \Qii::i(1513));
-        }
-        $fieldsAndValues = $this->getWhereCondition();
-
-        //检查数据是否存在
-        if($this->exist()->count() == 0) {
-            return  Response::NotExist('update', array('_result' => \Qii::i(1512, join(',', $this->getPrivateValue()))));
-        }
-
-        $result = $this->_easyORM->db
-            ->where($fieldsAndValues)
-            ->like($this->_easyORM->like)
-            ->exclude($this->_easyORM->exclude)
-            ->remove($this->_easyORM->rules->getTable());
-        if ($this->_easyORM->db->isError()) {
-            return $this->_easyORM->db->getResponse();
-        }
-        return  Response::Success('remove', array('_result' => $result));
-    }
-
-    /**
-     * 检查数据是否已经存在,并返回一行,只能根据主键查询
-     * privateKey 与 exclude、where 条件互斥
-     *
-     * @return \Qii\Driver\Response
-     */
-    final public function exist() {
-        if(!$this->_easyORM->privateKeys &&  !$this->_easyORM->exclude && !$this->_easyORM->where) {
-            $this->setPrivateKey(array_keys($this->getValueAsArray()));
-        }
-        if(!$this->_easyORM->privateKeys &&  !$this->_easyORM->exclude && !$this->_easyORM->where) {
-            return Response::FAIL('privateKey', \Qii::i(1513));
-        }
-        $fieldsAndValues = $this->getWhereCondition();
-        $verify = $this->_easyORM->rules->verifyFields($fieldsAndValues);
-        if(!$verify['valid']) {
-            return Response::FailValidate('validate', array('_result' => \Qii::i($verify['code'], $verify['msg'])
-            , 'fields' => array('field' => $verify['data'], 'message' => $verify['errorInfo'])));
-        }
-
-        if($this->_easyORM->exclude) {
-            $verify = $this->_easyORM->rules->verifyFields($this->_easyORM->exclude);
-            if (!$verify['valid'])  return Response::FailValidate('validate', array('_result' => \Qii::i($verify['code'],  $verify['msg'])
-            , 'fields' => array('field' => $verify['data'], 'message' => $verify['errorInfo'])));
-        }
-        $result = $this->_easyORM->db->limit(1)
-            ->fields($this->_easyORM->queryFields)
-            ->where($fieldsAndValues)
-            ->like($this->_easyORM->like)
-            ->exclude($this->_easyORM->exclude)
-            ->orderBy($this->_easyORM->orderBy)
-            ->selectRow($this->_easyORM->rules->getTable());
-        if ($this->_easyORM->db->isError()) {
-            return $this->_easyORM->db->getResponse();
-        }
-        return Response::Success('exist', array('_result' => $result));
-    }
-
-    /**
-     * 组合where查询条件
-     *
-     * @return array
-     */
-    final public function getWhereCondition() {
-        $fieldsAndValues = $this->getPrivateValue();
-        //merge where 条件的,这里不用merge,因为merge可能会merge出一个0索引的值
-        if($this->_easyORM->where && is_array($this->_easyORM->where)) {
-            foreach ($this->_easyORM->where as $key => $value) {
-                $fieldsAndValues[$key] = $value;
-            }
-        }
-        return $fieldsAndValues;
-    }
-    /**
-     * 使用此方法用于查询某一条数据的某一个字段
-     * @useage getXxxByXxx _getXxxByxxx
-     *     _getRowById:返回所有字段; _getRowsById:通过id获取所有匹配的数据
-     *     _getRowsByFields(['user_id', 'email']) 返回所有匹配的行数据,可以带参数,带参数优先使用参数的字段查询,否则使用设置的fields查询
-     *     _getRowByFields(['user_id', 'email']) 返回匹配的一行数据,可以带参数,带参数优先使用参数的字段查询,否则使用设置的fields查询
-     *     _getRowByUserId(1) 通过user_id查询,返回所有字段
-     *     getNameById:通过id获取name的值; getEmailById:通过id获取email;
-     *     getEmailAddressByUserId 通过user_id查询email_address
-     *     getEmailByUserId(1) 通过user_id查询,返回email字段
-     * 备注:以_开头的才会去走getRow, getRows方法去取所有字段,目前仅支持All, Row, Rows这几个方法
-     * @param  string $method [description]
-     * @param  mixed $args 请求的参数
-     * @return Response
-     */
-    final public function __call($method, $args)
-    {
-        $selectType = 'normal';
-        if (substr($method, 0, 1) == '_') {
-            $selectType = 'system';
-            $method = substr($method, 1);
-        }
-        preg_match('/^(get)(.*)(By)(.*)/', $method, $matches);
-
-        if ($matches && count($matches) == 5 && $matches[1] == 'get') {
-            //大写字母匹配下划线,字段中统一用小写字母,在查询的时候使用驼峰结构
-            //如:getEmailAddressByUserId 通过user_id查询email_address
-            $field = strtolower(preg_replace('/(?<!^)([A-Z])/', '_$1', $matches[2]));
-
-            $method = 'selectRow';
-            if ($field == 'rows' && $selectType == 'system') $method = 'selectRows';
-            if ($field == 'row' && $selectType == 'system') $method = 'selectRow';
-            if (in_array($field, array('all', 'row', 'rows')) && $selectType == 'system') {
-                $field = $this->_easyORM->queryFields == '*' ? $this->getFields() : $this->_easyORM->queryFields;
-            }
-            $value = $this->_easyORM->db->setQuote(array_shift($args));
-            $name = strtolower(strtolower(preg_replace('/(?<!^)([A-Z])/', '_$1', $matches[4])));
-            $whereArray = array();
-            if ($selectType == 'system' && $name == 'fields') {
-                //优先使用参数,参数没有就使用设置的fields
-                // _getRowsByFields() 返回所有匹配的行数据,可以带参数,带参数优先使用参数的字段查询,否则使用设置的fields查询
-                // _getRowByFields() 返回匹配的一行数据,可以带参数,带参数优先使用参数的字段查询,否则使用设置的fields查询
-                if(!$value) {
-                    $value = $this->_easyORM->fields->getValues();
-                }
-                foreach ($value AS $val) {
-                    $whereArray[$val] = $this->_easyORM->fields->hasField($val) ? $this->_easyORM->fields->getField($val) : '';
-                }
-            } else {
-                $whereArray[$name] = $value;
-            }
-            $where = array();
-            foreach ($whereArray AS $key => $val) {
-                if($this->_easyORM->fields->hasField($key)) $where[$key] = $val;
-            }
-
-            $result = $this->_easyORM->db->fields($field)->where($where)->$method($this->_easyORM->rules->getTable());
-            if ($this->_easyORM->db->isError()) {
-                return $this->_easyORM->db->getResponse();
-            }
-            return Response::Success($method, array('_result' => $result));
-        }
-
-        preg_match('/^(exec)(.*)/', $method, $matches);
-
-        if ($matches && count($matches) == 3) {
-            $alias = lcfirst($matches[2]);
-            if (method_exists($this->_easyORM->db, $alias)) {
-                $result = $this->_easyORM->db->{$matches[2]}($this->_easyORM->rules->getTable(), $this->getFields());
-                if ($this->_easyORM->db->isError()) {
-                    return $this->_easyORM->db->getResponse();
-                }
-                return Response::Success($matches[2], array('_result' => $result));
-            }
-            if ($this->_easyORM->db->getAlias($method) && method_exists($this->_easyORM->db, $this->_easyORM->db->getAlias($method))) {
-                $this->_easyORM->db->whereArray($this->getFields());
-                $result = $this->_easyORM->db->{$this->_easyORM->db->getAlias($method)}($this->_easyORM->rules->getTable());
-                if ($this->_easyORM->db->isError()) {
-                    return $this->_easyORM->db->getResponse();
-                }
-                return Response::Success($this->_easyORM->db->getAlias($method), array('_result' => $result));
-            }
-        }
-        //访问方法的别名
-        if ($this->_easyORM->db->getAlias($method)) {
-            if (method_exists($this->_easyORM->db, $this->_easyORM->db->getAlias($method))) {
-                $result = call_user_func_array(array($this->_easyORM->db, $this->_easyORM->db->getAlias($method)), $args);
-                if ($this->_easyORM->db->isError()) {
-                    return $this->_easyORM->db->getResponse();
-                }
-                return Response::Success($this->_easyORM->db->getAlias($method), array('_result' => $result));
-            }
-            \Qii::setError(false, __LINE__, 1106, 'Model', 'Alias ' . $this->_easyORM->db->getAlias($method) . ' does not exist.', print_r($args, true));
-            return Response::UndefinedMethod('__call', $this->_easyORM->db->getAlias($method));
-        }
-        \Qii::setError(false, __LINE__, 1106, 'Model', $method, print_r($args, true));
-        return Response::UndefinedMethod('__call', $method);
-    }
-}

+ 6 - 3
src/Driver/Entity/Base.php

@@ -604,7 +604,7 @@ class Base {
     }
     /**
      * 返回 entity 信息
-     * @return mixed
+     * @return \Qii\Driver\Entity\Entity
      */
     public function entity() {
         return _loadClass('\Qii\Driver\Entity\Entity');
@@ -979,7 +979,7 @@ class Base {
         try{
             $query = $this->createQuery();
             $info = $query->selectRow($this->prepareTable());
-            $this->calledSQL = $query->modelSQL;
+            $this->calledSQL = $query->executeSQL;
             if($info) $this->withRow($info);
             return Response::Success(static::class .'::'. __FUNCTION__,
                 [
@@ -1500,7 +1500,7 @@ class Base {
         }
         $query = $this->createQuery();
         $row = $query->groupBy($this->getGroupBy())->orderBy($orderBy)->limit(1)->selectRow($this->prepareTable());
-        $this->calledSQL = $query->modelSQL;
+        $this->calledSQL = $query->executeSQL;
         if($this->db()->isError()) {
             return Response::Fail(static::class .'::'. __FUNCTION__,
                 [
@@ -1654,6 +1654,9 @@ class Base {
                     $rel[] = $v1[$foreignKey];
                 }
             }
+            if(count($rel) == 0) {
+                return;
+            }
             // [rel key, where]
             $params = [
                 $associationForeignkey,

+ 49 - 52
src/Driver/TraitCache.php → src/Driver/Trait/Cache.php

@@ -1,53 +1,50 @@
-<?php
-namespace Qii\Driver;
-
-use Qii\Autoloader\Import;
-use Qii\Autoloader\Psr4;
-
-trait TraitCache
-{
-    public $cache;
-    /**
-     * 设置Cache
-     *
-     * @param String $cache
-     * @param Array $policy
-     */
-    final public function setCache($cache, $policy)
-    {
-        $this->cache = \Qii::getInstance()->setCache($cache, $policy);
-        return $this->cache;
-    }
-
-    /**
-     * 缓存内容
-     *
-     * @param String $id
-     * @param Array $value
-     * @param array $policy ['life_time' => 过期时间]
-     * @return Bool
-     */
-    final public function cache($id, $value, $policy = array())
-    {
-        return $this->cache->set($id, $value, $policy);
-    }
-
-    /**
-     * 获取缓存的类
-     */
-    final public function getCache()
-    {
-        return $this->cache;
-    }
-
-    /**
-     * 获取缓存内容
-     *
-     * @param String $id
-     * @return Array
-     */
-    final public function getCacheData($id)
-    {
-        return $this->cache->get($id);
-    }
+<?php
+namespace Qii\Driver\Trait;
+
+trait Cache
+{
+    public $traitCache;
+    /**
+     * 设置Cache
+     *
+     * @param String $cache
+     * @param Array $policy
+     */
+    final public function setCache($cache, $policy)
+    {
+        $this->traitCache = \Qii::getInstance()->setCache($cache, $policy);
+        return $this->traitCache;
+    }
+
+    /**
+     * 缓存内容
+     *
+     * @param String $id
+     * @param Array $value
+     * @param array $policy ['life_time' => 过期时间]
+     * @return Bool
+     */
+    final public function cache($id, $value, $policy = array())
+    {
+        return $this->traitCache->set($id, $value, $policy);
+    }
+
+    /**
+     * 获取缓存的类
+     */
+    final public function getCache()
+    {
+        return $this->traitCache;
+    }
+
+    /**
+     * 获取缓存内容
+     *
+     * @param String $id
+     * @return Array
+     */
+    final public function getCacheData($id)
+    {
+        return $this->traitCache->get($id);
+    }
 }

+ 374 - 374
src/Driver/TraitDatabase.php → src/Driver/Trait/Database.php

@@ -1,375 +1,375 @@
-<?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 数据库名称
-     * @return array
-     */
-    public function getTableIndex($table, $database = null) {
-        if (!$database) $database = $this->currentDB;
-        $sql = 'SHOW INDEX FROM '. $database .'.'. $table;
-        $rs = $this->setQuery($sql);
-        $index = array();
-        //Non_unique 0 是唯一 或主键 (0 + Key_name=(PRIMARY))  1 是索引
-        while ($row = $rs->fetch()) {
-            if($row['Key_name'] == 'PRIMARY') {
-                $index['PRIMARY'][] = $row['Column_name'];
-                continue;
-            }
-            if($row['Non_unique'] == '0') {
-                $index['UNIQUE'][$row['Key_name']][] = $row['Column_name'];
-                continue;
-            }
-            $index['INDEX'][$row['Key_name']][] = $row['Column_name'];
-        }
-        return $index;
-    }
-
-    /**
-     * 获取表的备注
-     *
-     * @param string $table 表名
-     * @param string $database 数据库名称
-     * @return array|mixed
-     */
-    public function getTableComment($table = '', $database = null) {
-        if (!$database) $database = $this->currentDB;
-        $sql = "
-                    SELECT TABLE_NAME AS table_name, TABLE_COMMENT AS comment
-                    FROM INFORMATION_SCHEMA.TABLES 
-                    WHERE TABLE_SCHEMA = '{$database}'";
-        if($table != '') {
-            $sql .= " AND TABLE_NAME = '{$table}'";
-        }
-
-        $rs = $this->setQuery($sql);
-        $comment = array();
-        while ($row = $rs->fetch()) {
-            $comment[$row['table_name']] = $row['comment'];
-        }
-
-        if($table != '' && isset($comment[$table])) {
-            return $comment[$table];
-        }
-        return $comment;
-    }
-    /**
-     * 获取指定数据表的所有字段
-     * @param string $table 表名
-     * @param string $database 数据库名
-     * @param string $autoIncr 自动增长的序号
-     * @return array
-     */
-    public function getTableInfo($table, $database = null, $autoIncr = null)
-    {
-        static $tableInfo;
-        if(isset($tableInfo[$table])) {
-            return $tableInfo[$table];
-        }
-        if (!$database) $database = $this->currentDB;
-        $sql = "SELECT * from information_schema.COLUMNS where table_name = '" . $table . "' and table_schema = '" . $database . "' ORDER BY ORDINAL_POSITION ASC";
-        $data = array(
-            'table' => $table,
-            'fields' => array(),
-            'fields_type' => array(),
-            'rules' => array(
-                'pri' => array(),
-                'required' => array()
-            )
-        );
-        $rs = $this->setQuery($sql);
-        $maxRange = [
-            'bigint' => [-1 * pow(2, 63), pow(2, 63)-1],
-            'int' => [-1 * pow(2, 31), pow(2, 31)-1],
-            'mediumint' => [-8388608, 8388607],
-            'smallint' => [-1 * pow(2, 15), pow(2, 15)-1],
-            'tinyint' => [-128, 127],
-            'integer' => [-1 * pow(2, 31), pow(2, 31)-1]
-        ];
-        $data['type'] = [];
-        while ($row = $rs->fetch()) {
-            $data['fields'][] = $row['COLUMN_NAME'];
-            $data['type'][$row['DATA_TYPE']][] = $row['COLUMN_NAME'];
-            $fieldsType = array();
-            $fieldsType['name'] = $row['COLUMN_NAME'];
-            $fieldsType['type'] = strtolower($row['DATA_TYPE']);
-            $fieldsType['is_pri'] = false;
-            $fieldsType['is_uni'] = false;
-            $fieldsType['is_null'] = true;
-            $fieldsType['is_number'] = false;
-            $fieldsType['is_float'] = false;
-            $fieldsType['is_decimal'] = false;
-            $fieldsType['is_timestamp'] = false;
-            $fieldsType['is_set'] = false;
-            $fieldsType['default'] = false;
-            $fieldsType['comment'] = '';
-            if ($row['EXTRA']) {
-                $data['rules']['extra'][$row['EXTRA']][] = $row['COLUMN_NAME'];
-                $fieldsType['extra'] = $row['EXTRA'];
-            }
-            if ($row['COLUMN_KEY'] == 'PRI') {
-                $data['rules']['pri'][] = $row['COLUMN_NAME'];
-                $data['rules']['required'][] = $row['COLUMN_NAME'];
-                $fieldsType['is_pri'] = true;
-            } else if($row['COLUMN_KEY'] == 'UNI'){
-                //$data['rules']['uni'][] = $row['COLUMN_NAME'];
-                $data['rules']['required'][] = $row['COLUMN_NAME'];
-                $fieldsType['is_uni'] = true;
-            }else if ($row['IS_NULLABLE'] == 'NO') {
-                $data['rules']['required'][] = $row['COLUMN_NAME'];
-                $fieldsType['is_null'] = false;
-            }
-            if (in_array($row['DATA_TYPE'], array('varchar', 'char'))) {
-                $data['rules']['maxlength'][$row['COLUMN_NAME']] = $row['CHARACTER_MAXIMUM_LENGTH'];
-                $fieldsType['maxlength'] = $row['CHARACTER_MAXIMUM_LENGTH'];
-            }
-            if (in_array($row['DATA_TYPE'], array('mediumtext', 'tinytext', 'text', 'longtext'))) {
-                $data['rules']['text'][] = $row['COLUMN_NAME'];
-            }
-            if (in_array($row['DATA_TYPE'], array('bigint', 'int', 'mediumint', 'smallint', 'tinyint', 'integer'))) {
-                preg_match('/[\d]{0,}/', $row['COLUMN_TYPE'], $matches);
-                if(!empty($matches)) {
-                    $data['rules']['int'][$row['COLUMN_NAME']] = isset($matches[0]) && $matches[0] ? $matches[0] : $maxRange[$row['DATA_TYPE']];
-                    $data['rules']['number'][] = $row['COLUMN_NAME'];
-                    $fieldsType['is_number'] = true;
-                }
-            }
-            if (in_array($row['DATA_TYPE'], array('float', 'double'))) {
-                $data['rules']['float'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
-                $fieldsType['is_float'] = true;
-            }
-            if (in_array($row['DATA_TYPE'], array('decimal'))) {
-                $data['rules']['decimal'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
-                $fieldsType['is_decimal'] = true;
-            }
-            if (in_array($row['DATA_TYPE'], array('timestamp', 'datetime'))) {
-                $data['rules']['timestamp'][] = $row['COLUMN_NAME'];
-                $fieldsType['is_timestamp'] = true;
-            }
-            if (in_array($row['DATA_TYPE'], array('enum', 'set'))) {
-                $data['rules']['sets'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
-                $fieldsType['is_set'] = true;
-            }
-            if (isset($row['COLUMN_DEFAULT'])) {
-                $data['rules']['default'][$row['COLUMN_NAME']] = $row['COLUMN_DEFAULT'];
-                $fieldsType['default'] = $row['COLUMN_DEFAULT'];
-            }
-            if(isset($row['COLUMN_COMMENT'])) {
-                $data['comment'][$row['COLUMN_NAME']] = $row['COLUMN_COMMENT'];
-                $fieldsType['comment'] = $row['COLUMN_COMMENT'];
-            }
-            $data['fields_type'][$row['COLUMN_NAME']] = $fieldsType;
-        }
-
-        $sql = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE table_name = '" . $table . "'";
-        $rs = $this->setQuery($sql);
-        $data['sql'] = $this->getTableSQL($table, $database, $autoIncr);
-        preg_match_all("/UNIQUE\sKEY\s`(.*?)`\s\(`(.*?)`\)/", $data['sql'], $matches);
-        $uniqKeys = [];
-        if(count($matches) == 3) {
-            foreach ($matches[2] as $key => $match) {
-                //$uniqKeys[$matches[1][$key]] = explode("`,`", $match);
-                $arr = explode("`,`", $match);
-                if(count($arr) > 0)  $uniqKeys[] = join(',', $arr);
-            }
-        }
-        if(count($uniqKeys) > 0) {
-            $data['rules']['uniq'] = $uniqKeys;
-        }
-        $tableInfo[$table] = $data;
-        return $data;
-    }
-
-    /**
-     * 从括号中获取指定的值
-     * @param string $str 需要获取的内容
-     * @return array
-     */
-    public function getValueFromBrackets($str)
-    {
-        preg_match("/(?:\()(.*)(?:\))/i", $str, $matches);
-        if(!$matches) {
-            return $str;
-        }
-        $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)
-    {
-        //去掉表名及数据库名的`符号,重新添加,避免重复
-        $table = str_replace("`", '', $table);
-        list($database, $tableName) = array_pad(explode('.', $table), 2, '');
-        if ($tableName) {
-            return "`{$database}`.`{$tableName}`";
-        }
-        return '`'. $table .'`';
-    }
+<?php
+namespace Qii\Driver\Trait;
+
+trait Database
+{
+
+    /**
+     * 获取数据库中所有的数据表
+     * @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 数据库名称
+     * @return array
+     */
+    public function getTableIndex($table, $database = null) {
+        if (!$database) $database = $this->currentDB;
+        $sql = 'SHOW INDEX FROM '. $database .'.'. $table;
+        $rs = $this->setQuery($sql);
+        $index = array();
+        //Non_unique 0 是唯一 或主键 (0 + Key_name=(PRIMARY))  1 是索引
+        while ($row = $rs->fetch()) {
+            if($row['Key_name'] == 'PRIMARY') {
+                $index['PRIMARY'][] = $row['Column_name'];
+                continue;
+            }
+            if($row['Non_unique'] == '0') {
+                $index['UNIQUE'][$row['Key_name']][] = $row['Column_name'];
+                continue;
+            }
+            $index['INDEX'][$row['Key_name']][] = $row['Column_name'];
+        }
+        return $index;
+    }
+
+    /**
+     * 获取表的备注
+     *
+     * @param string $table 表名
+     * @param string $database 数据库名称
+     * @return array|mixed
+     */
+    public function getTableComment($table = '', $database = null) {
+        if (!$database) $database = $this->currentDB;
+        $sql = "
+                    SELECT TABLE_NAME AS table_name, TABLE_COMMENT AS comment
+                    FROM INFORMATION_SCHEMA.TABLES 
+                    WHERE TABLE_SCHEMA = '{$database}'";
+        if($table != '') {
+            $sql .= " AND TABLE_NAME = '{$table}'";
+        }
+
+        $rs = $this->setQuery($sql);
+        $comment = array();
+        while ($row = $rs->fetch()) {
+            $comment[$row['table_name']] = $row['comment'];
+        }
+
+        if($table != '' && isset($comment[$table])) {
+            return $comment[$table];
+        }
+        return $comment;
+    }
+    /**
+     * 获取指定数据表的所有字段
+     * @param string $table 表名
+     * @param string $database 数据库名
+     * @param string $autoIncr 自动增长的序号
+     * @return array
+     */
+    public function getTableInfo($table, $database = null, $autoIncr = null)
+    {
+        static $tableInfo;
+        if(isset($tableInfo[$table])) {
+            return $tableInfo[$table];
+        }
+        if (!$database) $database = $this->currentDB;
+        $sql = "SELECT * from information_schema.COLUMNS where table_name = '" . $table . "' and table_schema = '" . $database . "' ORDER BY ORDINAL_POSITION ASC";
+        $data = array(
+            'table' => $table,
+            'fields' => array(),
+            'fields_type' => array(),
+            'rules' => array(
+                'pri' => array(),
+                'required' => array()
+            )
+        );
+        $rs = $this->setQuery($sql);
+        $maxRange = [
+            'bigint' => [-1 * pow(2, 63), pow(2, 63)-1],
+            'int' => [-1 * pow(2, 31), pow(2, 31)-1],
+            'mediumint' => [-8388608, 8388607],
+            'smallint' => [-1 * pow(2, 15), pow(2, 15)-1],
+            'tinyint' => [-128, 127],
+            'integer' => [-1 * pow(2, 31), pow(2, 31)-1]
+        ];
+        $data['type'] = [];
+        while ($row = $rs->fetch()) {
+            $data['fields'][] = $row['COLUMN_NAME'];
+            $data['type'][$row['DATA_TYPE']][] = $row['COLUMN_NAME'];
+            $fieldsType = array();
+            $fieldsType['name'] = $row['COLUMN_NAME'];
+            $fieldsType['type'] = strtolower($row['DATA_TYPE']);
+            $fieldsType['is_pri'] = false;
+            $fieldsType['is_uni'] = false;
+            $fieldsType['is_null'] = true;
+            $fieldsType['is_number'] = false;
+            $fieldsType['is_float'] = false;
+            $fieldsType['is_decimal'] = false;
+            $fieldsType['is_timestamp'] = false;
+            $fieldsType['is_set'] = false;
+            $fieldsType['default'] = false;
+            $fieldsType['comment'] = '';
+            if ($row['EXTRA']) {
+                $data['rules']['extra'][$row['EXTRA']][] = $row['COLUMN_NAME'];
+                $fieldsType['extra'] = $row['EXTRA'];
+            }
+            if ($row['COLUMN_KEY'] == 'PRI') {
+                $data['rules']['pri'][] = $row['COLUMN_NAME'];
+                $data['rules']['required'][] = $row['COLUMN_NAME'];
+                $fieldsType['is_pri'] = true;
+            } else if($row['COLUMN_KEY'] == 'UNI'){
+                //$data['rules']['uni'][] = $row['COLUMN_NAME'];
+                $data['rules']['required'][] = $row['COLUMN_NAME'];
+                $fieldsType['is_uni'] = true;
+            }else if ($row['IS_NULLABLE'] == 'NO') {
+                $data['rules']['required'][] = $row['COLUMN_NAME'];
+                $fieldsType['is_null'] = false;
+            }
+            if (in_array($row['DATA_TYPE'], array('varchar', 'char'))) {
+                $data['rules']['maxlength'][$row['COLUMN_NAME']] = $row['CHARACTER_MAXIMUM_LENGTH'];
+                $fieldsType['maxlength'] = $row['CHARACTER_MAXIMUM_LENGTH'];
+            }
+            if (in_array($row['DATA_TYPE'], array('mediumtext', 'tinytext', 'text', 'longtext'))) {
+                $data['rules']['text'][] = $row['COLUMN_NAME'];
+            }
+            if (in_array($row['DATA_TYPE'], array('bigint', 'int', 'mediumint', 'smallint', 'tinyint', 'integer'))) {
+                preg_match('/[\d]{0,}/', $row['COLUMN_TYPE'], $matches);
+                if(!empty($matches)) {
+                    $data['rules']['int'][$row['COLUMN_NAME']] = isset($matches[0]) && $matches[0] ? $matches[0] : $maxRange[$row['DATA_TYPE']];
+                    $data['rules']['number'][] = $row['COLUMN_NAME'];
+                    $fieldsType['is_number'] = true;
+                }
+            }
+            if (in_array($row['DATA_TYPE'], array('float', 'double'))) {
+                $data['rules']['float'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
+                $fieldsType['is_float'] = true;
+            }
+            if (in_array($row['DATA_TYPE'], array('decimal'))) {
+                $data['rules']['decimal'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
+                $fieldsType['is_decimal'] = true;
+            }
+            if (in_array($row['DATA_TYPE'], array('timestamp', 'datetime'))) {
+                $data['rules']['timestamp'][] = $row['COLUMN_NAME'];
+                $fieldsType['is_timestamp'] = true;
+            }
+            if (in_array($row['DATA_TYPE'], array('enum', 'set'))) {
+                $data['rules']['sets'][$row['COLUMN_NAME']] = $this->getValueFromBrackets($row['COLUMN_TYPE']);
+                $fieldsType['is_set'] = true;
+            }
+            if (isset($row['COLUMN_DEFAULT'])) {
+                $data['rules']['default'][$row['COLUMN_NAME']] = $row['COLUMN_DEFAULT'];
+                $fieldsType['default'] = $row['COLUMN_DEFAULT'];
+            }
+            if(isset($row['COLUMN_COMMENT'])) {
+                $data['comment'][$row['COLUMN_NAME']] = $row['COLUMN_COMMENT'];
+                $fieldsType['comment'] = $row['COLUMN_COMMENT'];
+            }
+            $data['fields_type'][$row['COLUMN_NAME']] = $fieldsType;
+        }
+
+        $sql = "SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE table_name = '" . $table . "'";
+        $rs = $this->setQuery($sql);
+        $data['sql'] = $this->getTableSQL($table, $database, $autoIncr);
+        preg_match_all("/UNIQUE\sKEY\s`(.*?)`\s\(`(.*?)`\)/", $data['sql'], $matches);
+        $uniqKeys = [];
+        if(count($matches) == 3) {
+            foreach ($matches[2] as $key => $match) {
+                //$uniqKeys[$matches[1][$key]] = explode("`,`", $match);
+                $arr = explode("`,`", $match);
+                if(count($arr) > 0)  $uniqKeys[] = join(',', $arr);
+            }
+        }
+        if(count($uniqKeys) > 0) {
+            $data['rules']['uniq'] = $uniqKeys;
+        }
+        $tableInfo[$table] = $data;
+        return $data;
+    }
+
+    /**
+     * 从括号中获取指定的值
+     * @param string $str 需要获取的内容
+     * @return array
+     */
+    public function getValueFromBrackets($str)
+    {
+        preg_match("/(?:\()(.*)(?:\))/i", $str, $matches);
+        if(!$matches) {
+            return $str;
+        }
+        $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)
+    {
+        //去掉表名及数据库名的`符号,重新添加,避免重复
+        $table = str_replace("`", '', $table);
+        list($database, $tableName) = array_pad(explode('.', $table), 2, '');
+        if ($tableName) {
+            return "`{$database}`.`{$tableName}`";
+        }
+        return '`'. $table .'`';
+    }
 }

+ 908 - 0
src/Driver/Trait/SQL.php

@@ -0,0 +1,908 @@
+<?php
+namespace Qii\Driver\Trait;
+
+use admin\api\office\actions\lists;
+use Qii\Exceptions\InvalidParams;
+use Qii\Exceptions\TableException;
+
+const JOINTYPE = [
+    'LEFTJOIN' => 'LEFT JOIN',
+    'RIGHTJOIN' => 'RIGHT JOIN',
+    'INNERJOIN' => 'INNER JOIN',
+    'OUTERJOIN' => 'OUTER JOIN',
+    'FULLOUTERJOIN' => 'FULL OUTER JOIN',
+    'LEFTOUTERJOIN' => 'LEFT OUTER JOIN',
+    'RIGHTOUTERJOIN' => 'RIGHT OUTER JOIN'
+];
+trait SQL
+{
+
+    private $operator = ['and', 'or'];
+    /**
+     * sql
+     * @var string[]
+     */
+    private $query = array(
+        "INSERT" => "INSERT INTO %s(%s) VALUES(%s)",
+        "REPLACE" => "REPLACE INTO %s (%s) VALUES(%s)",
+        "SELECT" => "SELECT %s FROM %s %s",
+        "UPDATE" => "UPDATE %s SET %s",
+        "DELETE" => "DELETE FROM %s %s",
+        "WHERE" => " WHERE %s",
+        "OR" => " `%s` = '%s' ",
+        "ORDER" => " ORDER BY %s",
+        "GROUP" => " GROUP BY %s",
+        "LIMIT" => " LIMIT %d, %d",
+        "HAVING" => " HAVING %s",
+        "BETWEEN" => " BETWEEN %s AND %s",
+    );
+    private $condition = ['eq', 'neq', 'gt', 'lt', 'gte', 'lte', 'in', 'between', 'like', 'llike', 'rlike'];
+    private $conditionFormatter = [
+        'eq' => "%s = '%s'",
+        'neq' => "%s != '%s'",
+        'gt' => "%s > '%s'",
+        'lt' => "%s < '%s'",
+        'gte' => "%s >= '%s'",
+        'lte' => "%s <= '%s'",
+        'in' => "%s IN (%s)",
+        'between' => "%s BETWEEN %s AND %s",
+        'like' => "%s LIKE '%%%s%%'",
+        'llike' => "%s LIKE '%%%s'",
+        'rlike' => "%s LIKE '%s%%'",
+    ];
+    /**
+     * sql执行的时间
+     *
+     * @var array
+     */
+    private $timer = [];
+    /**
+     * 执行的sql语句
+     * @var array
+     */
+    private $sql = [];
+
+    /**
+     * 查询字段
+     * @var array|string $fields
+     */
+    private $fields = null;
+    /**
+     * join
+     * @var string|null string
+     */
+    private $join = null;
+
+    /**
+     * where
+     * @var string | null $where
+     */
+    private $where = null;
+
+    /**
+     * group by
+     * @var string|null $group
+     */
+    private $group = null;
+    /**
+     * order
+     * @var string|null $order
+     */
+    private $order = null;
+    /**
+     * having
+     * @var string|null
+     */
+    private $having = null;
+
+    private $limit = null;
+
+    private $sets = null;
+    /**
+     * 查询的表名
+     *
+     * @var null $table 表名
+     */
+    private $table = null;
+    /**
+     * 执行的SQL及耗时
+     *
+     * @var array [{sql:'xxx', start:1723232121.111, end: 1723232121.112, cost:0.001}]
+     */
+    private $executionSQL = [];
+
+    final public function clean(){
+        $this->sql = [];
+        $this->fields = null;
+        $this->join = null;
+        $this->where = null;
+        $this->group = null;
+        $this->order = null;
+        $this->having = null;
+        $this->limit = null;
+        $this->sets = null;
+        $this->table = null;
+    }
+
+    /**
+     * 查询字段
+     *
+     * @param mixed $fields
+     * @return $this
+     */
+    final public function fields($fields) {
+        if(!is_string($fields) && !is_array($fields)) {
+            return $this;
+        }
+        if($fields == '*') {
+            $this->fields = null;
+        }
+
+        if(!is_array($fields)) {
+            if(preg_match('/(COUNT|SUM)\((.*)\)/', $fields)) {
+                $this->fields = $fields;
+                return $this;
+            }
+            // 如果是统计SQL,就只要统计相关字段
+            $this->fields = $this->fields == null ? $fields : $this->fields . ', ' . $fields;
+            return $this;
+        }
+
+        if(preg_match('/(COUNT|SUM)\((.*)\)/', $this->fields)) {
+            return $this;
+        }
+        $arr = [];
+        foreach($fields as $field) {
+            // 处理 ['table1.field', 'table2.field']
+            $tmp = explode('.', $field);
+            if(count($tmp) == 2) {
+                if($tmp[1] == '*') {
+                    $arr[] = $tmp[0]. '.'.$tmp[1];
+                }else{
+                    $arr[] = $tmp[0]. '.`'.$tmp[1].'`';
+                }
+            }else{
+                if($field == '*'){
+                    $arr[] = $field;
+                }else{
+                    $arr[] = '`'.$field.'`';
+                }
+            }
+        }
+        $this->fields = $this->fields != null ? $this->fields .' , '. join(', ',$arr) : join(' , ',$arr);
+        return $this;
+    }
+
+    /**
+     * sql执行的开始时间
+     *
+     * @param string $sql 执行的sql
+     * @return void
+     */
+    final public function startTime($sql){
+        $this->executionSQL[] = [
+            'sql' => $sql,
+            'start' => microtime(true)
+        ];
+    }
+
+    /**
+     * sql执行结束记录结束时间
+     *
+     * @param $sql
+     * @return void
+     */
+    final public function endTime($sql) {
+        $sqls = array_column($this->executionSQL, 'sql');
+        $index = array_search($sql, $sqls);
+        if($index === false) {
+            return;
+        }
+        $item = $this->executionSQL[$index];
+        $item['end'] = microtime(true);
+        $item['cost'] = sprintf('%.04f', $item['end'] - $item['start']) ;
+        $this->executionSQL[$index] = $item;
+    }
+
+    /**
+     * 过滤值
+     *
+     * @param string|array $word
+     * @return array|string
+     * @throws InvalidParams
+     */
+    final function setQuote($word)
+    {
+        if (ini_get("magic_quotes_gpc")) {
+            return $word;
+        }
+        $this->handleError(in_array(gettype($word), array("object", "resource","resource (closed)")), '期待参数为数组或字符串,获取到的是:'. gettype($word)."(". json_encode($word) .")");
+        return is_array($word) ? array_map('addslashes', $word) : addslashes($word);
+    }
+
+    /**
+     * 处理 table.field 这种形式的字段
+     *
+     * @param string $field 字段名
+     * @return mixed|string
+     */
+    private function handleFieldAlias($field) {
+        if(!stristr($field, '.')) {
+            if(!stristr($field, '`')) {
+                return '`' . $field. '`';
+            }
+            return $field;
+        }
+        $tmp = explode('.', $field);
+        if(count($tmp) != 2) {
+            return $field;
+        }
+        return $tmp[0] . '.`' . $tmp[1] . '`';
+    }
+
+    /**
+     * 处理字段及值 field1:field2:field2:field4:eq|neq|gt... val
+     * field1 eq val or field2 eq val ....
+     * @param $field
+     * @param $val
+     * @return string
+     * @throws \Exception
+     */
+    private function handleWhereField($field, $val) {
+        $this->handleError(!$field, '字段名不能为空');
+        $tmp = explode(':', $field);
+        if(count($tmp) == 1) {
+            return sprintf($this->conditionFormatter['eq'], $this->handleFieldAlias($field), $this->setQuote($val));
+        }
+        $cond = array_pop($tmp);
+        if(!in_array($cond, $this->condition)) {
+            $tmp[] = $cond;
+            $cond = 'eq';
+        }
+        $arr = [];
+        foreach($tmp as $v) {
+            $cond = strtolower($cond);
+            if(!isset($this->conditionFormatter[$cond])) {
+                continue;
+            }
+            $this->handleError($cond == 'between' && !is_array($val), 'BETWEEN的值必须为数组格式[a,b]');
+            if($cond == 'between') {
+                $arr[] = sprintf($this->conditionFormatter[$cond], $this->handleFieldAlias($v), "'". $this->setQuote($val[0]) . "'", "'". $this->setQuote($val[1]) ."'");
+                continue;
+            }
+            if($cond == 'in' && is_array($val)) {
+                $arr[] = sprintf($this->conditionFormatter[$cond], $this->handleFieldAlias($v), "'". join("', '", $this->setQuote($val)) . "'");
+                continue;
+            }
+            if(is_array($val)) {
+                throw new \Exception('eq|neq|gt|gte|lt|lte|like值不能为数组');
+            }
+            $arr[] = sprintf($this->conditionFormatter[$cond], $this->handleFieldAlias($v), $this->setQuote($val));
+        }
+        return '('. join(' OR ', $arr) . ')';
+    }
+
+    /**
+     * @param $where
+     * @return mixed
+     * @throws \Exception
+     */
+    private function handleSubWhere($where) {
+        $arr = [];
+
+        $count = count($where);
+        // 多维数组处理
+        if(count($where, 1) > $count) {
+            foreach($where as $k => $v) {
+                if(is_numeric($k) && is_array($v)) {
+                    $arr[] = "(". join(" ", $this->handleSubWhere($v)) . ")";
+                    $arr[] = 'AND';
+                    continue;
+                }
+                if(is_numeric($k) && is_string($v) && in_array(strtolower($v), $this->operator)) {
+                    if(in_array(strtolower($arr[count($arr) - 1]), $this->operator)) {
+                        $arr[count($arr) - 1] = strtoupper($v);
+                        continue;
+                    }
+                    $arr[] = strtoupper($v);
+                    continue;
+                }
+                $arr[]  = $this->handleWhereField($k, $v);
+                $arr[] = 'AND';
+            }
+            if($arr[count($arr) - 1] == 'AND') {
+                array_pop($arr);
+            }
+            return $arr;
+        }
+
+        $lastIsOperator = false;
+        foreach($where as $key => $val) {
+            if(is_numeric($key) && is_string($val) && in_array(strtolower($val), $this->operator)) {
+                $arr[] = strtoupper($val);
+                $lastIsOperator = true;
+                continue;
+            }
+            if(!$lastIsOperator && count($arr) > 0) {
+                $arr[] = 'AND';
+            }
+            $lastIsOperator = false;
+            $arr[] = $this->handleWhereField($key, $val);
+        }
+        return $arr;
+    }
+
+    /**
+     * 支持复杂的where条件
+     * field1 = '' and field2= ''
+     * ['field1' => '', 'field2' => '']
+     * ['field1' => '', 'and', 'field2' => '']
+     * ['field1'  => '', 'or', 'field2' => ''] ['field3' => '']
+     * [['field1'  => '', 'and', 'field2' => ''], 'or', ['field3' => '']]
+     *
+     * 当同时执行 where()->or() 的时候 where条件会整个括起来, 再通过or与or()相连
+     *
+     * 数组中field 支持
+     * ['field1:eq|ueq|like|gt|gte|lt|lte|between|in' => val]
+     * ['field1:field2|field3...:eq|neq|like|gt|gte|lt|lte|between|in' => val] 多字段or的形式
+     *
+     * @param string|array $where
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function where($where) {
+        $this->handleError(!is_array($where) && !is_string($where), '查询条件不能必须为字符串或数组');
+        if(!is_array($where)) {
+            $this->where = $this->where != null ? ($this->where) . ' AND '. $where : $where;
+            return $this;
+        }
+        if(count($where) == 0) {
+            return $this;
+        }
+        $arr = $this->handleSubWhere($where);
+        $sub = '('. join(' ', $arr) . ')';
+        $this->where = $this->where != null ? $this->where . ' AND '. $sub : $sub;
+        return $this;
+    }
+
+    /**
+     * or 条件
+     * @param $or
+     * @return $this
+     * @throws \Exception
+     */
+    final public function or($or){
+        if(!$or)  {
+            return $this;
+        }
+        if(is_string($or)) {
+            $this->where = $this->where != null ? $this->where . ' OR ('. $or . ')' : $or;
+            return $this;
+        }
+        $arr = $this->handleSubWhere($or);
+        $sub = '('. join(' ', $arr) . ')';
+        $this->where = $this->where != null ? '('. $this->where . ') OR '. $sub : $sub;
+        return $this;
+    }
+
+    /**
+     * @param $and
+     * @return $this
+     */
+    final public function and($and){
+        return $this->where($and);
+    }
+
+    /**
+     * like %keyword%
+     * @param $like
+     * @param string $type like/llike/rlike
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function like($like, $type = 'like'){
+        $this->handleError(!in_array($type, array('like', 'llike', 'rlike')), 'LIKE 只接受like/llike/rlike');
+        if(!is_array($like)) {
+            $this->where = $this->where != null ? '('. $this->where . ') AND '. $like : $like;
+        }
+        $arr = [];
+        foreach($like as $key => $val) {
+            $arr[$key .':'. $type] = $val;
+        }
+
+        return $this->where($arr);
+    }
+
+    /**
+     * llike %keyword
+     * @param $like
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function llike($like){
+        return $this->like($like, 'llike');
+    }
+
+    /**
+     * rlike %keyword
+     * @param $like
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function rlike($like){
+        return $this->like($like, 'rlike');
+    }
+
+    /**
+     * @param $group
+     * @return $this
+     */
+    final public function group($group){
+        $this->handleError(!is_array($group) && !is_string($group), 'group by 参数必须为字符串或数组');
+        if(is_string($group)) {
+            $this->group = $this->group != null ? $this->group . ', '. $group : sprintf($this->query['GROUP'], $group);
+            return $this;
+        }
+        if(count($group) == 0) {
+            return $this;
+        }
+        $this->group = $this->group != null ? $this->group . ', '. join(", ", $group) : sprintf($this->query['GROUP'], join(", ", $group));
+        return $this;
+    }
+
+    /**
+     * @param $order
+     * @return $this
+     */
+    final public function order($order){
+        $this->handleError(!is_array($order) && !is_string($order), 'order 参数必须为字符串或数组, 获取到的是'. gettype($order));
+
+        if((is_array($order) && count($order) == 0) || preg_match('/(COUNT|SUM)\((.*)\)/', $this->fields)) {
+            return $this;
+        }
+
+        if(is_string($order)) {
+            $this->order = $this->order == null ? sprintf($this->query['ORDER'], $order) : $this->order . ','. $order;
+            return $this;
+        }
+        $arr = [];
+        foreach($order as $key => $val) {
+            $arr[] = $key .' '. $val;
+        }
+        $this->order = $this->order == null ? sprintf($this->query['ORDER'], join( ',', $arr)) : $this->order . ', '. join( ',', $arr);
+        return $this;
+    }
+    /**
+     * @param $table
+     * @param string|array $on
+     * @param string $joinType LEFT JOIN / RIGHT JOIN / INNER JOIN
+     * @return $this
+     */
+    final public function join($table, $on, $joinType = JOINTYPE['LEFTJOIN']){
+        $arr = [];
+        if(!in_array($joinType, [
+            JOINTYPE['LEFTJOIN'],
+            JOINTYPE['RIGHTJOIN'],
+            JOINTYPE['INNERJOIN'],
+            JOINTYPE['OUTERJOIN'],
+            JOINTYPE['FULLOUTERJOIN'],
+            JOINTYPE['LEFTOUTERJOIN'],
+            JOINTYPE['RIGHTOUTERJOIN']
+        ]))
+        if(is_array($on)) {
+            foreach($on as $key => $val) {
+                $arr[] = $key .' = '. $val;
+            }
+            $on = join(' AND ', $arr);
+        }
+        $this->join = $this->join . PHP_EOL . $joinType  .' '. $table .' ON '. $on;
+        return $this;
+    }
+
+    /**
+     * right join
+     * @param string $table 表名
+     * @param array $on on条件
+     * @return $this
+     */
+    final public function rightJoin($table, $on) {
+        return $this->join($table, $on, JOINTYPE['RIGHTJOIN']);
+    }
+
+    /**
+     * right join
+     * @param string $table 表名
+     * @param array $on on条件
+     * @return $this
+     */
+    final public function innerJoin($table, $on) {
+        return $this->join($table, $on, JOINTYPE['INNERJOIN']);
+    }
+
+    /**
+     * @param $having
+     * @return $this
+     */
+    final public function having($having){
+        if($having != null){
+            $this->having = sprintf($this->query['HAVING'], $having);
+        }
+        return $this;
+    }
+
+    /**
+     * @param int $start start
+     * @param int|null $limit limit
+     * @return $this
+     */
+    final public function limit($start, $limit = null){
+        if($limit == null){
+            $limit = $start;
+            $start = 0;
+        }
+        $this->limit =  sprintf($this->query['LIMIT'], $start, $limit);
+        return $this;
+    }
+
+    /**
+     * @param $offset
+     * @return $this
+     */
+    final public function offset($offset){
+        return $this->limit($offset);
+    }
+
+    /**
+     * 查询
+     * @param string $table 表名,如果为空则从from中取
+     * @return string
+     * @throws TableException
+     */
+    final public function selectSQL($table = null){
+        if($table == null) {
+            $table = $this->table;
+        }
+        $this->handleError(!$this->verifyTable($table), '表名格式不正确');
+        $sql = sprintf(
+            $this->query['SELECT'],
+            ($this->fields != null ? $this->fields : '*'),
+            $table,
+            $this->montage(
+                $this->join,
+                ($this->where != null ? sprintf($this->query['WHERE'], $this->where) : ''),
+                $this->group,
+                $this->having,
+                $this->order,
+                $this->limit
+            )
+        );
+        $this->executeSQL = $sql;
+        $this->clean();
+        return $sql;
+    }
+
+    /**
+     * 保存数据
+     * @param string $table 表名
+     * @param array $data 数据
+     * @param string $opt INSERT/REPLACE
+     * @return string
+     * @throws InvalidParams
+     */
+    protected function createData($table, $data, $opt = 'INSERT') {
+        $this->handleError(!isset($this->query[$opt]), '不支持的操作方法');
+        if(is_object($data)) {
+            $data = get_object_vars($data);
+        }
+        if($table == null) {
+            $table = $this->table;
+        }
+        $this->handleError(!$this->verifyTable($table) || !$data, 'insert参数必须包含表名及插入的数据');
+
+        $fields = [];
+        $value = [];
+        foreach($data as $field => $val) {
+            $fields[] = '`'. $field .'`';
+            if(strtolower(gettype($val)) == 'null') {
+                $value[] = 'null';
+                continue;
+            }
+            $value[] = "'". $this->setQuote($val) ."'";
+        }
+        $sql = sprintf($this->query[$opt], $table, join(', ', $fields), join(', ', $value));
+        $this->executeSQL = $sql;
+        return $sql;
+    }
+    /**
+     * insert into table
+     * @param string $table 表名
+     * @param array $data 数据 可以为array 或者 new \stdClass()
+     * @return string
+     * @throws InvalidParams
+     */
+    final public function insertSQL($table = null, $data = []){
+        return $this->createData($table, $data, 'INSERT');
+    }
+
+    /**
+     * replace into table
+     * @param string $table 表名
+     * @param array $data 数据
+     * @return string
+     * @throws InvalidParams
+     */
+    final public function replaceSQL($table = null, $data = []){
+        return $this->createData($table, $data, 'REPLACE');
+    }
+
+    /**
+     * sets 更新数据使用
+     * @param $data
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function sets($data) {
+        $this->handleError(!is_array($data) && !is_string($data), '参数必须为字符串或数组');
+        if(is_string($data)) {
+            $this->sets = $this->sets == null ? $data : $this->sets . ', '. $data;
+            return $this;
+        }
+        foreach ($data as $field => $val) {
+            $this->set($field, $val);
+        }
+        return $this;
+    }
+
+    /**
+     * set 单个更新数据使用
+     * @param $field
+     * @param $value
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function set($field, $value = null){
+        if(is_array($field)) {
+            foreach ($field as $k => $v) {
+                $this->set($k, $v);
+            }
+            return $this;
+        }
+        $this->handleError(!is_string($field), '字段名必须为字符串,获取到的为'. print_r($field, true));
+        // 如果有 incr decr
+        if(strlen($field) > 5) {
+            $opt = substr($field, -5);
+            if(in_array($opt, [':incr', ':decr'])) {
+                $field = $this->formatField(substr($field, 0, -5));
+
+                if($opt == ':incr') {
+                    $val = $this->handleFieldAlias($field) .'='. $this->handleFieldAlias($field) .'+'. $value;
+                }else{
+                    $val = $this->handleFieldAlias($field) .'='. $this->handleFieldAlias($field) .'-'. $value;
+                }
+                $this->sets = $this->sets != null ? $this->sets . ', '. $val : $val;
+                return $this;
+            }
+        }
+        $val = $this->handleFieldAlias($field) ."='". $this->setQuote($value) . "'";
+        $this->sets = $this->sets != null ? $this->sets . ', '. $val : $val;
+        return $this;
+    }
+
+    /**
+     * 增加某一个字段值
+     * @param string $field 字段名
+     * @param int|float $val
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function incr($field, $val){
+        return $this->set($field . ':incr', $val);
+    }
+
+    /**
+     * 减小某一个字段值
+     * @param string $field 字段名
+     * @param int|float $val
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function decr($field, $val) {
+        return $this->set($field . ':decr', $val);
+    }
+    /**
+     * 更新数据
+     *
+     * @param string $table
+     * @return string
+     * @throws InvalidParams
+     */
+    final public function updateSQL($table = null){
+        if($table == null){
+            $table = $this->table;
+        }
+        $this->handleError(!$this->verifyTable($table), '数据表格式不正确');
+        $sql = sprintf(
+            $this->query['UPDATE'],
+            $table,
+            $this->montage(
+                $this->sets,
+                ($this->where != null ? sprintf($this->query['WHERE'], $this->where) : ''),
+                $this->formatLimitForUpdate($this->limit)
+            )
+        );
+        $this->executeSQL = $sql;
+        $this->clean();
+        return $sql;
+    }
+
+    /**
+     * 删除数据
+     * @param string $table 表名
+     * @return string
+     * @throws InvalidParams
+     */
+    final public function deleteSQL($table = null){
+        if($table == null){
+            $table = $this->table;
+        }
+        $this->handleError(!$this->verifyTable($table), '数据表格式不正确');
+
+        $sql = sprintf($this->query['DELETE'], $table, $this->montage(
+            ($this->where != null ? sprintf($this->query['WHERE'], $this->where) : ''),
+            $this->formatLimitForUpdate($this->limit)
+        ));
+        $this->executeSQL = $sql;
+        $this->clean();
+        return $sql;
+    }
+
+    /**
+     * 去掉null的值,并将他们拼接在一起
+     *
+     * @return string
+     */
+    protected function montage(){
+        $arr = func_get_args();
+        $tmp = [];
+        foreach ($arr as $value) {
+            if($value !== null) {
+                $tmp[] = $value;
+            }
+        }
+        return join(PHP_EOL, $tmp);
+    }
+
+    /**
+     * from table
+     * @param string $table 表名
+     * @return $this
+     * @throws InvalidParams
+     */
+    final public function from($table){
+        $this->handleError(!$table, '查询表名');
+        $this->handleError(!$this->verifyTable($table), '数据表格式');
+        $this->table = $table;
+        return $this;
+    }
+
+    /**
+     * 如果$bool为true直接抛出异常
+     *
+     * @param bool $bool bool
+     * @param string $msg 异常提示消息
+     * @return false
+     * @throws InvalidParams
+     */
+    final public function handleError($bool, $msg) {
+        if($bool) {
+            throw new InvalidParams(_i('%s is invalid', $msg), 400);
+        }
+        return false;
+    }
+    /**
+     * 验证数据表名是否符合规范
+     * 表名不能以数字开头,
+     *
+     * @param string $name
+     * @return bool
+     */
+    final public function verifyTable($name) {
+        if (!is_string($name) || (
+                // table
+                !preg_match("/^[a-zA-Z_]+[a-zA-Z0-9_]{0,}$/", $name) &&
+                // `table`
+                !preg_match("/^`[a-zA-Z_]+[a-zA-Z0-9_]{0,}`$/", $name)) &&
+            // table alias
+            !preg_match("/^[a-zA-Z_]+[a-zA-Z0-9_]{0,}\s+[a-zA-Z]+[a-zA-Z0-9_]{0,}$/", $name) &&
+            // `table` alias
+            !preg_match("/^`[a-zA-Z_]+[a-zA-Z0-9_]{0,}`\s+[a-zA-Z]+[a-zA-Z0-9_]{0,}$/", $name) &&
+            // database.table
+            !preg_match("/^[a-zA-Z]+\.[a-zA-Z]+[a-zA-Z0-9_]{0,}$/", $name) &&
+            !preg_match("/^[a-zA-Z]+\.[a-zA-Z]+[a-zA-Z0-9_]{0,}\s+[a-zA-Z]+[a-zA-Z0-9_]{0,}$/", $name)
+        ) {
+            return false;
+        }
+        return true;
+    }
+
+
+    /**
+     * 获取表的别名
+     *
+     * @param string $name 名字
+     * @return array
+     */
+    final protected function getTableAlias($name)
+    {
+        if (!$this->verifyTable($name)) {
+            if (gettype($name) == 'string') {
+                throw new TableException("表名不能包含怪字符且不能以数字开头,获取到的是". $name);
+            }
+            throw new TableException("表名必须是字符串加下划线,目标字符为". gettype($name));
+        }
+        //去掉table前后的``符号
+        $name = str_replace('`', '', $name);
+        $aliases = explode(' ', $name);
+        //检查表名中时候含数据库名,有数据表名的时候需要单独处理
+        $hasDatabaseName = false;
+        if(stristr($name, '.')) {
+            $hasDatabaseName = true;
+        }
+        if(count($aliases) == 1) {
+            if($hasDatabaseName) {
+                $names = explode(".", $name);
+                $name = $names[0] . ".`". $names[1] . "`";
+            }else{
+                $name = "`". $name ."`";
+            }
+            return array('alias' => '', 'name' => $name);
+        }
+        $res = array();
+        $res['alias'] = array_pop($aliases);
+        $res['name'] = join(" ", array_slice($aliases, -1));
+        if($hasDatabaseName) {
+            $names = explode(".", $res['name']);
+            $res['name'] = $names[0] . ".`". $names[1] . "`";
+        }else{
+            $res['name'] = "`". $res['name'] ."`";
+        }
+        return $res;
+    }
+    /**
+     * UPDATE DELETE 仅支持 LIMIT count 方式
+     *
+     * @param string $limit LIMIT 1,10
+     * @return mixed|string
+     */
+    final public function formatLimitForUpdate($limit) {
+        preg_match("/LIMIT\s+(\d+),\s+(\d+)/", $limit, $matches);
+        if(count($matches) == 3) {
+            return "LIMIT ". intval($matches[2]);
+        }
+        return $limit;
+    }
+
+    /**
+     * 格式化 a.field 格式为 a.`field`
+     * @param string $field 字段名
+     * @return mixed|string
+     */
+    final public function formatField($field) {
+        if(strpos($field, '.') !== false) {
+            preg_match("/^(.+)\.(.+)$/", $field, $matches);
+            if(count($matches) == 3) {
+                return $matches[1] . ".`". $matches[2] . "`";
+            }
+        }
+        return $field;
+    }
+
+    /**
+     * 返回所有执行的SQL及耗时
+     *
+     * @return array
+     */
+    final public function getExecutionSQL(){
+        return $this->executionSQL;
+    }
+}

+ 51 - 15
src/Library/Crypt.php

@@ -23,7 +23,8 @@ class Crypt
 	const VERSION = '1.2';
 	//密匙
 	private $securityKey = 'qii.v.1.3';
-	private $keyLength = 4;
+	private $verifyKeyLength = 4;
+    private $securityKeyLength = 32;
 	private $iv = 'sdEKw2wJCnctEG09';
 
 	public function __construct()
@@ -43,8 +44,8 @@ class Crypt
 	{
 		if(!$key) return;
 		$len = strlen($key);
-		if ($len < 16) $key = str_pad($key, 16, '.');
-		if($len > 16) $key = substr($key, 0, 16);
+		if ($len < $this->securityKeyLength) $key = str_pad($key, $this->securityKeyLength, '.');
+		if($len > $this->securityKeyLength) $key = substr($key, 0, $this->securityKeyLength);
 		$this->securityKey = $key;
 		return $this;
 	}
@@ -63,9 +64,8 @@ class Crypt
 	 */
 	public function getIv()
 	{
-		$this->iv = $this->iv;
+        if(strlen($this->iv) == 16) return $this->iv;
 		if(!$this->iv < 16) $this->iv = str_pad($this->iv, 16, '.');
-		if(strlen($this->iv) == 16) return $this->iv;
 		return substr($this->iv, 0, 16);
 	}
 
@@ -77,11 +77,25 @@ class Crypt
 	 */
 	public function encrypt($string)
 	{
-		$string = time() . $string;
-		$passcrypt = openssl_encrypt($string, 'aes-256-cbc', $this->securityKey, OPENSSL_RAW_DATA, $this->getIv());
-		return $this->getVerifyString(base64_encode($passcrypt));
+        $passcrypt = $this->encryptPure($string);
+		return $this->getVerifyString($passcrypt);
 	}
 
+    /**
+     * 仅加密
+     *
+     * @param $string
+     * @param $algo
+     * @return string
+     */
+    public function encryptPure($string, $algo = 'aes-256-cbc') {
+        $string = time() . $string;
+        if(strlen($this->securityKey) == 16) {
+            $algo = 'aes-128-cbc';
+        }
+        $passcrypt = openssl_encrypt($string, $algo, $this->securityKey, OPENSSL_RAW_DATA, $this->getIv());
+        return base64_encode($passcrypt);
+    }
     /**
      * 带过期时间加密
      *
@@ -142,19 +156,41 @@ class Crypt
 	 * @param $string
 	 * @return string
 	 */
-	public function decrypt($string)
+	public function decrypt($string, $algo = 'aes-256-cbc')
 	{
 		$string = str_replace(' ', '+', $string);
 		$string = $this->verifyString($string);
 		if(!$string)
         {
             return '';
+        }
+        if(strlen($this->securityKey) == 16) {
+            $algo = 'aes-128-cbc';
         }
 		$string = base64_decode($string);
-		$passCrypt = openssl_decrypt($string, 'aes-256-cbc', $this->securityKey, OPENSSL_RAW_DATA, $this->getIv());
-		return substr($passCrypt, 10);
+		$passCrypt = openssl_decrypt($string, $algo, $this->securityKey, OPENSSL_RAW_DATA, $this->getIv());
+        return substr($passCrypt, 10);
 	}
 
+    /**
+     * decrypt without verify
+     * @param $string
+     * @return false|string
+     */
+    public function decryptPure($string, $algo = 'aes-256-cbc') {
+        $string = str_replace(' ', '+', $string);
+        if(!$string)
+        {
+            return '';
+        }
+        if(strlen($this->securityKey) == 16) {
+            $algo = 'aes-128-cbc';
+        }
+        $string = base64_decode($string);
+        $passCrypt = openssl_decrypt($string, $algo, $this->securityKey, OPENSSL_RAW_DATA, $this->getIv());
+        return $passCrypt;
+    }
+
 	/**
 	 * 将字符串做数字签名
 	 *
@@ -163,7 +199,7 @@ class Crypt
 	 */
 	public function getVerifyCode($string)
 	{
-		return substr(md5($string), -1 * $this->keyLength);
+		return substr(md5($string), -1 * $this->verifyKeyLength);
 	}
 
 	/**
@@ -186,8 +222,8 @@ class Crypt
 	 */
 	public function verifyString($string)
 	{
-		$verifyCode = substr($string, 0, $this->keyLength);
-		if ($this->getVerifyCode(substr($string, $this->keyLength)) != $verifyCode) return '';
-		return substr($string, $this->keyLength);
+		$verifyCode = substr($string, 0, $this->verifyKeyLength);
+		if ($this->getVerifyCode(substr($string, $this->verifyKeyLength)) != $verifyCode) return '';
+		return substr($string, $this->verifyKeyLength);
 	}
 }