朱金辉 5 ماه پیش
والد
کامیت
e47cbc3f78
3فایلهای تغییر یافته به همراه245 افزوده شده و 17 حذف شده
  1. 105 14
      src/Driver/Base.php
  2. 135 3
      src/Driver/Entity/Base.php
  3. 5 0
      src/Driver/Entity/Entity.php

+ 105 - 14
src/Driver/Base.php

@@ -71,6 +71,20 @@ class Base
     public $executeSQL = '';
 
     public $operateVal = array('or', 'and', 'like');//连接条件操作;
+    public $shortExpression = array(
+        'equal' => "%s`%s` = '%s'",
+        'in' => "%s`%s` in (%s)",
+        'unequal' => "%s`%s` != '%s'",
+        'greater' => "%s`%s` > '%s'",
+        'gt' => "%s`%s` > '%s'",
+        'greaterEqual' => "%s`%s` >= '%s'",
+        'gte' => "%s`%s` >= '%s'",
+        'less' => "%s`%s` < '%s'",
+        'lessEqual' => "%s`%s` <= '%s'",
+        'lte' => "%s`%s` <= '%s'",
+        'like' => "%s`%s` like '%%%s%%'"
+    );
+
     public $operateTable = array('leftJoin', 'rightJoin', 'innerJoin');//链接表的操作
     public $faultTolerant = true;
 
@@ -346,14 +360,14 @@ class Base
      * @param int $limit
      * @param int $offset
      */
-    final function limit($limit, $offset = 0)
+    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) {
+            if ($offset === null) {
                 $this->limit = sprintf($this->_query["LIMIT"], 0, $limit);
             } else {
                 $this->limit = sprintf($this->_query["LIMIT"], $limit, $offset);
@@ -462,6 +476,38 @@ class Base
         }
         return $this->set($set);
     }
+
+    /**
+     * 处理where条件
+     *
+     * @param $where
+     * @return $this|array
+     * @throws \Exception
+     */
+    public function handleWhereFields($where) {
+        if(!is_array($where)) {
+            return $this;
+        }
+        $fields = [];
+        foreach ($where as $key => $val) {
+            $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);
+                foreach ($arr1 as $key) {
+                    $fields[$key . $opt] = $val;
+                }
+            }
+        }
+        return $fields;
+    }
     /**
      * where条件
      * @param array $where where语句
@@ -487,6 +533,7 @@ class Base
         if(count($where) == 0) {
             return $this;
         }
+        $where = $this->handleWhereFields($where);
         $slices = $this->groupContents($where);
         $this->handleCondition($slices, $res);
         return $this;
@@ -494,6 +541,14 @@ class Base
 
     /**
      * OR 条件
+     * 用法:
+     *  1:
+     *  $this->orTerms(['field1:like|equal....' => val1])->orTerms(....)
+     *  $this->orTerms(['field1:field2...:like|equal....' => val1])
+     *  == (field1 like|equal.... val1) or (field2 like|equal.... val1) ....
+     *  2:
+     * $this->orTerm(['field1:like|equal...' => val1, 'field2:like|equal...' => val1])
+     * == (field1 like|equal.... val1 AND field2 like|equal.... val1 ....)
      * @param $where
      * @param string $defaultOperater
      * @param null $res
@@ -515,7 +570,33 @@ class Base
         if(count($where) == 0) {
             return $this;
         }
-        $this->handleCondition(array(array($defaultOperater, $where)), $res);
+        $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 $field) {
+                    $extra[$field . $opt] = $val;
+                }
+                unset($where[$key]);
+            }
+        }
+        if(count($where) > 0) {
+            $this->handleCondition(array(array($defaultOperater, $where)), $res);
+        }
+
+        if(count($extra) > 0) {
+            foreach ($extra as $key => $val) {
+                $this->handleCondition(array(array($defaultOperater, [$key => $val])), $res);
+            }
+        }
         return $this;
     }
 
@@ -550,6 +631,7 @@ class Base
             $where[$key . ":in"] = $val;
             unset($where[$key]);
         }
+        $where = $this->handleWhereFields($where);
         $this->handleCondition(array(array('and', $where)), $res);
         return $this;
     }
@@ -1037,6 +1119,24 @@ class Base
         return in_array($val, $this->operateVal) || in_array($val, $this->operateTable);
     }
 
+    /**
+     * 判断是否是表达式 equal unequal ...
+     *
+     * @param string $val
+     * @return bool
+     * @throws \Exception
+     */
+    protected function isExpression($val) {
+        if(is_array($val)) {
+            return false;
+        }
+        if(in_array(gettype($val), array("array", "object", "resource","resource (closed)"))) {
+            throw new \Exception("期待参数为字符串,获取到的为: " . gettype($val) ."(". json_encode($val) . ")");
+        }
+
+        return isset($this->shortExpression[$val]);
+    }
+
     /**
      * 是否是操作表
      *
@@ -1068,16 +1168,7 @@ class Base
             $extraParams = array_slice(func_get_args(), 2);
         }
         $where = array();
-        $operator = array('equal' => "%s`%s` = '%s'",
-                            'in' => "%s`%s` in (%s)",
-                            'unequal' => "%s`%s` != '%s'",
-                            'greater' => "%s`%s` > '%s'",
-                            'greaterEqual' => "%s`%s` >= '%s'",
-                            'gte' => "%s`%s` >= '%s'",
-                            'less' => "%s`%s` < '%s'",
-                            'lessEqual' => "%s`%s` <= '%s'",
-                            'lte' => "%s`%s` <= '%s'",
-                            'like' => "%s`%s` like '%%%s%%'");
+        $operator = $this->shortExpression;
         $lastIsOperator = false;
         $lastIsValue = null;
         $i = 0;
@@ -1255,7 +1346,7 @@ class Base
         if(!empty($this->whereCondition))
         {
             $lastCondition = $this->whereCondition[count($this->whereCondition) - 1];
-            if(!$this->isOperator($whereCondition[0]) && !$this->isOperator($lastCondition)) {
+            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);

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

@@ -115,6 +115,24 @@ class Base {
         return $this;
     }
 
+    /**
+     * or 查询
+     * @param array | string $condition 条件
+     * @param mixed $args 参数
+     * @return $this
+     * @throws \Exception
+     */
+    final public function or($condition, $args = null) {
+        $this->setOrHooker(function($or) use($condition){
+            if(is_array($condition)) {
+                $or = array_merge($or, $condition);
+                return $or;
+            }
+            return $condition;
+        });
+        return $this;
+    }
+
     /**
      * Or Hooker
      * @param $hooker
@@ -147,6 +165,25 @@ class Base {
         }
         return $or;
     }
+
+    /**
+     * where 条件
+     * @param array $where where条件
+     * @param mixed $args 参数
+     * @return $this
+     * @throws \Exception
+     */
+    final public function where($where, $args = null) {
+        $this->setWhereHooker(function($w) use($where){
+            if(is_array($where)) {
+                $w = array_merge($w, $condition);
+                return $w;
+            }
+            return $where;
+        }, $args);
+        return $this;
+    }
+
     /**
      * 设置where hooker
      * @param object $hooker
@@ -179,6 +216,20 @@ class Base {
         return $where;
     }
 
+    /**
+     * join 条件
+     * @param mixed $join 条件
+     * @param mixed $args 参数
+     * @return $this
+     * @throws \Exception
+     */
+    final public function join($join, $args = null) {
+        $this->setJoinHooker(function($j) use($join){
+            $j[] = $join;
+            return $j;
+        }, $args);
+        return $this;
+    }
     /**
      * join hooker
      * @param \Closure $hooker
@@ -210,6 +261,19 @@ class Base {
         }
         return $join;
     }
+    /**
+     * order by
+     * @param array $order
+     * @param mix $args 参数
+     * @return $this
+     * @throws \Exception
+     */
+    final public function order($order, $args = null) {
+        $this->setOrderHooker(function() use($order) {
+            return $order;
+        }, $args);
+        return $this;
+    }
     /**
      * 设置order by hooker
      * @param object $hooker
@@ -222,6 +286,19 @@ class Base {
         return $this;
     }
 
+    /**
+     * limit
+     * @param  array $limit [page, limit]
+     * @param mixed $args 参数
+     * @return $this
+     * @throws \Exception
+     */
+    final public function limit($limit, $args = null) {
+        $this->setLimitHooker(function() use($limit){
+            return $limit;
+        }, $args);
+        return $this;
+    }
     /**
      * 设置 limit hooker
      *
@@ -231,7 +308,7 @@ class Base {
      */
     public function setLimitHooker($hooker, $args = null) {
         $this->checkCallable($hooker);
-        $this->setHooker('order', $hooker, $args);
+        $this->setHooker('limit', $hooker, $args);
         return $this;
     }
     /**
@@ -245,6 +322,19 @@ class Base {
         return [];
     }
 
+    /**
+     * 设置缓存插件
+     *
+     * @param Cache $cache 缓存类
+     * @return $this
+     * @throws \Exception
+     */
+    final public function cache($cache) {
+        $this->setCacheHooker(function() use($cache){
+            return $cache;
+        });
+        return $this;
+    }
     /**
      * 设置 cache hooker
      *
@@ -295,6 +385,19 @@ class Base {
         return array();
     }
 
+    /**
+     * with
+     *
+     * @param array $with 获取信息 [$rel, 'with name', 'hasOne/hasMany', 'key', 'rel_pri_key']
+     * @return $this
+     * @throws \Exception
+     */
+    public function with($with) {
+        $this->setWith(function ()use($with){
+            return $with;
+        });
+        return $this;
+    }
     /**
      * 设置关联子查询
      *
@@ -1243,6 +1346,29 @@ class Base {
         }
         return $query->rs($this->prepareTable());
     }
+
+    /**
+     * select rows
+     * @param int $page 页码
+     * @param int $pageSize 页大小
+     * @return array
+     * @throws \Qii\Exceptions\InvalidParams
+     */
+    final public function select($page = null, $pageSize = null) {
+        $limit = $this->getLimitHooker();
+        if(count($limit) > 0) {
+            $page = $limit[0];
+            $pageSize = isset($limit[1]) ? $limit[1] : null;
+        }
+        $query = $this->createQuery();
+        $query = $query->orderBy($this->getOrderBy());
+        if($page !== null) {
+            $query = $query->limit($page, $pageSize);
+        }
+        $lists = $query->selectRows($this->prepareTable());
+        $this->withList($lists);
+        return $lists;
+    }
     /**
      * listts
      * @param int $page 页码
@@ -1251,14 +1377,20 @@ class Base {
      * @throws \Exception
      */
     public function lists($page = 1, $pageSize = 20) {
+        $limit = $this->getLimitHooker();
+        if(count($limit) > 0) {
+            $page = $limit[0];
+            $pageSize = isset($limit[1]) ? $limit[1] : null;
+        }
         $count = $this->count();
         if(!$this->initPages($data, $count, $page, $pageSize)) {
             return $data;
         }
-        $query = $this->createQuery();
+        /*$query = $this->createQuery();
         $lists = $query->orderBy($this->getOrderBy())->limit($data['pages']['limitStart'], $pageSize)->selectRows($this->prepareTable());
         $this->withList($lists);
-        $data['lists'] = $lists;
+        $data['lists'] = $lists;*/
+        $data['lists'] = $this->select($data['pages']['limitStart'], $pageSize);
         return $data;
     }
     /**

+ 5 - 0
src/Driver/Entity/Entity.php

@@ -129,13 +129,18 @@ class Entity {
         $classAndProperty[] = <<<DOC
 /**
  * @method $class setWhereHooker(\$hooker, \$args = null)
+ * @method $class with(\$with, \$args = null)
  * @method $class setWith(\$hooker, \$args = null)
+ * @method $class order(\$order, \$args = null)
  * @method $class setOrderHooker(\$hooker, \$args = null)
  * @method $class setHooker(\$key, \$hooker, \$args)
  * @method $class setCacheConfig(\$config)
  * @method $class setCacheHooker(\$hooker, \$args = null)
+ * @method $class join(\$join, \$args = null)
  * @method $class setJoinHooker(\$hooker, \$args = null)
+ * @method $class limit(\$limit, \$args = null)
  * @method $class setLimitHooker(\$hooker, \$args = null)
+ * @method $class or(\$or, \$args = null)
  * @method $class setOrHooker(\$hooker, \$args = null)
  * @method $class setQueryFieldsHooker(\$hooker, \$args = null)
  * @method $class get()