feat: 同步下新环境

This commit is contained in:
笔记本里的永平
2025-07-07 11:31:25 +08:00
parent 3d1050db3d
commit 86c261ba70
196 changed files with 13146 additions and 29319 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,178 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace think\db;
use ArrayAccess;
class Where implements ArrayAccess
{
/**
* 查询表达式
* @var array
*/
protected $where = [];
/**
* 是否需要增加括号
* @var bool
*/
protected $enclose = false;
/**
* 创建一个查询表达式
*
* @param array $where 查询条件数组
* @param bool $enclose 是否增加括号
*/
public function __construct(array $where = [], $enclose = false)
{
$this->where = $where;
$this->enclose = $enclose;
}
/**
* 设置是否添加括号
* @access public
* @param bool $enclose
* @return $this
*/
public function enclose($enclose = true)
{
$this->enclose = $enclose;
return $this;
}
/**
* 解析为Query对象可识别的查询条件数组
* @access public
* @return array
*/
public function parse()
{
$where = [];
foreach ($this->where as $key => $val) {
if ($val instanceof Expression) {
$where[] = [$key, 'exp', $val];
} elseif (is_null($val)) {
$where[] = [$key, 'NULL', ''];
} elseif (is_array($val)) {
$where[] = $this->parseItem($key, $val);
} else {
$where[] = [$key, '=', $val];
}
}
return $this->enclose ? [$where] : $where;
}
/**
* 分析查询表达式
* @access protected
* @param string $field 查询字段
* @param array $where 查询条件
* @return array
*/
protected function parseItem($field, $where = [])
{
$op = $where[0];
$condition = isset($where[1]) ? $where[1] : null;
if (is_array($op)) {
// 同一字段多条件查询
array_unshift($where, $field);
} elseif (is_null($condition)) {
if (in_array(strtoupper($op), ['NULL', 'NOTNULL', 'NOT NULL'], true)) {
// null查询
$where = [$field, $op, ''];
} elseif (in_array($op, ['=', 'eq', 'EQ', null], true)) {
$where = [$field, 'NULL', ''];
} elseif (in_array($op, ['<>', 'neq', 'NEQ'], true)) {
$where = [$field, 'NOTNULL', ''];
} else {
// 字段相等查询
$where = [$field, '=', $op];
}
} else {
$where = [$field, $op, $condition];
}
return $where;
}
/**
* 修改器 设置数据对象的值
* @access public
* @param string $name 名称
* @param mixed $value 值
* @return void
*/
public function __set($name, $value)
{
$this->where[$name] = $value;
}
/**
* 获取器 获取数据对象的值
* @access public
* @param string $name 名称
* @return mixed
*/
public function __get($name)
{
return isset($this->where[$name]) ? $this->where[$name] : null;
}
/**
* 检测数据对象的值
* @access public
* @param string $name 名称
* @return boolean
*/
public function __isset($name)
{
return isset($this->where[$name]);
}
/**
* 销毁数据对象的值
* @access public
* @param string $name 名称
* @return void
*/
public function __unset($name)
{
unset($this->where[$name]);
}
// ArrayAccess
public function offsetSet($name, $value)
{
$this->__set($name, $value);
}
public function offsetExists($name)
{
return $this->__isset($name);
}
public function offsetUnset($name)
{
$this->__unset($name);
}
public function offsetGet($name)
{
return $this->__get($name);
}
}

View File

@@ -12,8 +12,6 @@
namespace think\db\builder;
use think\db\Builder;
use think\db\Expression;
use think\db\Query;
use think\Exception;
/**
@@ -21,20 +19,6 @@ use think\Exception;
*/
class Mysql extends Builder
{
// 查询表达式解析
protected $parser = [
'parseCompare' => ['=', '<>', '>', '>=', '<', '<='],
'parseLike' => ['LIKE', 'NOT LIKE'],
'parseBetween' => ['NOT BETWEEN', 'BETWEEN'],
'parseIn' => ['NOT IN', 'IN'],
'parseExp' => ['EXP'],
'parseRegexp' => ['REGEXP', 'NOT REGEXP'],
'parseNull' => ['NOT NULL', 'NULL'],
'parseBetweenTime' => ['BETWEEN TIME', 'NOT BETWEEN TIME'],
'parseTime' => ['< TIME', '> TIME', '<= TIME', '>= TIME'],
'parseExists' => ['NOT EXISTS', 'EXISTS'],
'parseColumn' => ['COLUMN'],
];
protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES %DATA% %COMMENT%';
protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
@@ -42,80 +26,67 @@ class Mysql extends Builder
/**
* 生成insertall SQL
* @access public
* @param Query $query 查询对象
* @param array $dataSet 数据集
* @param bool $replace 是否replace
* @param array $dataSet 数据集
* @param array $options 表达式
* @param bool $replace 是否replace
* @return string
* @throws Exception
*/
public function insertAll(Query $query, $dataSet, $replace = false)
public function insertAll($dataSet, $options = [], $replace = false)
{
$options = $query->getOptions();
// 获取合法的字段
if ('*' == $options['field']) {
$allowFields = $this->connection->getTableFields($options['table']);
$fields = array_keys($this->query->getFieldsType($options['table']));
} else {
$allowFields = $options['field'];
$fields = $options['field'];
}
// 获取绑定信息
$bind = $this->connection->getFieldsBind($options['table']);
foreach ($dataSet as $k => $data) {
$data = $this->parseData($query, $data, $allowFields, $bind);
$values[] = '( ' . implode(',', array_values($data)) . ' )';
foreach ($dataSet as $data) {
foreach ($data as $key => $val) {
if (!in_array($key, $fields, true)) {
if ($options['strict']) {
throw new Exception('fields not exists:[' . $key . ']');
}
unset($data[$key]);
} elseif (is_null($val)) {
$data[$key] = 'NULL';
} elseif (is_scalar($val)) {
$data[$key] = $this->parseValue($val, $key);
} elseif (is_object($val) && method_exists($val, '__toString')) {
// 对象数据写入
$data[$key] = $val->__toString();
} else {
// 过滤掉非标量数据
unset($data[$key]);
}
}
$value = array_values($data);
$values[] = '( ' . implode(',', $value) . ' )';
if (!isset($insertFields)) {
$insertFields = array_keys($data);
$insertFields = array_map([$this, 'parseKey'], array_keys($data));
}
}
$fields = [];
foreach ($insertFields as $field) {
$fields[] = $this->parseKey($query, $field);
}
return str_replace(
['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
[
$replace ? 'REPLACE' : 'INSERT',
$this->parseTable($query, $options['table']),
implode(' , ', $fields),
$this->parseTable($options['table'], $options),
implode(' , ', $insertFields),
implode(' , ', $values),
$this->parseComment($query, $options['comment']),
],
$this->insertAllSql);
}
/**
* 正则查询
* @access protected
* @param Query $query 查询对象
* @param string $key
* @param string $exp
* @param mixed $value
* @param string $field
* @return string
*/
protected function parseRegexp(Query $query, $key, $exp, $value, $field)
{
if ($value instanceof Expression) {
$value = $value->getValue();
}
return $key . ' ' . $exp . ' ' . $value;
$this->parseComment($options['comment']),
], $this->insertAllSql);
}
/**
* 字段和表名处理
* @access public
* @param Query $query 查询对象
* @param mixed $key 字段名
* @param bool $strict 严格检测
* @access protected
* @param mixed $key
* @param array $options
* @return string
*/
public function parseKey(Query $query, $key, $strict = false)
protected function parseKey($key, $options = [], $strict = false)
{
if (is_numeric($key)) {
return $key;
@@ -124,59 +95,41 @@ class Mysql extends Builder
}
$key = trim($key);
if(strpos($key, '->>') && false === strpos($key, '(')){
if (strpos($key, '$.') && false === strpos($key, '(')) {
// JSON字段支持
list($field, $name) = explode('->>', $key, 2);
return $this->parseKey($query, $field, true) . '->>\'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->>', '.', $name) . '\'';
}
elseif (strpos($key, '->') && false === strpos($key, '(')) {
// JSON字段支持
list($field, $name) = explode('->', $key, 2);
return 'json_extract(' . $this->parseKey($query, $field, true) . ', \'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->', '.', $name) . '\')';
list($field, $name) = explode('$.', $key);
return 'json_extract(' . $field . ', \'$.' . $name . '\')';
} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
list($table, $key) = explode('.', $key, 2);
$alias = $query->getOptions('alias');
if ('__TABLE__' == $table) {
$table = $query->getOptions('table');
$table = is_array($table) ? array_shift($table) : $table;
$table = $this->query->getTable();
}
if (isset($alias[$table])) {
$table = $alias[$table];
if (isset($options['alias'][$table])) {
$table = $options['alias'][$table];
}
}
if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
throw new Exception('not support data:' . $key);
}
if ('*' != $key && !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) {
$key = '`' . $key . '`';
}
if (isset($table)) {
if (strpos($table, '.')) {
$table = str_replace('.', '`.`', $table);
}
$key = '`' . $table . '`.' . $key;
}
return $key;
}
/**
* 随机排序
* @access protected
* @param Query $query 查询对象
* @return string
*/
protected function parseRand(Query $query)
protected function parseRand()
{
return 'rand()';
}

View File

@@ -12,28 +12,24 @@
namespace think\db\builder;
use think\db\Builder;
use think\db\Query;
/**
* Pgsql数据库驱动
*/
class Pgsql extends Builder
{
protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';
protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';
/**
* limit分析
* @access protected
* @param Query $query 查询对象
* @param mixed $limit
* @param mixed $limit
* @return string
*/
public function parseLimit(Query $query, $limit)
public function parseLimit($limit)
{
$limitStr = '';
if (!empty($limit)) {
$limit = explode(',', $limit);
if (count($limit) > 1) {
@@ -42,19 +38,17 @@ class Pgsql extends Builder
$limitStr .= ' LIMIT ' . $limit[0] . ' ';
}
}
return $limitStr;
}
/**
* 字段和表名处理
* @access public
* @param Query $query 查询对象
* @param mixed $key 字段名
* @param bool $strict 严格检测
* @access protected
* @param mixed $key
* @param array $options
* @return string
*/
public function parseKey(Query $query, $key, $strict = false)
protected function parseKey($key, $options = [], $strict = false)
{
if (is_numeric($key)) {
return $key;
@@ -63,40 +57,31 @@ class Pgsql extends Builder
}
$key = trim($key);
if (strpos($key, '->') && false === strpos($key, '(')) {
if (strpos($key, '$.') && false === strpos($key, '(')) {
// JSON字段支持
list($field, $name) = explode('->', $key);
list($field, $name) = explode('$.', $key);
$key = $field . '->>\'' . $name . '\'';
} elseif (strpos($key, '.')) {
list($table, $key) = explode('.', $key, 2);
$alias = $query->getOptions('alias');
if ('__TABLE__' == $table) {
$table = $query->getOptions('table');
$table = is_array($table) ? array_shift($table) : $table;
$table = $this->query->getTable();
}
if (isset($alias[$table])) {
$table = $alias[$table];
if (isset($options['alias'][$table])) {
$table = $options['alias'][$table];
}
}
if (isset($table)) {
$key = $table . '.' . $key;
}
return $key;
}
/**
* 随机排序
* @access protected
* @param Query $query 查询对象
* @return string
*/
protected function parseRand(Query $query)
protected function parseRand()
{
return 'RANDOM()';
}

View File

@@ -12,7 +12,6 @@
namespace think\db\builder;
use think\db\Builder;
use think\db\Query;
/**
* Sqlite数据库驱动
@@ -23,14 +22,12 @@ class Sqlite extends Builder
/**
* limit
* @access public
* @param Query $query 查询对象
* @param mixed $limit
* @param string $limit
* @return string
*/
public function parseLimit(Query $query, $limit)
public function parseLimit($limit)
{
$limitStr = '';
if (!empty($limit)) {
$limit = explode(',', $limit);
if (count($limit) > 1) {
@@ -39,30 +36,27 @@ class Sqlite extends Builder
$limitStr .= ' LIMIT ' . $limit[0] . ' ';
}
}
return $limitStr;
}
/**
* 随机排序
* @access protected
* @param Query $query 查询对象
* @return string
*/
protected function parseRand(Query $query)
protected function parseRand()
{
return 'RANDOM()';
}
/**
* 字段和表名处理
* @access public
* @param Query $query 查询对象
* @param mixed $key 字段名
* @param bool $strict 严格检测
* @access protected
* @param mixed $key
* @param array $options
* @return string
*/
public function parseKey(Query $query, $key, $strict = false)
protected function parseKey($key, $options = [], $strict = false)
{
if (is_numeric($key)) {
return $key;
@@ -71,26 +65,18 @@ class Sqlite extends Builder
}
$key = trim($key);
if (strpos($key, '.')) {
list($table, $key) = explode('.', $key, 2);
$alias = $query->getOptions('alias');
if ('__TABLE__' == $table) {
$table = $query->getOptions('table');
$table = is_array($table) ? array_shift($table) : $table;
$table = $this->query->getTable();
}
if (isset($alias[$table])) {
$table = $alias[$table];
if (isset($options['alias'][$table])) {
$table = $options['alias'][$table];
}
}
if (isset($table)) {
$key = $table . '.' . $key;
}
return $key;
}
}

View File

@@ -13,8 +13,6 @@ namespace think\db\builder;
use think\db\Builder;
use think\db\Expression;
use think\db\Query;
use think\Exception;
/**
* Sqlsrv数据库驱动
@@ -24,136 +22,116 @@ class Sqlsrv extends Builder
protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%) AS thinkphp) AS T1 %LIMIT%%COMMENT%';
protected $selectInsertSql = 'SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%';
protected $updateSql = 'UPDATE %TABLE% SET %SET% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
protected $deleteSql = 'DELETE FROM %TABLE% %USING% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
protected $deleteSql = 'DELETE FROM %TABLE% %USING% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';
protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';
/**
* order分析
* @access protected
* @param Query $query 查询对象
* @param mixed $order
* @param mixed $order
* @param array $options
* @return string
*/
protected function parseOrder(Query $query, $order)
protected function parseOrder($order, $options = [])
{
if (empty($order)) {
return ' ORDER BY rand()';
}
$array = [];
foreach ($order as $key => $val) {
if ($val instanceof Expression) {
$array[] = $val->getValue();
} elseif ('[rand]' == $val) {
$array[] = $this->parseRand($query);
} elseif (is_numeric($key)) {
if (false === strpos($val, '(')) {
$array[] = $this->parseKey($val, $options);
} elseif ('[rand]' == $val) {
$array[] = $this->parseRand();
} else {
$array[] = $val;
}
} else {
if (is_numeric($key)) {
list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' ');
} else {
$sort = $val;
}
if (preg_match('/^[\w\.]+$/', $key)) {
$sort = strtoupper($sort);
$sort = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : '';
$array[] = $this->parseKey($query, $key, true) . $sort;
} else {
throw new Exception('order express error:' . $key);
}
$sort = in_array(strtolower(trim($val)), ['asc', 'desc'], true) ? ' ' . $val : '';
$array[] = $this->parseKey($key, $options, true) . ' ' . $sort;
}
}
return empty($array) ? '' : ' ORDER BY ' . implode(',', $array);
return ' ORDER BY ' . implode(',', $array);
}
/**
* 随机排序
* @access protected
* @param Query $query 查询对象
* @return string
*/
protected function parseRand(Query $query)
protected function parseRand()
{
return 'rand()';
}
/**
* 字段和表名处理
* @access public
* @param Query $query 查询对象
* @param mixed $key 字段名
* @param bool $strict 严格检测
* @access protected
* @param mixed $key
* @param array $options
* @return string
*/
public function parseKey(Query $query, $key, $strict = false)
protected function parseKey($key, $options = [], $strict = false)
{
if (is_numeric($key)) {
return $key;
} elseif ($key instanceof Expression) {
return $key->getValue();
}
$key = trim($key);
if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) {
list($table, $key) = explode('.', $key, 2);
$alias = $query->getOptions('alias');
if ('__TABLE__' == $table) {
$table = $query->getOptions('table');
$table = is_array($table) ? array_shift($table) : $table;
$table = $this->query->getTable();
}
if (isset($alias[$table])) {
$table = $alias[$table];
if (isset($options['alias'][$table])) {
$table = $options['alias'][$table];
}
}
if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
throw new Exception('not support data:' . $key);
}
if ('*' != $key && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) {
$key = '[' . $key . ']';
}
if (isset($table)) {
$key = '[' . $table . '].' . $key;
}
return $key;
}
/**
* limit
* @access protected
* @param Query $query 查询对象
* @param mixed $limit
* @param mixed $limit
* @return string
*/
protected function parseLimit(Query $query, $limit)
protected function parseLimit($limit)
{
if (empty($limit)) {
return '';
}
$limit = explode(',', $limit);
if (count($limit) > 1) {
$limitStr = '(T1.ROW_NUMBER BETWEEN ' . $limit[0] . ' + 1 AND ' . $limit[0] . ' + ' . $limit[1] . ')';
} else {
$limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND ' . $limit[0] . ")";
}
return 'WHERE ' . $limitStr;
}
public function selectInsert(Query $query, $fields, $table)
public function selectInsert($fields, $table, $options)
{
$this->selectSql = $this->selectInsertSql;
return parent::selectInsert($query, $fields, $table);
return parent::selectInsert($fields, $table, $options);
}
}

View File

@@ -13,7 +13,7 @@ namespace think\db\connector;
use PDO;
use think\db\Connection;
use think\db\Query;
use think\Log;
/**
* mysql数据库驱动
@@ -23,32 +23,10 @@ class Mysql extends Connection
protected $builder = '\\think\\db\\builder\\Mysql';
/**
* 初始化
* @access protected
* @return void
*/
protected function initialize()
{
// Point类型支持
Query::extend('point', function ($query, $field, $value = null, $fun = 'GeomFromText', $type = 'POINT') {
if (!is_null($value)) {
$query->data($field, ['point', $value, $fun, $type]);
} else {
if (is_string($field)) {
$field = explode(',', $field);
}
$query->setOption('point', $field);
}
return $query;
});
}
/**
* 解析pdo连接的dsn信息
* @access protected
* @param array $config 连接信息
* @param array $config 连接信息
* @return string
*/
protected function parseDsn($config)
@@ -65,53 +43,48 @@ class Mysql extends Connection
if (!empty($config['charset'])) {
$dsn .= ';charset=' . $config['charset'];
}
return $dsn;
}
/**
* 取得数据表的字段信息
* @access public
* @param string $tableName
* @param string $tableName
* @return array
*/
public function getFields($tableName)
{
list($tableName) = explode(' ', $tableName);
if (false === strpos($tableName, '`')) {
if (strpos($tableName, '.')) {
$tableName = str_replace('.', '`.`', $tableName);
}
$tableName = '`' . $tableName . '`';
}
$sql = 'SHOW COLUMNS FROM ' . $tableName;
$pdo = $this->query($sql, [], false, true);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
$info = [];
if ($result) {
foreach ($result as $key => $val) {
$val = array_change_key_case($val);
$info[$val['field']] = [
'name' => $val['field'],
'type' => $val['type'],
'notnull' => 'NO' == $val['null'],
'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes
'default' => $val['default'],
'primary' => strtolower($val['key']) == 'pri',
'autoinc' => strtolower($val['extra']) == 'auto_increment',
'primary' => (strtolower($val['key']) == 'pri'),
'autoinc' => (strtolower($val['extra']) == 'auto_increment'),
];
}
}
return $this->fieldCase($info);
}
/**
* 取得数据库的表信息
* @access public
* @param string $dbName
* @param string $dbName
* @return array
*/
public function getTables($dbName = '')
@@ -120,52 +93,28 @@ class Mysql extends Connection
$pdo = $this->query($sql, [], false, true);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
$info = [];
foreach ($result as $key => $val) {
$info[$key] = current($val);
}
return $info;
}
/**
* SQL性能分析
* @access protected
* @param string $sql
* @param string $sql
* @return array
*/
protected function getExplain($sql)
{
$pdo = $this->linkID->prepare("EXPLAIN " . $this->queryStr);
foreach ($this->bind as $key => $val) {
// 占位符
$param = is_int($key) ? $key + 1 : ':' . $key;
if (is_array($val)) {
if (PDO::PARAM_INT == $val[1] && '' === $val[0]) {
$val[0] = 0;
} elseif (self::PARAM_FLOAT == $val[1]) {
$val[0] = is_string($val[0]) ? (float) $val[0] : $val[0];
$val[1] = PDO::PARAM_STR;
}
$result = $pdo->bindValue($param, $val[0], $val[1]);
} else {
$result = $pdo->bindValue($param, $val);
}
}
$pdo->execute();
$pdo = $this->linkID->query("EXPLAIN " . $sql);
$result = $pdo->fetch(PDO::FETCH_ASSOC);
$result = array_change_key_case($result);
if (isset($result['extra'])) {
if (strpos($result['extra'], 'filesort') || strpos($result['extra'], 'temporary')) {
$this->log('SQL:' . $this->queryStr . '[' . $result['extra'] . ']', 'warn');
Log::record('SQL:' . $this->queryStr . '[' . $result['extra'] . ']', 'warn');
}
}
return $result;
}
@@ -174,56 +123,4 @@ class Mysql extends Connection
return true;
}
/**
* 启动XA事务
* @access public
* @param string $xid XA事务id
* @return void
*/
public function startTransXa($xid)
{
$this->initConnect(true);
if (!$this->linkID) {
return false;
}
$this->linkID->exec("XA START '$xid'");
}
/**
* 预编译XA事务
* @access public
* @param string $xid XA事务id
* @return void
*/
public function prepareXa($xid)
{
$this->initConnect(true);
$this->linkID->exec("XA END '$xid'");
$this->linkID->exec("XA PREPARE '$xid'");
}
/**
* 提交XA事务
* @access public
* @param string $xid XA事务id
* @return void
*/
public function commitXa($xid)
{
$this->initConnect(true);
$this->linkID->exec("XA COMMIT '$xid'");
}
/**
* 回滚XA事务
* @access public
* @param string $xid XA事务id
* @return void
*/
public function rollbackXa($xid)
{
$this->initConnect(true);
$this->linkID->exec("XA ROLLBACK '$xid'");
}
}

View File

@@ -21,46 +21,36 @@ class Pgsql extends Connection
{
protected $builder = '\\think\\db\\builder\\Pgsql';
// PDO连接参数
protected $params = [
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
];
/**
* 解析pdo连接的dsn信息
* @access protected
* @param array $config 连接信息
* @param array $config 连接信息
* @return string
*/
protected function parseDsn($config)
{
$dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname'];
if (!empty($config['hostport'])) {
$dsn .= ';port=' . $config['hostport'];
}
return $dsn;
}
/**
* 取得数据表的字段信息
* @access public
* @param string $tableName
* @param string $tableName
* @return array
*/
public function getFields($tableName)
{
list($tableName) = explode(' ', $tableName);
$sql = 'select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(\'' . $tableName . '\');';
$pdo = $this->query($sql, [], false, true);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
$info = [];
if ($result) {
foreach ($result as $key => $val) {
$val = array_change_key_case($val);
@@ -74,14 +64,13 @@ class Pgsql extends Connection
];
}
}
return $this->fieldCase($info);
}
/**
* 取得数据库的表信息
* @access public
* @param string $dbName
* @param string $dbName
* @return array
*/
public function getTables($dbName = '')
@@ -90,18 +79,16 @@ class Pgsql extends Connection
$pdo = $this->query($sql, [], false, true);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
$info = [];
foreach ($result as $key => $val) {
$info[$key] = current($val);
}
return $info;
}
/**
* SQL性能分析
* @access protected
* @param string $sql
* @param string $sql
* @return array
*/
protected function getExplain($sql)

View File

@@ -25,20 +25,19 @@ class Sqlite extends Connection
/**
* 解析pdo连接的dsn信息
* @access protected
* @param array $config 连接信息
* @param array $config 连接信息
* @return string
*/
protected function parseDsn($config)
{
$dsn = 'sqlite:' . $config['database'];
return $dsn;
}
/**
* 取得数据表的字段信息
* @access public
* @param string $tableName
* @param string $tableName
* @return array
*/
public function getFields($tableName)
@@ -49,7 +48,6 @@ class Sqlite extends Connection
$pdo = $this->query($sql, [], false, true);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
$info = [];
if ($result) {
foreach ($result as $key => $val) {
$val = array_change_key_case($val);
@@ -63,18 +61,18 @@ class Sqlite extends Connection
];
}
}
return $this->fieldCase($info);
}
/**
* 取得数据库的表信息
* @access public
* @param string $dbName
* @param string $dbName
* @return array
*/
public function getTables($dbName = '')
{
$sql = "SELECT name FROM sqlite_master WHERE type='table' "
. "UNION ALL SELECT name FROM sqlite_temp_master "
. "WHERE type='table' ORDER BY name";
@@ -82,18 +80,16 @@ class Sqlite extends Connection
$pdo = $this->query($sql, [], false, true);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
$info = [];
foreach ($result as $key => $val) {
$info[$key] = current($val);
}
return $info;
}
/**
* SQL性能分析
* @access protected
* @param string $sql
* @param string $sql
* @return array
*/
protected function getExplain($sql)

View File

@@ -13,7 +13,6 @@ namespace think\db\connector;
use PDO;
use think\db\Connection;
use think\db\Query;
/**
* Sqlsrv数据库驱动
@@ -24,33 +23,28 @@ class Sqlsrv extends Connection
protected $params = [
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
];
protected $builder = '\\think\\db\\builder\\Sqlsrv';
/**
* 解析pdo连接的dsn信息
* @access protected
* @param array $config 连接信息
* @param array $config 连接信息
* @return string
*/
protected function parseDsn($config)
{
$dsn = 'sqlsrv:Database=' . $config['database'] . ';Server=' . $config['hostname'];
if (!empty($config['hostport'])) {
$dsn .= ',' . $config['hostport'];
}
return $dsn;
}
/**
* 取得数据表的字段信息
* @access public
* @param string $tableName
* @param string $tableName
* @return array
*/
public function getFields($tableName)
@@ -70,7 +64,6 @@ class Sqlsrv extends Connection
$pdo = $this->query($sql, [], false, true);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
$info = [];
if ($result) {
foreach ($result as $key => $val) {
$val = array_change_key_case($val);
@@ -84,30 +77,23 @@ class Sqlsrv extends Connection
];
}
}
$sql = "SELECT column_name FROM information_schema.key_column_usage WHERE table_name='$tableName'";
// 调试开始
$this->debug(true);
$pdo = $this->linkID->query($sql);
// 调试结束
$this->debug(false, $sql);
$result = $pdo->fetch(PDO::FETCH_ASSOC);
if ($result) {
$info[$result['column_name']]['primary'] = true;
}
return $this->fieldCase($info);
}
/**
* 取得数据表的字段信息
* @access public
* @param string $dbName
* @param string $dbName
* @return array
*/
public function getTables($dbName = '')
@@ -120,112 +106,16 @@ class Sqlsrv extends Connection
$pdo = $this->query($sql, [], false, true);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
$info = [];
foreach ($result as $key => $val) {
$info[$key] = current($val);
}
return $info;
}
/**
* 得到某个列的数组
* @access public
* @param Query $query 查询对象
* @param string $field 字段名 多个字段用逗号分隔
* @param string $key 索引
* @return array
*/
public function column(Query $query, $field, $key = '')
{
$options = $query->getOptions();
if (empty($options['fetch_sql']) && !empty($options['cache'])) {
// 判断查询缓存
$cache = $options['cache'];
$guid = is_string($cache['key']) ? $cache['key'] : $this->getCacheKey($query, $field);
$result = Container::get('cache')->get($guid);
if (false !== $result) {
return $result;
}
}
if (isset($options['field'])) {
$query->removeOption('field');
}
if (is_null($field)) {
$field = '*';
} elseif ($key && '*' != $field) {
$field = $key . ',' . $field;
}
if (is_string($field)) {
$field = array_map('trim', explode(',', $field));
}
$query->setOption('field', $field);
// 生成查询SQL
$sql = $this->builder->select($query);
$bind = $query->getBind();
if (!empty($options['fetch_sql'])) {
// 获取实际执行的SQL语句
return $this->getRealSql($sql, $bind);
}
// 执行查询操作
$pdo = $this->query($sql, $bind, $options['master'], true);
if (1 == $pdo->columnCount()) {
$result = $pdo->fetchAll(PDO::FETCH_COLUMN);
} else {
$resultSet = $pdo->fetchAll(PDO::FETCH_ASSOC);
if ('*' == $field && $key) {
$result = array_column($resultSet, null, $key);
} elseif ($resultSet) {
$fields = array_keys($resultSet[0]);
$count = count($fields);
$key1 = array_shift($fields);
$key2 = $fields ? array_shift($fields) : '';
$key = $key ?: $key1;
if (strpos($key, '.')) {
list($alias, $key) = explode('.', $key);
}
if (3 == $count) {
$column = $key2;
} elseif ($count < 3) {
$column = $key1;
} else {
$column = null;
}
$result = array_column($resultSet, $column, $key);
} else {
$result = [];
}
}
if (isset($cache) && isset($guid)) {
// 缓存数据
$this->cacheData($guid, $result, $cache);
}
return $result;
}
/**
* SQL性能分析
* @access protected
* @param string $sql
* @param string $sql
* @return array
*/
protected function getExplain($sql)

View File

@@ -37,10 +37,6 @@ DECLARE
v_sql varchar;
v_rec RECORD;
v_key varchar;
v_conkey smallint[];
v_pk varchar[];
v_len smallint;
v_pos smallint := 1;
BEGIN
SELECT
pg_class.oid INTO v_oid
@@ -53,31 +49,6 @@ BEGIN
RETURN;
END IF;
SELECT
pg_constraint.conkey INTO v_conkey
FROM
pg_constraint
INNER JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
INNER JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid
INNER JOIN pg_type ON pg_type.oid = pg_attribute.atttypid
WHERE
pg_class.relname = a_table_name
AND pg_constraint.contype = 'p';
v_len := array_length(v_conkey,1) + 1;
WHILE v_pos < v_len LOOP
SELECT
pg_attribute.attname INTO v_key
FROM pg_constraint
INNER JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
INNER JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = pg_constraint.conkey [ v_conkey[v_pos] ]
INNER JOIN pg_type ON pg_type.oid = pg_attribute.atttypid
WHERE pg_class.relname = a_table_name AND pg_constraint.contype = 'p';
v_pk := array_append(v_pk,v_key);
v_pos := v_pos + 1;
END LOOP;
v_sql='
SELECT
pg_attribute.attname AS fields_name,
@@ -112,19 +83,12 @@ BEGIN
v_ret.fields_not_null=v_rec.fields_not_null;
v_ret.fields_default=v_rec.fields_default;
v_ret.fields_comment=v_rec.fields_comment;
v_ret.fields_key_name='';
v_len := array_length(v_pk,1) + 1;
v_pos := 1;
WHILE v_pos < v_len LOOP
IF v_rec.fields_name = v_pk[v_pos] THEN
v_ret.fields_key_name=v_pk[v_pos];
EXIT;
END IF;
v_pos := v_pos + 1;
END LOOP;
SELECT constraint_name INTO v_key FROM information_schema.key_column_usage WHERE table_schema=a_schema_name AND table_name=a_table_name AND column_name=v_rec.fields_name;
IF FOUND THEN
v_ret.fields_key_name=v_key;
ELSE
v_ret.fields_key_name='';
END IF;
RETURN NEXT v_ret;
END LOOP;
RETURN ;

View File

@@ -21,12 +21,11 @@ class BindParamException extends DbException
/**
* BindParamException constructor.
* @access public
* @param string $message
* @param array $config
* @param string $sql
* @param array $bind
* @param int $code
* @param string $message
* @param array $config
* @param string $sql
* @param array $bind
* @param int $code
*/
public function __construct($message, $config, $sql, $bind, $code = 10502)
{

View File

@@ -19,10 +19,9 @@ class DataNotFoundException extends DbException
/**
* DbException constructor.
* @access public
* @param string $message
* @param string $table
* @param array $config
* @param string $message
* @param string $table
* @param array $config
*/
public function __construct($message, $table = '', array $config = [])
{

View File

@@ -19,10 +19,8 @@ class ModelNotFoundException extends DbException
/**
* 构造方法
* @access public
* @param string $message
* @param string $model
* @param array $config
* @param string $message
* @param string $model
*/
public function __construct($message, $model = '', array $config = [])
{