|
@@ -12,7 +12,12 @@ 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,11 +143,50 @@ 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
|
|
@@ -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;
|