Skip to content

Commit

Permalink
Merge pull request #51 from teamones-open/add_hint
Browse files Browse the repository at this point in the history
add:Partition 数据库分区,和 setSuffix() 设置数据表后缀支持分表查询
  • Loading branch information
weijer committed Dec 18, 2023
2 parents 55d831d + 773e3cd commit 904bdce
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 14 deletions.
45 changes: 44 additions & 1 deletion src/think/Model.php
Expand Up @@ -85,6 +85,9 @@ class Model
// 数据表名(不包含表前缀)
protected $tableName = '';

// 数据表后缀
protected $suffix = '';

// 实际数据表名(包含表前缀)
protected $trueTableName = '';

Expand Down Expand Up @@ -1022,6 +1025,11 @@ protected function _parseOptions($options = [])
$fields = $this->getDbFields();
}

// 拼接数据表后缀
if (!empty($this->suffix)) {
$options['table'] .= $this->suffix;
}

// 数据表别名
if (!empty($options['alias'])) {
$options['table'] .= ' ' . $options['alias'];
Expand Down Expand Up @@ -2194,6 +2202,28 @@ protected function parseSql($sql, $parse)
return $sql;
}

/**
* 设置当前模型数据表的后缀
* @access public
* @param $suffix
* @return $this
*/
public function setSuffix($suffix)
{
$this->suffix = $suffix;
return $this;
}

/**
* 获取当前模型的数据表后缀
* @access public
* @return string
*/
public function getSuffix()
{
return $this->suffix ?: '';
}

/**
* 切换当前的数据库连接
* @access public
Expand Down Expand Up @@ -2760,6 +2790,18 @@ public function forceMasterDB()
return $this->hint('FORCE_MASTER');
}

/**
* 设置当前查询所在的分区
* @access public
* @param string|array $partition 分区名称
* @return $this
*/
public function partition($partition)
{
$this->options['partition'] = $partition;
return $this;
}

/**
* 增加hint标识
* @param $hintContent
Expand All @@ -2775,7 +2817,8 @@ public function hint($hintContent)
* 禁用DB after event 回调,防止死循环事件产生
* @return $this
*/
public function disableDBAfter(){
public function disableDBAfter()
{
$this->options['disable_db_after'] = true;
return $this;
}
Expand Down
47 changes: 34 additions & 13 deletions src/think/db/Driver.php
Expand Up @@ -93,7 +93,7 @@ abstract class Driver
];

// 查询表达式
protected $selectSql = '%HINT% SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%';
protected $selectSql = '%HINT% SELECT%DISTINCT% %FIELD% FROM %TABLE%%PARTITION%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%';

// 查询次数
protected $queryTimes = 0;
Expand Down Expand Up @@ -279,7 +279,7 @@ public function query($str, $fetchSql = false, $master = false)
} else {
return $this->getResult();
}
} catch (\PDOException | \Exception | \Throwable $e) {
} catch (\PDOException|\Exception|\Throwable $e) {
if ($this->transTimes > 0) {
// 当前是开启了事务 避免多层事务失效 直接重置事务计数
if ($this->isBreak($e)) {
Expand Down Expand Up @@ -361,7 +361,7 @@ public function execute($str, $fetchSql = false)
}
return $this->numRows;
}
} catch (\PDOException | \Exception | \Throwable $e) {
} catch (\PDOException|\Exception|\Throwable $e) {
if ($this->transTimes > 0) {
// 当前是开启了事务 避免多层事务失效 直接重置事务计数
if ($this->isBreak($e)) {
Expand Down Expand Up @@ -569,19 +569,19 @@ protected function parseSet($data)

if (false !== strpos($key, '->')) {
// 处理局部json字段数据更新
[$key, $name] = explode('->', $key, 2);
$item = $this->parseKey($key);
[$key, $name] = explode('->', $key, 2);
$item = $this->parseKey($key);

if(is_array($val)){
if (is_array($val)) {
// json数据格式保持原样不转义
$val = json_encode($val);
$jsonSql = 'JSON_SET(' . $item . ', \'$.' . $name . '\', CAST(\'' . $val . '\' AS JSON))';
}else{
} else {
$jsonSql = 'JSON_SET(' . $item . ', \'$.' . $name . '\', \'' . $val . '\')';
}

$set[] = $item.'='.$jsonSql;
}elseif (isset($val[0]) && 'exp' == $val[0]) {
$set[] = $item . '=' . $jsonSql;
} elseif (isset($val[0]) && 'exp' == $val[0]) {
$set[] = $this->parseKey($key) . '=' . $val[1];
} elseif (is_null($val)) {
$set[] = $this->parseKey($key) . '=NULL';
Expand Down Expand Up @@ -1000,6 +1000,25 @@ protected function parseHint($hint)
return !empty($hint) ? '/*' . $hint . '*/' : '';
}


/**
* Partition 分析
* @param $partition
* @return string
*/
protected function parsePartition($partition)
{
if ('' == $partition) {
return '';
}

if (is_string($partition)) {
$partition = explode(',', $partition);
}

return ' PARTITION (' . implode(' , ', $partition) . ') ';
}

/**
* distinct分析
* @access protected
Expand Down Expand Up @@ -1111,7 +1130,7 @@ public function insert($data, $options = [], $replace = false)
}
// 兼容数字传入方式
$replace = (is_numeric($replace) && $replace > 0) ? true : $replace;
$sql = (true === $replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') VALUES (' . implode(',', $values) . ')' . $this->parseDuplicate($replace);
$sql = (true === $replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable($options['table']) . $this->parsePartition(!empty($options['partition']) ? $options['partition'] : '') . ' (' . implode(',', $fields) . ') VALUES (' . implode(',', $values) . ')' . $this->parseDuplicate($replace);
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
return $this->execute($sql, !empty($options['fetch_sql']) ? true : false);
}
Expand Down Expand Up @@ -1157,7 +1176,7 @@ public function insertAll($dataSet, $options = [], $replace = false)
}
$values[] = 'SELECT ' . implode(',', $value);
}
$sql = 'INSERT INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') ' . implode(' UNION ALL ', $values);
$sql = 'INSERT INTO ' . $this->parseTable($options['table']) . $this->parsePartition(!empty($options['partition']) ? $options['partition'] : '') . ' (' . implode(',', $fields) . ') ' . implode(' UNION ALL ', $values);
$sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
return $this->execute($sql, !empty($options['fetch_sql']) ? true : false);
}
Expand Down Expand Up @@ -1205,7 +1224,7 @@ public function update($data, $options)
$this->model = $options['model'];
$this->parseBind(!empty($options['bind']) ? $options['bind'] : []);
$table = $this->parseTable($options['table']);
$sql = 'UPDATE ' . $table . $this->parseSet($data);
$sql = 'UPDATE ' . $table . $this->parsePartition(!empty($options['partition']) ? $options['partition'] : '') . $this->parseSet($data);
if (strpos($table, ',')) {
// 多表更新支持JOIN操作
$sql .= $this->parseJoin(!empty($options['join']) ? $options['join'] : '');
Expand Down Expand Up @@ -1236,7 +1255,7 @@ public function delete($options = [])
$this->model = $options['model'];
$this->parseBind(!empty($options['bind']) ? $options['bind'] : []);
$table = $this->parseTable($options['table']);
$sql = 'DELETE FROM ' . $table;
$sql = 'DELETE FROM ' . $table . $this->parsePartition(!empty($options['partition']) ? $options['partition'] : '');
if (strpos($table, ',')) {
// 多表删除支持USING和JOIN操作
if (!empty($options['using'])) {
Expand Down Expand Up @@ -1306,6 +1325,7 @@ public function parseSql($sql, $options = [])
[
'%HINT%',
'%TABLE%',
'%PARTITION%',
'%DISTINCT%',
'%FIELD%',
'%JOIN%',
Expand All @@ -1322,6 +1342,7 @@ public function parseSql($sql, $options = [])
[
$this->parseHint(!empty($options['hint']) ? $options['hint'] : ''),
$this->parseTable($options['table']),
$this->parsePartition(!empty($options['partition']) ? $options['partition'] : ''),
$this->parseDistinct(isset($options['distinct']) ? $options['distinct'] : false),
$this->parseField(!empty($options['field']) ? $options['field'] : '*'),
$this->parseJoin(!empty($options['join']) ? $options['join'] : ''),
Expand Down

0 comments on commit 904bdce

Please sign in to comment.