Bladeren bron

Fixed: some bugs

朱金辉 1 maand geleden
bovenliggende
commit
3a92ad4086
4 gewijzigde bestanden met toevoegingen van 189 en 46 verwijderingen
  1. 37 12
      src/Driver/Base.php
  2. 3 3
      src/Driver/EasyDrive.php
  3. 1 1
      src/Driver/EasyORM.php
  4. 148 30
      src/Driver/Entity/Base.php

+ 37 - 12
src/Driver/Base.php

@@ -65,6 +65,10 @@ class Base
     public $response;
     //执行的sql语句
     public $modelSQL = "";
+    /**
+     * @var string sql 引用
+     */
+    public $executeSQL = '';
 
     public $operateVal = array('or', 'and', 'like');//连接条件操作;
     public $operateTable = array('leftJoin', 'rightJoin', 'innerJoin');//链接表的操作
@@ -102,7 +106,7 @@ class Base
         {
             $this->where($where);
         }
-        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        $sql = $this->createSelectSQL($table);
         return $this->getAll($sql);
     }
     /**
@@ -111,7 +115,7 @@ class Base
      */
     final function rs($table)
     {
-        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        $sql = $this->createSelectSQL($table);
         return $this->setQuery($sql);
     }
     /**
@@ -127,7 +131,7 @@ class Base
         {
             $this->where($where);
         }
-        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        $sql = $this->createSelectSQL($table);
         return $this->getRow($sql);
     }
 
@@ -156,7 +160,7 @@ class Base
             }
             throw new TableException("表名必须是字符串加下划线,目标字符为". gettype($table));
         }
-        $this->modelSQL = $sql = $this->createSelectSQL($table);
+        $sql = $this->createSelectSQL($table);
         return $this->getOne($sql);
     }
 
@@ -186,7 +190,7 @@ class Base
         {
             throw new Variable(_i('Invalid %s format', 'data'), __LINE__);
         }
-        $this->modelSQL = $sql = "INSERT INTO " . $this->getTable($table) . "(`" . join("`, `", $replaceObj['fields']) . "`) VALUES('" . join("', '", $replaceObj['values']) . "')";
+        $this->executeSQL = $this->modelSQL = $sql = "INSERT INTO " . $this->getTable($table) . "(`" . join("`, `", $replaceObj['fields']) . "`) VALUES('" . join("', '", $replaceObj['values']) . "')";
         $this->setQuery($sql);
         $this->setError();
         return $this->lastInsertId();
@@ -207,7 +211,7 @@ class Base
         {
             throw new Variable(_i('Invalid %s format', 'data'), __LINE__);
         }
-        $this->modelSQL = $sql = "REPLACE INTO " . $this->getTable($table) . "(`" . join("`, `", $replaceObj['fields']) . "`) VALUES('" . join("', '", $replaceObj['values']) . "')";
+        $this->executeSQL = $this->modelSQL = $sql = "REPLACE INTO " . $this->getTable($table) . "(`" . join("`, `", $replaceObj['fields']) . "`) VALUES('" . join("', '", $replaceObj['values']) . "')";
         $rs = $this->setQuery($sql);
         $this->setError();
         return $this->AffectedRows($rs);
@@ -261,7 +265,7 @@ class Base
         $this->whereCondition = array();
 
         $alias = $this->getTableAlias($table);
-        $this->modelSQL = $sql = sprintf($this->_query['UPDATE'], $alias['name'] . $alias['alias']) . $set. $where;
+        $this->executeSQL = $this->modelSQL = $sql = sprintf($this->_query['UPDATE'], $alias['name'] . $alias['alias']) . $set. $where;
         return $this->exec($sql);
     }
     /**
@@ -296,7 +300,7 @@ class Base
         $this->whereCondition = array();
 
         $alias = $this->getTableAlias($table);
-        $this->modelSQL = $sql = sprintf($this->_query['DELETE'], $alias['name'], $where);
+        $this->executeSQL = $this->modelSQL = $sql = sprintf($this->_query['DELETE'], $alias['name'], $where);
         return $this->exec($sql);
     }
 
@@ -701,25 +705,34 @@ class Base
      * @param string|array $fields
      * @return $this
      */
-    final function fields($fields = "*")
+    final function fields($fields = "*", $append = false)
     {
-        if (empty($fields)) $fields = "*";
+        if (empty($fields) && !$append) $fields = "*";
         if (is_array($fields)) {
             if(count($fields) == 0) {
-                $fields = '*';
+                $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);
             }
         }
-        $this->fields = $fields;
+        if($append) {
+            if($fields != "") $this->fields .= ','. $fields;
+        }else{
+            $this->fields = $fields;
+        }
+
         return $this;
     }
     /**
@@ -794,6 +807,17 @@ class Base
         }
         return 0;
     }
+
+    /**
+     * 获取执行的sql
+     *
+     * @param string $sql
+     * @return $this
+     */
+    public function fetchSql(&$sql) {
+        $this->executeSQL = &$sql;
+        return $this;
+    }
     /**
      * 通过where\set\limit等方法自动生成SQL语句
      *
@@ -832,6 +856,7 @@ class Base
 
         $sql = sprintf($this->_query['SELECT'], $fields, $aliases['name'], $aliases['alias']) . $join . $where . $groupBy . $orderBy . $limit;
         $this->cleanCondition();
+        $this->executeSQL = $this->modelSQL = $sql;
         return $sql;
     }
     /**

+ 3 - 3
src/Driver/EasyDrive.php

@@ -337,7 +337,7 @@ class EasyDrive {
     /**
      * 删除指定数据
      *
-     * @return Qii\Driver\Response
+     * @return Response
      */
     final public function remove() {
         return $this->_easyORM->remove();
@@ -346,7 +346,7 @@ class EasyDrive {
     /**
      * 更新字段,与update的区别是只验更新字段的值,不验证update设定的字段
      *
-     * @return mixed|Qii\Driver\Response
+     * @return mixed|Response
      */
     final public function updateFields(){
         return $this->_easyORM->updateFields();
@@ -402,7 +402,7 @@ class EasyDrive {
     /**
      * 检查数据是否已经存在,并返回一行,只能根据主键查询
      *
-     * @return \Qii\Driver\Response
+     * @return Response
      */
     final public function exist() {
         return $this->_easyORM->exist();

+ 1 - 1
src/Driver/EasyORM.php

@@ -667,7 +667,7 @@ final class EasyORM {
     /**
      * 删除指定数据
      *
-     * @return Qii\Driver\Response
+     * @return \Qii\Driver\Response
      */
     final public function remove() {
         if(!$this->_easyORM->privateKeys &&  !$this->_easyORM->exclude && !$this->_easyORM->where) {

+ 148 - 30
src/Driver/Entity/Base.php

@@ -12,8 +12,13 @@ class Base {
      * @var array $properties
      */
     public static $properties;
+
     public static $config;
     /**
+     * @var string 表别名
+     */
+    private $alias;
+    /**
      * hooker for fields 查询字段/ where 查询条件 / order 排序 / cache 缓存 / with 关联查询
      * @var array $hooker
      */
@@ -25,6 +30,12 @@ class Base {
      */
     private $defaultExpired = 600;
 
+    /** 当前执行的sql
+     *
+     * @var string
+     */
+    private $calledSQL = "";
+
     public function __construct(){
     }
 
@@ -44,6 +55,30 @@ class Base {
     public function getTable() {
         throw new \Exception('请先设置需要保存的数据表');
     }
+
+    /**
+     * 当前表名别名
+     *
+     * @param string $name
+     * @return $this
+     */
+    public function alias($name) {
+        $this->alias = $name;
+        return $this;
+    }
+
+    /**
+     * 预处理表名
+     *
+     * @return mixed|string
+     * @throws \Exception
+     */
+    public function prepareTable() {
+        if($this->alias == '') {
+            return $this->getTable();
+        }
+        return $this->getTable() . ' ' . $this->alias;
+    }
     /**
      * set hooker for method
      * 目前 where 和 order 及 fields 支持
@@ -108,12 +143,51 @@ class Base {
     public function getWhereHooker() {
         $where = $this->properties();
         if(isset($this->hooker['where']) && is_callable($this->hooker['where']['func'])) {
-            $where = call_user_func($this->hooker['where']['func'], $this->properties(), $this->hooker['where']['args']);
+            if($this->alias != ""){
+                foreach ($where as $key => $value) {
+                    if(!preg_match("/{$this->alias}\.{$key}/", $key)) {
+                        $where[$this->alias .'.'. $key] = $value;
+                        unset($where[$key]);
+                    }
+                }
+            }
+            $where = call_user_func($this->hooker['where']['func'], $where, $this->hooker['where']['args']);
         }
         return $where;
     }
 
     /**
+     * join hooker
+     * @param \Closure $hooker
+     * @param mix $args
+     * @return $this
+     * @throws \Exception
+     */
+    public function setJoinHooker($hooker, $args = null) {
+        $this->checkCallable($hooker);
+        if(!isset($this->hooker['join'])) {
+            $this->hooker['join'] = [];
+        }
+        $this->hooker['join'][] = ['func' => $hooker, 'args' => $args];
+        return $this;
+    }
+
+    /**
+     * 获取 join hooker
+     * @return array
+     */
+    public function getJoinHooker() {
+        $join = [];
+        if(isset($this->hooker['join'])) {
+            foreach ($this->hooker['join'] as $value) {
+                if(is_callable($value['func'])) {
+                    $join[] = call_user_func($value['func'], [], $value['args']);
+                }
+            }
+        }
+        return $join;
+    }
+    /**
      * 设置order by hooker
      * @param object $hooker
      * @return void
@@ -427,7 +501,9 @@ class Base {
      * @throws \Exception
      */
     public function count() {
-        return $this->db()->fields(' COUNT(1) as count')->where($this->getWhereHooker())->selectOne($this->getTable());
+        $query = $this->createQuery();
+        $query->fields(' COUNT(1) as count');
+        return $query->selectOne($this->prepareTable());
     }
 
     /**
@@ -474,6 +550,15 @@ class Base {
         }
         return $this;
     }
+
+    /**
+     * 回去当前执行的sql
+     *
+     * @return string
+     */
+    public function getCalledSQL() {
+        return $this->calledSQL;
+    }
     /**
      * 获取数据
      *
@@ -485,6 +570,7 @@ class Base {
         $obj = new $class();
         $response = $this->info();
         if($response->isError()) {
+            $obj->Error = $response->getResult();
             return $obj;
         }
         $info = $response->getResult()['body'];
@@ -505,7 +591,9 @@ class Base {
      */
     public function info() {
         try{
-            $info = $this->createQuery()->selectRow($this->getTable());
+            $query = $this->createQuery();
+            $info = $query->selectRow($this->prepareTable());
+            $this->calledSQL = $query->modelSQL;
             if($info) $this->withRow($info);
             return Response::Success(static::class .'::'. __FUNCTION__,
                 [
@@ -544,7 +632,7 @@ class Base {
             foreach ($vars as $extra) {
                 if(!isset($arr[$extra])) {
                     $field = $this->entity()->convertToField($extra);
-                    $arr[$field] = $this->$extra;
+                    if(isset($this->$extra)) $arr[$field] = $this->$extra;
                 }
             }
             return $arr;
@@ -555,7 +643,7 @@ class Base {
             if($property->isPublic() && !$property->isStatic()) {
                 $name = $property->getName();
                 $field = $this->entity()->convertToField($name);
-                $arr[$field] = $this->$name;
+                if(isset($this->$name))  $arr[$field] = $this->$name;
                 continue;
             }
             //移除非public的变量
@@ -567,7 +655,7 @@ class Base {
         foreach ($vars as $extra) {
             if(!isset($arr[$extra])) {
                 $field = $this->entity()->convertToField($extra);
-                $arr[$field] = $this->$extra;
+                if(isset($this->$extra)) $arr[$field] = $this->$extra;
             }
         }
         return $arr;
@@ -582,7 +670,7 @@ class Base {
         if(!$where) {
             return false;
         }
-        return (bool) $this->db()->where($where)->selectOne($this->getTable());
+        return (bool) $this->db()->where($where)->selectOne($this->prepareTable());
     }
     /**
      * 保存数据
@@ -601,7 +689,7 @@ class Base {
 
         //如果 $where $or 为空,看看主键是否有设置值,有设置值说明验证主键就可以,反之设置了主键,主键值设置了,只验证主键就可以了
         if(count($primary) > 0) {
-            $exist = $this->db()->limit(1)->where($primary)->selectRow($this->getTable());
+            $exist = $this->db()->limit(1)->where($primary)->selectRow($this->prepareTable());
             if($exist) {
                 return Response::Exist(static::class .'::'. __FUNCTION__,
                     [
@@ -613,7 +701,7 @@ class Base {
         }
 
         if(count($uniqueWhere) > 0 || count($uniqueOr) > 0) {
-            $exist = $this->db()->limit(1)->where($uniqueWhere)->orTerms($uniqueOr)->selectRow($this->getTable());
+            $exist = $this->db()->limit(1)->where($uniqueWhere)->orTerms($uniqueOr)->selectRow($this->prepareTable());
             if($exist) {
                 return Response::Exist(static::class .'::'. __FUNCTION__,
                     [
@@ -625,7 +713,7 @@ class Base {
         }
 
         $values = array_merge($this->getDefaultValue(), $this->properties());
-        $res = $this->db()->insertObject($this->getTable(), $values);
+        $res = $this->db()->insertObject($this->prepareTable(), $values);
 
         if($this->db()->isError()) {
             return Response::FailSave(static::class .'::'. __FUNCTION__,
@@ -659,9 +747,8 @@ class Base {
         if($valid->isError()) {
             return $valid;
         }
-        $query = $this->db()->where($this->getWhereHooker());
-        $this->handleOrTerm($query);
-        $affectedRows = $query->delete($this->getTable());
+        $query = $this->createQuery();
+        $affectedRows = $query->delete($this->prepareTable());
         if($this->db()->isError()) {
             return Response::FailSave(static::class .'::'. __FUNCTION__,
                 [
@@ -712,7 +799,7 @@ class Base {
         );*/
 
         if(count($diffWhere) > 0 || count($diffOr) > 0) {
-            $unique = $this->db()->limit(1)->where($diffWhere)->orTerms($diffOr)->exclude($exclude)->selectRow($this->getTable());
+            $unique = $this->db()->limit(1)->where($diffWhere)->orTerms($diffOr)->exclude($exclude)->selectRow($this->prepareTable());
             if($unique) {
                 return Response::Exist(static::class .'::'. __FUNCTION__,
                     ['_result' => ['code' => Response::DOES_EXIST, 'msg' => '已经存在相关记录', 'body' => $unique]]
@@ -721,7 +808,7 @@ class Base {
         }
 
         //检查更新的数据是否存在,以主键为主
-        $exit = $this->db()->limit(1)->where($primaryKey)->selectOne($this->getTable());
+        $exit = $this->db()->limit(1)->where($primaryKey)->selectOne($this->prepareTable());
         if($exit === null || $exit === false) {
             return Response::NotExist(static::class .'::'. __FUNCTION__,
                 ['_result' => ['code' => Response::DOES_NOT_EXIST, 'msg' => '未找到相关记录', 'body' => []]]
@@ -731,7 +818,7 @@ class Base {
         //更新的时候不使用默认值
         //$values = array_merge($this->getDefaultValue(), $this->properties());
 
-        $affectedRows = $this->db()->updateObject($this->getTable(), $this->properties(), $primaryKey);
+        $affectedRows = $this->db()->updateObject($this->prepareTable(), $this->properties(), $primaryKey);
         if($this->db()->isError()) {
             return Response::FailUpdate(static::class .'::'. __FUNCTION__,
                 [
@@ -783,7 +870,7 @@ class Base {
         );*/
 
         if(count($diffWhere) > 0 || count($diffOr) > 0) {
-            $unique = $this->db()->limit(1)->where($diffWhere)->orTerms($diffOr)->exclude($exclude)->selectRow($this->getTable());
+            $unique = $this->db()->limit(1)->where($diffWhere)->orTerms($diffOr)->exclude($exclude)->selectRow($this->prepareTable());
             if($unique) {
                 return Response::Exist(static::class .'::'. __FUNCTION__,
                     ['_result' => ['code' => Response::DOES_EXIST, 'msg' => '已经存在相关记录', 'body' => $unique]]
@@ -791,7 +878,7 @@ class Base {
             }
         }
         //检查更新的数据是否存在,以主键为主
-        $exit = $this->db()->limit(1)->where($primaryKey)->selectOne($this->getTable());
+        $exit = $this->db()->limit(1)->where($primaryKey)->selectOne($this->prepareTable());
         if($exit === null || $exit === false) {
             return Response::NotExist(static::class .'::'. __FUNCTION__,
                 [
@@ -805,7 +892,7 @@ class Base {
         //更新的时候不使用默认值
         //$values = array_merge($this->getDefaultValue(), $this->properties());
 
-        $affectedRows = $this->db()->updateObject($this->getTable(), $this->properties(), $primaryKey);
+        $affectedRows = $this->db()->updateObject($this->prepareTable(), $this->properties(), $primaryKey);
         if($this->db()->isError()) {
             return Response::FailUpdate(static::class .'::'. __FUNCTION__,
                 [
@@ -857,7 +944,7 @@ class Base {
                 $sets[$key . ':minus'] = $val * -1;
             }
         }
-        $affectedRows = $this->db()->set($sets)->where($primary)->update($this->getTable());
+        $affectedRows = $this->db()->set($sets)->where($primary)->update($this->prepareTable());
 
         if($this->db()->isError()) {
             return Response::FailUpdate(static::class .'::'. __FUNCTION__,
@@ -873,17 +960,34 @@ class Base {
             ]
         );
     }
+
+    /**
+     * 获取fields
+     *
+     * @return false|mixed|string|string[]
+     */
+    public function getFields() {
+        $fields = $this->getFieldsHooker();
+        if(!is_array($fields)) {
+            $fields = explode(',', str_replace(" ", "", $fields));
+        }
+        return $fields;
+    }
     /**
      * 获取where及or条件并创建查询条件
      *
      * @return \Qii\Driver\Base
      */
     public function createQuery() {
-        $query = $this->db()->fields($this->getFieldsHooker())->where($this->getWhereHooker());
+        $query = $this->db()->fields($this->getFields())->where($this->getWhereHooker())->fetchSql($this->calledSQL);
         $or = $this->getOrHooker();
         foreach ($or as $v) {
             $query = $query->orTerms($v);
         }
+        $join = $this->getJoinHooker();
+        foreach ($join as $j) {
+            $query = $query->join($j);
+        }
         return $query;
     }
     /**
@@ -898,7 +1002,7 @@ class Base {
             $orderBy[$key] = 'ASC';
         }
         $query = $this->createQuery();
-        $row = $query->limit(1)->orderBy($orderBy)->selectRow($this->getTable());
+        $row = $query->limit(1)->orderBy($orderBy)->selectRow($this->prepareTable());
         if($this->db()->isError()) {
             return Response::Fail(static::class .'::'. __FUNCTION__,
                 [
@@ -927,7 +1031,9 @@ class Base {
         foreach ($orderBy as $key => $value) {
             $orderBy[$key] = 'DESC';
         }
-        $row = $this->createQuery()->orderBy($orderBy)->limit(1)->selectRow($this->getTable());
+        $query = $this->createQuery();
+        $row = $query->orderBy($orderBy)->limit(1)->selectRow($this->prepareTable());
+        $this->calledSQL = $query->modelSQL;
         if($this->db()->isError()) {
             return Response::Fail(static::class .'::'. __FUNCTION__,
                 [
@@ -998,7 +1104,8 @@ class Base {
         if(!$this->initPages($data, $count, $page, $pageSize)) {
             return $data;
         }
-        $lists = $this->createQuery()->orderBy($this->getOrderBy())->limit($data['pages']['limitStart'], $pageSize)->selectRows($this->getTable());
+        $query = $this->createQuery();
+        $lists = $query->orderBy($this->getOrderBy())->limit($data['pages']['limitStart'], $pageSize)->selectRows($this->prepareTable());
         $this->withList($lists);
         $data['lists'] = $lists;
         return $data;
@@ -1062,7 +1169,11 @@ class Base {
             $fields = $args[2];
             if(!in_array($relKey, $fields)) $fields[] = $relKey;
         }
-        $res = $this->db()->fields($fields)->where($args[1])->rs($this->getTable());
+        if(count($this->getFields()) > 0 && !in_array($relKey, $this->getFields())) {
+            $fields[] = $relKey;
+        }
+        $query = $this->createQuery()->fields($fields, true);
+        $res = $query->where($args[1])->rs($this->prepareTable());
         $rows = [];
         foreach($res as $v) {
             $rows[$v[$relKey]] = $v;
@@ -1086,8 +1197,12 @@ class Base {
             $fields = $args[2];
             if(!in_array($relKey, $fields)) $fields[] = $relKey;
         }
-
-        $res = $this->db()->fields($fields)->where($args[1])->rs($this->getTable());
+        if(count($this->getFields()) > 0 && !in_array($relKey, $this->getFields())) {
+            $fields[] = $relKey;
+        }
+        $query = $this->createQuery()->fields($fields, true);
+        $res = $query->where($args[1])->rs($this->prepareTable());
+        echo $this->calledSQL;
         $rows = [];
         foreach($res as $v) {
             $rows[$v[$relKey]][] = $v;
@@ -1107,17 +1222,17 @@ class Base {
         $query = $this->createQuery()->orderBy($this->getOrderBy());
         if(empty($limit) || !is_array($limit)) {
             $list =  $query
-                ->selectRows($this->getTable());
+                ->selectRows($this->prepareTable());
             $this->withList($list);
             return $list;
         }
         if(count($limit) == 1) {
-            $list = $query->limit($limit[0])->selectRows($this->getTable());
+            $list = $query->limit($limit[0])->selectRows($this->prepareTable());
             $this->withList($list);
             return $list;
         }
         $list =  $query
-            ->limit($limit[0], $limit[1])->selectRows($this->getTable());
+            ->limit($limit[0], $limit[1])->selectRows($this->prepareTable());
         $this->withList($list);
         return $list;
     }
@@ -1306,6 +1421,9 @@ class Base {
         }
         foreach ($orderBy as $key => $val) {
             $field = $this->entity()->convertToField($key);
+            if($this->alias != "" && strpos($field, '.') === false) {
+                $field = $this->alias . '.' . $field;
+            }
             $val = strtoupper($val);
             if(!in_array($val, array('DESC', 'ASC'))) {
                 continue;