添加网站文件
This commit is contained in:
1173
thinkphp/library/think/db/Builder.php
Normal file
1173
thinkphp/library/think/db/Builder.php
Normal file
File diff suppressed because it is too large
Load Diff
2152
thinkphp/library/think/db/Connection.php
Normal file
2152
thinkphp/library/think/db/Connection.php
Normal file
File diff suppressed because it is too large
Load Diff
48
thinkphp/library/think/db/Expression.php
Normal file
48
thinkphp/library/think/db/Expression.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?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;
|
||||
|
||||
class Expression
|
||||
{
|
||||
/**
|
||||
* 查询表达式
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* 创建一个查询表达式
|
||||
*
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表达式
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->value;
|
||||
}
|
||||
}
|
||||
3766
thinkphp/library/think/db/Query.php
Normal file
3766
thinkphp/library/think/db/Query.php
Normal file
File diff suppressed because it is too large
Load Diff
178
thinkphp/library/think/db/Where.php
Normal file
178
thinkphp/library/think/db/Where.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?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);
|
||||
}
|
||||
|
||||
}
|
||||
184
thinkphp/library/think/db/builder/Mysql.php
Normal file
184
thinkphp/library/think/db/builder/Mysql.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?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\builder;
|
||||
|
||||
use think\db\Builder;
|
||||
use think\db\Expression;
|
||||
use think\db\Query;
|
||||
use think\Exception;
|
||||
|
||||
/**
|
||||
* mysql数据库驱动
|
||||
*/
|
||||
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%';
|
||||
|
||||
/**
|
||||
* 生成insertall SQL
|
||||
* @access public
|
||||
* @param Query $query 查询对象
|
||||
* @param array $dataSet 数据集
|
||||
* @param bool $replace 是否replace
|
||||
* @return string
|
||||
*/
|
||||
public function insertAll(Query $query, $dataSet, $replace = false)
|
||||
{
|
||||
$options = $query->getOptions();
|
||||
|
||||
// 获取合法的字段
|
||||
if ('*' == $options['field']) {
|
||||
$allowFields = $this->connection->getTableFields($options['table']);
|
||||
} else {
|
||||
$allowFields = $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)) . ' )';
|
||||
|
||||
if (!isset($insertFields)) {
|
||||
$insertFields = 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),
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段和表名处理
|
||||
* @access public
|
||||
* @param Query $query 查询对象
|
||||
* @param mixed $key 字段名
|
||||
* @param bool $strict 严格检测
|
||||
* @return string
|
||||
*/
|
||||
public function parseKey(Query $query, $key, $strict = false)
|
||||
{
|
||||
if (is_numeric($key)) {
|
||||
return $key;
|
||||
} elseif ($key instanceof Expression) {
|
||||
return $key->getValue();
|
||||
}
|
||||
|
||||
$key = trim($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) . '\')';
|
||||
} 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;
|
||||
}
|
||||
|
||||
if (isset($alias[$table])) {
|
||||
$table = $alias[$table];
|
||||
}
|
||||
}
|
||||
|
||||
if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
|
||||
throw new Exception('not support data:' . $key);
|
||||
}
|
||||
|
||||
if ('*' != $key && !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)
|
||||
{
|
||||
return 'rand()';
|
||||
}
|
||||
|
||||
}
|
||||
104
thinkphp/library/think/db/builder/Pgsql.php
Normal file
104
thinkphp/library/think/db/builder/Pgsql.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?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\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
|
||||
* @return string
|
||||
*/
|
||||
public function parseLimit(Query $query, $limit)
|
||||
{
|
||||
$limitStr = '';
|
||||
|
||||
if (!empty($limit)) {
|
||||
$limit = explode(',', $limit);
|
||||
if (count($limit) > 1) {
|
||||
$limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' ';
|
||||
} else {
|
||||
$limitStr .= ' LIMIT ' . $limit[0] . ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return $limitStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段和表名处理
|
||||
* @access public
|
||||
* @param Query $query 查询对象
|
||||
* @param mixed $key 字段名
|
||||
* @param bool $strict 严格检测
|
||||
* @return string
|
||||
*/
|
||||
public function parseKey(Query $query, $key, $strict = false)
|
||||
{
|
||||
if (is_numeric($key)) {
|
||||
return $key;
|
||||
} elseif ($key instanceof Expression) {
|
||||
return $key->getValue();
|
||||
}
|
||||
|
||||
$key = trim($key);
|
||||
|
||||
if (strpos($key, '->') && false === strpos($key, '(')) {
|
||||
// JSON字段支持
|
||||
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;
|
||||
}
|
||||
|
||||
if (isset($alias[$table])) {
|
||||
$table = $alias[$table];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($table)) {
|
||||
$key = $table . '.' . $key;
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机排序
|
||||
* @access protected
|
||||
* @param Query $query 查询对象
|
||||
* @return string
|
||||
*/
|
||||
protected function parseRand(Query $query)
|
||||
{
|
||||
return 'RANDOM()';
|
||||
}
|
||||
|
||||
}
|
||||
96
thinkphp/library/think/db/builder/Sqlite.php
Normal file
96
thinkphp/library/think/db/builder/Sqlite.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?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\builder;
|
||||
|
||||
use think\db\Builder;
|
||||
use think\db\Query;
|
||||
|
||||
/**
|
||||
* Sqlite数据库驱动
|
||||
*/
|
||||
class Sqlite extends Builder
|
||||
{
|
||||
|
||||
/**
|
||||
* limit
|
||||
* @access public
|
||||
* @param Query $query 查询对象
|
||||
* @param mixed $limit
|
||||
* @return string
|
||||
*/
|
||||
public function parseLimit(Query $query, $limit)
|
||||
{
|
||||
$limitStr = '';
|
||||
|
||||
if (!empty($limit)) {
|
||||
$limit = explode(',', $limit);
|
||||
if (count($limit) > 1) {
|
||||
$limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' ';
|
||||
} else {
|
||||
$limitStr .= ' LIMIT ' . $limit[0] . ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return $limitStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机排序
|
||||
* @access protected
|
||||
* @param Query $query 查询对象
|
||||
* @return string
|
||||
*/
|
||||
protected function parseRand(Query $query)
|
||||
{
|
||||
return 'RANDOM()';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段和表名处理
|
||||
* @access public
|
||||
* @param Query $query 查询对象
|
||||
* @param mixed $key 字段名
|
||||
* @param bool $strict 严格检测
|
||||
* @return string
|
||||
*/
|
||||
public function parseKey(Query $query, $key, $strict = false)
|
||||
{
|
||||
if (is_numeric($key)) {
|
||||
return $key;
|
||||
} elseif ($key instanceof Expression) {
|
||||
return $key->getValue();
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
if (isset($alias[$table])) {
|
||||
$table = $alias[$table];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($table)) {
|
||||
$key = $table . '.' . $key;
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
159
thinkphp/library/think/db/builder/Sqlsrv.php
Normal file
159
thinkphp/library/think/db/builder/Sqlsrv.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\db\builder;
|
||||
|
||||
use think\db\Builder;
|
||||
use think\db\Expression;
|
||||
use think\db\Query;
|
||||
use think\Exception;
|
||||
|
||||
/**
|
||||
* Sqlsrv数据库驱动
|
||||
*/
|
||||
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 $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
|
||||
* @return string
|
||||
*/
|
||||
protected function parseOrder(Query $query, $order)
|
||||
{
|
||||
if (empty($order)) {
|
||||
return ' ORDER BY rand()';
|
||||
}
|
||||
|
||||
foreach ($order as $key => $val) {
|
||||
if ($val instanceof Expression) {
|
||||
$array[] = $val->getValue();
|
||||
} elseif ('[rand]' == $val) {
|
||||
$array[] = $this->parseRand($query);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return empty($array) ? '' : ' ORDER BY ' . implode(',', $array);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机排序
|
||||
* @access protected
|
||||
* @param Query $query 查询对象
|
||||
* @return string
|
||||
*/
|
||||
protected function parseRand(Query $query)
|
||||
{
|
||||
return 'rand()';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段和表名处理
|
||||
* @access public
|
||||
* @param Query $query 查询对象
|
||||
* @param mixed $key 字段名
|
||||
* @param bool $strict 严格检测
|
||||
* @return string
|
||||
*/
|
||||
public function parseKey(Query $query, $key, $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;
|
||||
}
|
||||
|
||||
if (isset($alias[$table])) {
|
||||
$table = $alias[$table];
|
||||
}
|
||||
}
|
||||
|
||||
if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
|
||||
throw new Exception('not support data:' . $key);
|
||||
}
|
||||
|
||||
if ('*' != $key && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
|
||||
$key = '[' . $key . ']';
|
||||
}
|
||||
|
||||
if (isset($table)) {
|
||||
$key = '[' . $table . '].' . $key;
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* limit
|
||||
* @access protected
|
||||
* @param Query $query 查询对象
|
||||
* @param mixed $limit
|
||||
* @return string
|
||||
*/
|
||||
protected function parseLimit(Query $query, $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)
|
||||
{
|
||||
$this->selectSql = $this->selectInsertSql;
|
||||
|
||||
return parent::selectInsert($query, $fields, $table);
|
||||
}
|
||||
|
||||
}
|
||||
229
thinkphp/library/think/db/connector/Mysql.php
Normal file
229
thinkphp/library/think/db/connector/Mysql.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?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\connector;
|
||||
|
||||
use PDO;
|
||||
use think\db\Connection;
|
||||
use think\db\Query;
|
||||
|
||||
/**
|
||||
* mysql数据库驱动
|
||||
*/
|
||||
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 连接信息
|
||||
* @return string
|
||||
*/
|
||||
protected function parseDsn($config)
|
||||
{
|
||||
if (!empty($config['socket'])) {
|
||||
$dsn = 'mysql:unix_socket=' . $config['socket'];
|
||||
} elseif (!empty($config['hostport'])) {
|
||||
$dsn = 'mysql:host=' . $config['hostname'] . ';port=' . $config['hostport'];
|
||||
} else {
|
||||
$dsn = 'mysql:host=' . $config['hostname'];
|
||||
}
|
||||
$dsn .= ';dbname=' . $config['database'];
|
||||
|
||||
if (!empty($config['charset'])) {
|
||||
$dsn .= ';charset=' . $config['charset'];
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得数据表的字段信息
|
||||
* @access public
|
||||
* @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'],
|
||||
'default' => $val['default'],
|
||||
'primary' => strtolower($val['key']) == 'pri',
|
||||
'autoinc' => strtolower($val['extra']) == 'auto_increment',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fieldCase($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得数据库的表信息
|
||||
* @access public
|
||||
* @param string $dbName
|
||||
* @return array
|
||||
*/
|
||||
public function getTables($dbName = '')
|
||||
{
|
||||
$sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES ';
|
||||
$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
|
||||
* @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();
|
||||
$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');
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function supportSavepoint()
|
||||
{
|
||||
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'");
|
||||
}
|
||||
}
|
||||
116
thinkphp/library/think/db/connector/Pgsql.php
Normal file
116
thinkphp/library/think/db/connector/Pgsql.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?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\connector;
|
||||
|
||||
use PDO;
|
||||
use think\db\Connection;
|
||||
|
||||
/**
|
||||
* Pgsql数据库驱动
|
||||
*/
|
||||
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 连接信息
|
||||
* @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
|
||||
* @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);
|
||||
$info[$val['field']] = [
|
||||
'name' => $val['field'],
|
||||
'type' => $val['type'],
|
||||
'notnull' => (bool) ('' !== $val['null']),
|
||||
'default' => $val['default'],
|
||||
'primary' => !empty($val['key']),
|
||||
'autoinc' => (0 === strpos($val['extra'], 'nextval(')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fieldCase($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得数据库的表信息
|
||||
* @access public
|
||||
* @param string $dbName
|
||||
* @return array
|
||||
*/
|
||||
public function getTables($dbName = '')
|
||||
{
|
||||
$sql = "select tablename as Tables_in_test from pg_tables where schemaname ='public'";
|
||||
$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
|
||||
* @return array
|
||||
*/
|
||||
protected function getExplain($sql)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function supportSavepoint()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
108
thinkphp/library/think/db/connector/Sqlite.php
Normal file
108
thinkphp/library/think/db/connector/Sqlite.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?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\connector;
|
||||
|
||||
use PDO;
|
||||
use think\db\Connection;
|
||||
|
||||
/**
|
||||
* Sqlite数据库驱动
|
||||
*/
|
||||
class Sqlite extends Connection
|
||||
{
|
||||
|
||||
protected $builder = '\\think\\db\\builder\\Sqlite';
|
||||
|
||||
/**
|
||||
* 解析pdo连接的dsn信息
|
||||
* @access protected
|
||||
* @param array $config 连接信息
|
||||
* @return string
|
||||
*/
|
||||
protected function parseDsn($config)
|
||||
{
|
||||
$dsn = 'sqlite:' . $config['database'];
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得数据表的字段信息
|
||||
* @access public
|
||||
* @param string $tableName
|
||||
* @return array
|
||||
*/
|
||||
public function getFields($tableName)
|
||||
{
|
||||
list($tableName) = explode(' ', $tableName);
|
||||
$sql = 'PRAGMA table_info( ' . $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['name']] = [
|
||||
'name' => $val['name'],
|
||||
'type' => $val['type'],
|
||||
'notnull' => 1 === $val['notnull'],
|
||||
'default' => $val['dflt_value'],
|
||||
'primary' => '1' == $val['pk'],
|
||||
'autoinc' => '1' == $val['pk'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fieldCase($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得数据库的表信息
|
||||
* @access public
|
||||
* @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";
|
||||
|
||||
$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
|
||||
* @return array
|
||||
*/
|
||||
protected function getExplain($sql)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function supportSavepoint()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
235
thinkphp/library/think/db/connector/Sqlsrv.php
Normal file
235
thinkphp/library/think/db/connector/Sqlsrv.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\db\connector;
|
||||
|
||||
use PDO;
|
||||
use think\db\Connection;
|
||||
use think\db\Query;
|
||||
|
||||
/**
|
||||
* Sqlsrv数据库驱动
|
||||
*/
|
||||
class Sqlsrv extends Connection
|
||||
{
|
||||
// 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,
|
||||
];
|
||||
|
||||
protected $builder = '\\think\\db\\builder\\Sqlsrv';
|
||||
|
||||
/**
|
||||
* 解析pdo连接的dsn信息
|
||||
* @access protected
|
||||
* @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
|
||||
* @return array
|
||||
*/
|
||||
public function getFields($tableName)
|
||||
{
|
||||
list($tableName) = explode(' ', $tableName);
|
||||
$tableNames = explode('.', $tableName);
|
||||
$tableName = isset($tableNames[1]) ? $tableNames[1] : $tableNames[0];
|
||||
|
||||
$sql = "SELECT column_name, data_type, column_default, is_nullable
|
||||
FROM information_schema.tables AS t
|
||||
JOIN information_schema.columns AS c
|
||||
ON t.table_catalog = c.table_catalog
|
||||
AND t.table_schema = c.table_schema
|
||||
AND t.table_name = c.table_name
|
||||
WHERE t.table_name = '$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['column_name']] = [
|
||||
'name' => $val['column_name'],
|
||||
'type' => $val['data_type'],
|
||||
'notnull' => (bool) ('' === $val['is_nullable']), // not null is empty, null is yes
|
||||
'default' => $val['column_default'],
|
||||
'primary' => false,
|
||||
'autoinc' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$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
|
||||
* @return array
|
||||
*/
|
||||
public function getTables($dbName = '')
|
||||
{
|
||||
$sql = "SELECT TABLE_NAME
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_TYPE = 'BASE TABLE'
|
||||
";
|
||||
|
||||
$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
|
||||
* @return array
|
||||
*/
|
||||
protected function getExplain($sql)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
153
thinkphp/library/think/db/connector/pgsql.sql
Normal file
153
thinkphp/library/think/db/connector/pgsql.sql
Normal file
@@ -0,0 +1,153 @@
|
||||
CREATE OR REPLACE FUNCTION pgsql_type(a_type varchar) RETURNS varchar AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_type varchar;
|
||||
BEGIN
|
||||
IF a_type='int8' THEN
|
||||
v_type:='bigint';
|
||||
ELSIF a_type='int4' THEN
|
||||
v_type:='integer';
|
||||
ELSIF a_type='int2' THEN
|
||||
v_type:='smallint';
|
||||
ELSIF a_type='bpchar' THEN
|
||||
v_type:='char';
|
||||
ELSE
|
||||
v_type:=a_type;
|
||||
END IF;
|
||||
RETURN v_type;
|
||||
END;
|
||||
$BODY$
|
||||
LANGUAGE PLPGSQL;
|
||||
|
||||
CREATE TYPE "public"."tablestruct" AS (
|
||||
"fields_key_name" varchar(100),
|
||||
"fields_name" VARCHAR(200),
|
||||
"fields_type" VARCHAR(20),
|
||||
"fields_length" BIGINT,
|
||||
"fields_not_null" VARCHAR(10),
|
||||
"fields_default" VARCHAR(500),
|
||||
"fields_comment" VARCHAR(1000)
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION "public"."table_msg" (a_schema_name varchar, a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS
|
||||
$body$
|
||||
DECLARE
|
||||
v_ret tablestruct;
|
||||
v_oid oid;
|
||||
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
|
||||
FROM
|
||||
pg_class
|
||||
INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid AND lower(pg_namespace.nspname) = a_schema_name)
|
||||
WHERE
|
||||
pg_class.relname=a_table_name;
|
||||
IF NOT FOUND THEN
|
||||
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,
|
||||
pg_attribute.attnum AS fields_index,
|
||||
pgsql_type(pg_type.typname::varchar) AS fields_type,
|
||||
pg_attribute.atttypmod-4 as fields_length,
|
||||
CASE WHEN pg_attribute.attnotnull THEN ''not null''
|
||||
ELSE ''''
|
||||
END AS fields_not_null,
|
||||
pg_attrdef.adsrc AS fields_default,
|
||||
pg_description.description AS fields_comment
|
||||
FROM
|
||||
pg_attribute
|
||||
INNER JOIN pg_class ON pg_attribute.attrelid = pg_class.oid
|
||||
INNER JOIN pg_type ON pg_attribute.atttypid = pg_type.oid
|
||||
LEFT OUTER JOIN pg_attrdef ON pg_attrdef.adrelid = pg_class.oid AND pg_attrdef.adnum = pg_attribute.attnum
|
||||
LEFT OUTER JOIN pg_description ON pg_description.objoid = pg_class.oid AND pg_description.objsubid = pg_attribute.attnum
|
||||
WHERE
|
||||
pg_attribute.attnum > 0
|
||||
AND attisdropped <> ''t''
|
||||
AND pg_class.oid = ' || v_oid || '
|
||||
ORDER BY pg_attribute.attnum' ;
|
||||
|
||||
FOR v_rec IN EXECUTE v_sql LOOP
|
||||
v_ret.fields_name=v_rec.fields_name;
|
||||
v_ret.fields_type=v_rec.fields_type;
|
||||
IF v_rec.fields_length > 0 THEN
|
||||
v_ret.fields_length:=v_rec.fields_length;
|
||||
ELSE
|
||||
v_ret.fields_length:=NULL;
|
||||
END IF;
|
||||
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;
|
||||
|
||||
RETURN NEXT v_ret;
|
||||
END LOOP;
|
||||
RETURN ;
|
||||
END;
|
||||
$body$
|
||||
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
|
||||
|
||||
COMMENT ON FUNCTION "public"."table_msg"(a_schema_name varchar, a_table_name varchar)
|
||||
IS '获得表信息';
|
||||
|
||||
---重载一个函数
|
||||
CREATE OR REPLACE FUNCTION "public"."table_msg" (a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS
|
||||
$body$
|
||||
DECLARE
|
||||
v_ret tablestruct;
|
||||
BEGIN
|
||||
FOR v_ret IN SELECT * FROM table_msg('public',a_table_name) LOOP
|
||||
RETURN NEXT v_ret;
|
||||
END LOOP;
|
||||
RETURN;
|
||||
END;
|
||||
$body$
|
||||
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
|
||||
|
||||
COMMENT ON FUNCTION "public"."table_msg"(a_table_name varchar)
|
||||
IS '获得表信息';
|
||||
36
thinkphp/library/think/db/exception/BindParamException.php
Normal file
36
thinkphp/library/think/db/exception/BindParamException.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?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: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\db\exception;
|
||||
|
||||
use think\exception\DbException;
|
||||
|
||||
/**
|
||||
* PDO参数绑定异常
|
||||
*/
|
||||
class BindParamException extends DbException
|
||||
{
|
||||
|
||||
/**
|
||||
* BindParamException constructor.
|
||||
* @access public
|
||||
* @param string $message
|
||||
* @param array $config
|
||||
* @param string $sql
|
||||
* @param array $bind
|
||||
* @param int $code
|
||||
*/
|
||||
public function __construct($message, $config, $sql, $bind, $code = 10502)
|
||||
{
|
||||
$this->setData('Bind Param', $bind);
|
||||
parent::__construct($message, $config, $sql, $code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?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: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\db\exception;
|
||||
|
||||
use think\exception\DbException;
|
||||
|
||||
class DataNotFoundException extends DbException
|
||||
{
|
||||
protected $table;
|
||||
|
||||
/**
|
||||
* DbException constructor.
|
||||
* @access public
|
||||
* @param string $message
|
||||
* @param string $table
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($message, $table = '', array $config = [])
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->table = $table;
|
||||
|
||||
$this->setData('Database Config', $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据表名
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\db\exception;
|
||||
|
||||
use think\exception\DbException;
|
||||
|
||||
class ModelNotFoundException extends DbException
|
||||
{
|
||||
protected $model;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* @access public
|
||||
* @param string $message
|
||||
* @param string $model
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($message, $model = '', array $config = [])
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->model = $model;
|
||||
|
||||
$this->setData('Database Config', $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型类名
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getModel()
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user