|
@@ -90,6 +90,8 @@ abstract class Connection
|
|
|
'master_num' => 1,
|
|
|
// 指定从服务器序号
|
|
|
'slave_no' => '',
|
|
|
+ // 模型写入后自动读取主服务器
|
|
|
+ 'read_master' => false,
|
|
|
// 是否严格检查字段是否存在
|
|
|
'fields_strict' => true,
|
|
|
// 数据集返回类型
|
|
@@ -614,7 +616,7 @@ abstract class Connection
|
|
|
$this->PDOStatement->execute();
|
|
|
|
|
|
// 调试结束
|
|
|
- $this->debug(false);
|
|
|
+ $this->debug(false, '', $master);
|
|
|
|
|
|
// 返回结果集
|
|
|
while ($result = $this->PDOStatement->fetch($this->fetchType)) {
|
|
@@ -688,7 +690,7 @@ abstract class Connection
|
|
|
$this->PDOStatement->execute();
|
|
|
|
|
|
// 调试结束
|
|
|
- $this->debug(false);
|
|
|
+ $this->debug(false, '', $master);
|
|
|
|
|
|
// 返回结果集
|
|
|
return $this->getResult($pdo, $procedure);
|
|
@@ -718,13 +720,14 @@ abstract class Connection
|
|
|
* @access public
|
|
|
* @param string $sql sql指令
|
|
|
* @param array $bind 参数绑定
|
|
|
+ * @param Query $query 查询对象
|
|
|
* @return int
|
|
|
* @throws BindParamException
|
|
|
* @throws \PDOException
|
|
|
* @throws \Exception
|
|
|
* @throws \Throwable
|
|
|
*/
|
|
|
- public function execute($sql, $bind = [])
|
|
|
+ public function execute($sql, $bind = [], Query $query = null)
|
|
|
{
|
|
|
$this->initConnect(true);
|
|
|
|
|
@@ -766,26 +769,30 @@ abstract class Connection
|
|
|
$this->PDOStatement->execute();
|
|
|
|
|
|
// 调试结束
|
|
|
- $this->debug(false);
|
|
|
+ $this->debug(false, '', true);
|
|
|
+
|
|
|
+ if ($query && !empty($this->config['deploy']) && !empty($this->config['read_master'])) {
|
|
|
+ $query->readMaster();
|
|
|
+ }
|
|
|
|
|
|
$this->numRows = $this->PDOStatement->rowCount();
|
|
|
|
|
|
return $this->numRows;
|
|
|
} catch (\PDOException $e) {
|
|
|
if ($this->isBreak($e)) {
|
|
|
- return $this->close()->execute($sql, $bind);
|
|
|
+ return $this->close()->execute($sql, $bind, $query);
|
|
|
}
|
|
|
|
|
|
throw new PDOException($e, $this->config, $this->getLastsql());
|
|
|
} catch (\Throwable $e) {
|
|
|
if ($this->isBreak($e)) {
|
|
|
- return $this->close()->execute($sql, $bind);
|
|
|
+ return $this->close()->execute($sql, $bind, $query);
|
|
|
}
|
|
|
|
|
|
throw $e;
|
|
|
} catch (\Exception $e) {
|
|
|
if ($this->isBreak($e)) {
|
|
|
- return $this->close()->execute($sql, $bind);
|
|
|
+ return $this->close()->execute($sql, $bind, $query);
|
|
|
}
|
|
|
|
|
|
throw $e;
|
|
@@ -976,7 +983,7 @@ abstract class Connection
|
|
|
}
|
|
|
|
|
|
// 执行操作
|
|
|
- $result = $this->execute($sql, $bind);
|
|
|
+ $result = $this->execute($sql, $bind, $query);
|
|
|
|
|
|
if ($result) {
|
|
|
$sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);
|
|
@@ -1037,7 +1044,7 @@ abstract class Connection
|
|
|
if (!empty($options['fetch_sql'])) {
|
|
|
$fetchSql[] = $this->getRealSql($sql, $bind);
|
|
|
} else {
|
|
|
- $count += $this->execute($sql, $bind);
|
|
|
+ $count += $this->execute($sql, $bind, $query);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1061,7 +1068,7 @@ abstract class Connection
|
|
|
return $this->getRealSql($sql, $bind);
|
|
|
}
|
|
|
|
|
|
- return $this->execute($sql, $bind);
|
|
|
+ return $this->execute($sql, $bind, $query);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1088,7 +1095,7 @@ abstract class Connection
|
|
|
return $this->getRealSql($sql, $bind);
|
|
|
}
|
|
|
|
|
|
- return $this->execute($sql, $bind);
|
|
|
+ return $this->execute($sql, $bind, $query);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1165,7 +1172,7 @@ abstract class Connection
|
|
|
}
|
|
|
|
|
|
// 执行操作
|
|
|
- $result = '' == $sql ? 0 : $this->execute($sql, $bind);
|
|
|
+ $result = '' == $sql ? 0 : $this->execute($sql, $bind, $query);
|
|
|
|
|
|
if ($result) {
|
|
|
if (is_string($pk) && isset($where[$pk])) {
|
|
@@ -1231,7 +1238,7 @@ abstract class Connection
|
|
|
}
|
|
|
|
|
|
// 执行操作
|
|
|
- $result = $this->execute($sql, $bind);
|
|
|
+ $result = $this->execute($sql, $bind, $query);
|
|
|
|
|
|
if ($result) {
|
|
|
if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) {
|
|
@@ -1261,8 +1268,8 @@ abstract class Connection
|
|
|
$options = $query->getOptions();
|
|
|
|
|
|
if (empty($options['fetch_sql']) && !empty($options['cache'])) {
|
|
|
-
|
|
|
- $result = $this->getCacheData($query, $options['cache'], $field, $key);
|
|
|
+ $cache = $options['cache'];
|
|
|
+ $result = $this->getCacheData($query, $cache, $field, $key);
|
|
|
|
|
|
if (false !== $result) {
|
|
|
return $result;
|
|
@@ -1867,9 +1874,10 @@ abstract class Connection
|
|
|
* @access protected
|
|
|
* @param boolean $start 调试开始标记 true 开始 false 结束
|
|
|
* @param string $sql 执行的SQL语句 留空自动获取
|
|
|
+ * @param bool $master 主从标记
|
|
|
* @return void
|
|
|
*/
|
|
|
- protected function debug($start, $sql = '')
|
|
|
+ protected function debug($start, $sql = '', $master = false)
|
|
|
{
|
|
|
if (!empty($this->config['debug'])) {
|
|
|
// 开启数据库调试模式
|
|
@@ -1890,7 +1898,7 @@ abstract class Connection
|
|
|
}
|
|
|
|
|
|
// SQL监听
|
|
|
- $this->triggerSql($sql, $runtime, $result);
|
|
|
+ $this->triggerSql($sql, $runtime, $result, $master);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1912,19 +1920,27 @@ abstract class Connection
|
|
|
* @param string $sql SQL语句
|
|
|
* @param float $runtime SQL运行时间
|
|
|
* @param mixed $explain SQL分析
|
|
|
- * @return bool
|
|
|
+ * @param bool $master 主从标记
|
|
|
+ * @return void
|
|
|
*/
|
|
|
- protected function triggerSql($sql, $runtime, $explain = [])
|
|
|
+ protected function triggerSql($sql, $runtime, $explain = [], $master = false)
|
|
|
{
|
|
|
if (!empty(self::$event)) {
|
|
|
foreach (self::$event as $callback) {
|
|
|
if (is_callable($callback)) {
|
|
|
- call_user_func_array($callback, [$sql, $runtime, $explain]);
|
|
|
+ call_user_func_array($callback, [$sql, $runtime, $explain, $master]);
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
+ if ($this->config['deploy']) {
|
|
|
+ // 分布式记录当前操作的主从
|
|
|
+ $master = $master ? 'master|' : 'slave|';
|
|
|
+ } else {
|
|
|
+ $master = '';
|
|
|
+ }
|
|
|
+
|
|
|
// 未注册监听则记录到日志中
|
|
|
- $this->log('[ SQL ] ' . $sql . ' [ RunTime:' . $runtime . 's ]');
|
|
|
+ $this->log('[ SQL ] ' . $sql . ' [ ' . $master . 'RunTime:' . $runtime . 's ]');
|
|
|
|
|
|
if (!empty($explain)) {
|
|
|
$this->log('[ EXPLAIN : ' . var_export($explain, true) . ' ]');
|