更新数据库驱动类

增加各自的parseDsn方法
This commit is contained in:
ThinkPHP
2013-04-27 12:29:18 +08:00
parent 2c5b98888c
commit ee0b30ec6e
5 changed files with 608 additions and 548 deletions

View File

@@ -1,75 +1,91 @@
<?php <?php
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
namespace Think\Db\Driver; namespace Think\Db\Driver;
use Think\Db\Driver; use Think\Db\Driver;
/** /**
* mysql数据库驱动 * mysql数据库驱动
* @category Extend */
* @package Extend class Mysql extends Driver{
* @subpackage Driver.Db
* @author liu21st <liu21st@gmail.com> /**
*/ * 解析pdo连接的dsn信息
class Mysql extends Driver{ * @access public
/** * @param array $config 连接信息
* 取得数据表的字段信息 * @return string
* @access public */
*/ protected function parseDsn($config){
public function getFields($tableName) { $dsn = 'mysql:dbname='.$config['database'].';host='.$config['hostname'];
$this->initConnect(true); if(!empty($config['hostport'])) {
$sql = 'SHOW COLUMNS FROM `'.$tableName.'`'; $dsn .= ';port='.$config['hostport'];
$result = $this->query($sql); }elseif(!empty($config['socket'])){
$info = []; $dsn .= ';unix_socket='.$config['socket'];
if($result) { }
foreach ($result as $key => $val) { if(!empty($config['charset'])){
$info[$val['field']] = [ $dsn .= ';charset='.$config['charset'];
'name' => $val['field'], }
'type' => $val['type'], return $dsn;
'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'), * 取得数据表的字段信息
]; * @access public
} */
} public function getFields($tableName) {
return $info; $this->initConnect(true);
} $sql = 'SHOW COLUMNS FROM `'.$tableName.'`';
$result = $this->query($sql);
/** $info = [];
* 取得数据库的表信息 if($result) {
* @access public foreach ($result as $key => $val) {
*/ $info[$val['field']] = [
public function getTables($dbName='') { 'name' => $val['field'],
$sql = !empty($dbName)?'SHOW TABLES FROM '.$dbName:'SHOW TABLES '; 'type' => $val['type'],
$result = $this->query($sql); 'notnull' => (bool) ($val['null'] === ''), // not null is empty, null is yes
$info = []; 'default' => $val['default'],
foreach ($result as $key => $val) { 'primary' => (strtolower($val['key']) == 'pri'),
$info[$key] = current($val); 'autoinc' => (strtolower($val['extra']) == 'auto_increment'),
} ];
return $info; }
} }
return $info;
/** }
* 字段和表名处理
* @access protected /**
* @param string $key * 取得数据库的表信息
* @return string * @access public
*/ */
protected function parseKey(&$key) { public function getTables($dbName='') {
$key = trim($key); $sql = !empty($dbName)?'SHOW TABLES FROM '.$dbName:'SHOW TABLES ';
if(!preg_match('/[,\'\"\*\(\)`.\s]/',$key)) { $result = $this->query($sql);
$key = '`'.$key.'`'; $info = [];
} foreach ($result as $key => $val) {
return $key; $info[$key] = current($val);
} }
return $info;
} }
/**
* 字段和表名处理
* @access protected
* @param string $key
* @return string
*/
protected function parseKey(&$key) {
$key = trim($key);
if(!preg_match('/[,\'\"\*\(\)`.\s]/',$key)) {
$key = '`'.$key.'`';
}
return $key;
}
}

View File

@@ -1,172 +1,182 @@
<?php <?php
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
namespace Think\Db\Driver; namespace Think\Db\Driver;
use Think\Db\Driver; use Think\Db\Driver;
/** /**
* Oracle数据库驱动 * Oracle数据库驱动
* @category Extend */
* @package Extend class Oracle extends Driver{
* @subpackage Driver.Db
* @author ZhangXuehun <zhangxuehun@sohu.com> private $table = '';
*/ protected $selectSql = 'SELECT * FROM (SELECT thinkphp.*, rownum AS numrow FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%) thinkphp ) %LIMIT%%COMMENT%';
class Oracle extends Driver{
/**
private $table = ''; * 解析pdo连接的dsn信息
protected $selectSql = 'SELECT * FROM (SELECT thinkphp.*, rownum AS numrow FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%) thinkphp ) %LIMIT%%COMMENT%'; * @access public
* @param array $config 连接信息
/** * @return string
* 执行语句 */
* @access public protected function parseDsn($config){
* @param string $str sql指令 $dsn = 'oci:dbname='.$config['database'];
* @return integer if(!empty($config['charset'])) {
*/ $dsn .= ';charset='.$config['charset'];
public function execute($str,$bind=[]) { }
$this->initConnect(true); return $dsn;
if ( !$this->_linkID ) return false; }
$this->queryStr = $str;
$flag = false; /**
if(preg_match("/^\s*(INSERT\s+INTO)\s+(\w+)\s+/i", $this->queryStr, $match)) { * 执行语句
$this->table = C("DB_SEQUENCE_PREFIX").str_ireplace(C("DB_PREFIX"), "", $match[2]); * @access public
$flag = (boolean)$this->query("SELECT * FROM user_sequences WHERE sequence_name='" . strtoupper($this->table) . "'"); * @param string $str sql指令
} * @return integer
//释放前次的查询结果 */
if ( !empty($this->PDOStatement) ) $this->free(); public function execute($str,$bind=[]) {
$this->executeTimes++; $this->initConnect(true);
// 记录开始执行时间 if ( !$this->_linkID ) return false;
$this->debug(true); $this->queryStr = $str;
$this->PDOStatement = $this->_linkID->prepare($str); $flag = false;
if(false === $this->PDOStatement) { if(preg_match("/^\s*(INSERT\s+INTO)\s+(\w+)\s+/i", $this->queryStr, $match)) {
E($this->error()); $this->table = C("DB_SEQUENCE_PREFIX").str_ireplace(C("DB_PREFIX"), "", $match[2]);
} $flag = (boolean)$this->query("SELECT * FROM user_sequences WHERE sequence_name='" . strtoupper($this->table) . "'");
$result = $this->PDOStatement->execute($bind); }
$this->debug(false); //释放前次的查询结果
if ( false === $result) { if ( !empty($this->PDOStatement) ) $this->free();
$this->error(); $this->executeTimes++;
return false; // 记录开始执行时间
} else { $this->debug(true);
$this->numRows = $this->PDOStatement->rowCount(); $this->PDOStatement = $this->_linkID->prepare($str);
if($flag || preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { if(false === $this->PDOStatement) {
$this->lastInsID = $this->getLastInsertId(); E($this->error());
} }
return $this->numRows; $result = $this->PDOStatement->execute($bind);
} $this->debug(false);
} if ( false === $result) {
$this->error();
/** return false;
* 取得数据表的字段信息 } else {
* @access public $this->numRows = $this->PDOStatement->rowCount();
*/ if($flag || preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) {
public function getFields($tableName) { $this->lastInsID = $this->getLastInsertId();
$result = $this->query("select a.column_name,data_type,decode(nullable,'Y',0,1) notnull,data_default,decode(a.column_name,b.column_name,1,0) pk " }
."from user_tab_columns a,(select column_name from user_constraints c,user_cons_columns col " return $this->numRows;
."where c.constraint_name=col.constraint_name and c.constraint_type='P'and c.table_name='".strtoupper($tableName) }
."') b where table_name='".strtoupper($tableName)."' and a.column_name=b.column_name(+)"); }
$info = [];
if($result) { /**
foreach ($result as $key => $val) { * 取得数据表的字段信息
$info[strtolower($val['column_name'])] = [ * @access public
'name' => strtolower($val['column_name']), */
'type' => strtolower($val['data_type']), public function getFields($tableName) {
'notnull' => $val['notnull'], $result = $this->query("select a.column_name,data_type,decode(nullable,'Y',0,1) notnull,data_default,decode(a.column_name,b.column_name,1,0) pk "
'default' => $val['data_default'], ."from user_tab_columns a,(select column_name from user_constraints c,user_cons_columns col "
'primary' => $val['pk'], ."where c.constraint_name=col.constraint_name and c.constraint_type='P'and c.table_name='".strtoupper($tableName)
'autoinc' => $val['pk'], ."') b where table_name='".strtoupper($tableName)."' and a.column_name=b.column_name(+)");
]; $info = [];
} if($result) {
} foreach ($result as $key => $val) {
return $info; $info[strtolower($val['column_name'])] = [
} 'name' => strtolower($val['column_name']),
'type' => strtolower($val['data_type']),
/** 'notnull' => $val['notnull'],
* 取得数据库的表信息(暂时实现取得用户表信息) 'default' => $val['data_default'],
* @access public 'primary' => $val['pk'],
*/ 'autoinc' => $val['pk'],
public function getTables($dbName='') { ];
$result = $this->query("select table_name from user_tables"); }
$info = []; }
foreach ($result as $key => $val) { return $info;
$info[$key] = current($val); }
}
return $info; /**
} * 取得数据库的表信息(暂时实现取得用户表信息)
* @access public
/** */
* SQL指令安全过滤 public function getTables($dbName='') {
* @access public $result = $this->query("select table_name from user_tables");
* @param string $str SQL指令 $info = [];
* @return string foreach ($result as $key => $val) {
*/ $info[$key] = current($val);
public function escapeString($str) { }
return str_ireplace("'", "''", $str); return $info;
} }
/** /**
* 获取最后插入id ,仅适用于采用序列+触发器结合生成ID的方式 * SQL指令安全过滤
* 在config.php中指定 * @access public
* 'DB_TRIGGER_PREFIX' => 'tr_', * @param string $str SQL指令
* 'DB_SEQUENCE_PREFIX' => 'ts_', * @return string
* eg:表 tb_user */
* 相对tb_user的序列为 public function escapeString($str) {
* -- Create sequence return str_ireplace("'", "''", $str);
* create sequence TS_USER }
* minvalue 1
* maxvalue 999999999999999999999999999 /**
* start with 1 * 获取最后插入id ,仅适用于采用序列+触发器结合生成ID的方式
* increment by 1 * 在config.php中指定
* nocache; * 'DB_TRIGGER_PREFIX' => 'tr_',
* 相对tb_user,ts_user的触发器为 * 'DB_SEQUENCE_PREFIX' => 'ts_',
* create or replace trigger TR_USER * eg:表 tb_user
* before insert on "TB_USER" * 相对tb_user的序列为
* for each row * -- Create sequence
* begin * create sequence TS_USER
* select "TS_USER".nextval into :NEW.ID from dual; * minvalue 1
* end; * maxvalue 999999999999999999999999999
* @access public * start with 1
* @return integer * increment by 1
*/ * nocache;
public function getLastInsertId() { * 相对tb_user,ts_user的触发器为
if(empty($this->table)) { * create or replace trigger TR_USER
return 0; * before insert on "TB_USER"
} * for each row
$sequenceName = $this->table; * begin
$vo = $this->query("SELECT {$sequenceName}.currval currval FROM dual"); * select "TS_USER".nextval into :NEW.ID from dual;
return $vo?$vo[0]["currval"]:0; * end;
} * @access public
* @return integer
/** */
* limit public function getLastInsertId() {
* @access public if(empty($this->table)) {
* @return string return 0;
*/ }
public function parseLimit($limit) { $sequenceName = $this->table;
$limitStr = ''; $vo = $this->query("SELECT {$sequenceName}.currval currval FROM dual");
if(!empty($limit)) { return $vo?$vo[0]["currval"]:0;
$limit = explode(',',$limit); }
if(count($limit)>1)
$limitStr = "(numrow>" . $limit[0] . ") AND (numrow<=" . ($limit[0]+$limit[1]) . ")"; /**
else * limit
$limitStr = "(numrow>0 AND numrow<=".$limit[0].")"; * @access public
} * @return string
return $limitStr?' WHERE '.$limitStr:''; */
} public function parseLimit($limit) {
$limitStr = '';
/** if(!empty($limit)) {
* 设置锁机制 $limit = explode(',',$limit);
* @access protected if(count($limit)>1)
* @return string $limitStr = "(numrow>" . $limit[0] . ") AND (numrow<=" . ($limit[0]+$limit[1]) . ")";
*/ else
protected function parseLock($lock=false) { $limitStr = "(numrow>0 AND numrow<=".$limit[0].")";
if(!$lock) return ''; }
return ' FOR UPDATE NOWAIT '; return $limitStr?' WHERE '.$limitStr:'';
} }
}
/**
* 设置锁机制
* @access protected
* @return string
*/
protected function parseLock($lock=false) {
if(!$lock) return '';
return ' FOR UPDATE NOWAIT ';
}
}

View File

@@ -1,80 +1,90 @@
<?php <?php
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
namespace Think\Db\Driver; namespace Think\Db\Driver;
use Think\Db\Driver; use Think\Db\Driver;
/** /**
* Pgsql数据库驱动 * Pgsql数据库驱动
* @category Extend */
* @package Extend class Pgsql extends Driver{
* @subpackage Driver.Db
* @author liu21st <liu21st@gmail.com> /**
*/ * 解析pdo连接的dsn信息
class Pgsql extends Driver{ * @access public
* @param array $config 连接信息
/** * @return string
* 取得数据表的字段信息 */
* @access public protected function parseDsn($config){
* @return array $dsn = 'pgsql:dbname='.$config['database'].';host='.$config['hostname'];
*/ if(!empty($config['hostport'])) {
public function getFields($tableName) { $dsn .= ';port='.$config['hostport'];
$result = $this->query('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.');'); }
$info = []; return $dsn;
if($result){ }
foreach ($result as $key => $val) {
$info[$val['field']] = [ /**
'name' => $val['field'], * 取得数据表的字段信息
'type' => $val['type'], * @access public
'notnull' => (bool) ($val['null'] === ''), // not null is empty, null is yes * @return array
'default' => $val['default'], */
'primary' => (strtolower($val['key']) == 'pri'), public function getFields($tableName) {
'autoinc' => (strtolower($val['extra']) == 'auto_increment'), $result = $this->query('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.');');
]; $info = [];
} if($result){
} foreach ($result as $key => $val) {
return $info; $info[$val['field']] = [
} 'name' => $val['field'],
'type' => $val['type'],
/** 'notnull' => (bool) ($val['null'] === ''), // not null is empty, null is yes
* 取得数据库的表信息 'default' => $val['default'],
* @access public 'primary' => (strtolower($val['key']) == 'pri'),
* @return array 'autoinc' => (strtolower($val['extra']) == 'auto_increment'),
*/ ];
public function getTables($dbName='') { }
$result = $this->query("select tablename as Tables_in_test from pg_tables where schemaname ='public'"); }
$info = []; return $info;
foreach ($result as $key => $val) { }
$info[$key] = current($val);
} /**
return $info; * 取得数据库的表信息
} * @access public
* @return array
/** */
* limit分析 public function getTables($dbName='') {
* @access protected $result = $this->query("select tablename as Tables_in_test from pg_tables where schemaname ='public'");
* @param mixed $lmit $info = [];
* @return string foreach ($result as $key => $val) {
*/ $info[$key] = current($val);
public function parseLimit($limit) { }
$limitStr = ''; return $info;
if(!empty($limit)) { }
$limit = explode(',',$limit);
if(count($limit)>1) { /**
$limitStr .= ' LIMIT '.$limit[1].' OFFSET '.$limit[0].' '; * limit分析
}else{ * @access protected
$limitStr .= ' LIMIT '.$limit[0].' '; * @param mixed $lmit
} * @return string
} */
return $limitStr; public function parseLimit($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;
}
}

View File

@@ -1,90 +1,97 @@
<?php <?php
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
namespace Think\Db\Driver; namespace Think\Db\Driver;
use Think\Db\Driver; use Think\Db\Driver;
/** /**
* Sqlite数据库驱动 * Sqlite数据库驱动
* @category Extend */
* @package Extend class Sqlite extends Driver {
* @subpackage Driver.Db
* @author liu21st <liu21st@gmail.com> /**
*/ * 解析pdo连接的dsn信息
class Sqlite extends Driver { * @access public
* @param array $config 连接信息
/** * @return string
* 取得数据表的字段信息 */
* @access public protected function parseDsn($config){
* @return array $dsn = 'sqlite:'.$config['database'];
*/ return $dsn;
public function getFields($tableName) { }
$result = $this->query('PRAGMA table_info( '.$tableName.' )');
$info = []; /**
if($result){ * 取得数据表的字段信息
foreach ($result as $key => $val) { * @access public
$info[$val['field']] = [ * @return array
'name' => $val['field'], */
'type' => $val['type'], public function getFields($tableName) {
'notnull' => (bool) ($val['null'] === ''), // not null is empty, null is yes $result = $this->query('PRAGMA table_info( '.$tableName.' )');
'default' => $val['default'], $info = [];
'primary' => (strtolower($val['dey']) == 'pri'), if($result){
'autoinc' => (strtolower($val['extra']) == 'auto_increment'), foreach ($result as $key => $val) {
]; $info[$val['field']] = [
} 'name' => $val['field'],
} 'type' => $val['type'],
return $info; 'notnull' => (bool) ($val['null'] === ''), // not null is empty, null is yes
} 'default' => $val['default'],
'primary' => (strtolower($val['dey']) == 'pri'),
/** 'autoinc' => (strtolower($val['extra']) == 'auto_increment'),
* 取得数据库的表信息 ];
* @access public }
* @return array }
*/ return $info;
public function getTables($dbName='') { }
$result = $this->query("SELECT name FROM sqlite_master WHERE type='table' "
. "UNION ALL SELECT name FROM sqlite_temp_master " /**
. "WHERE type='table' ORDER BY name"); * 取得数据库的表信息
$info = []; * @access public
foreach ($result as $key => $val) { * @return array
$info[$key] = current($val); */
} public function getTables($dbName='') {
return $info; $result = $this->query("SELECT name FROM sqlite_master WHERE type='table' "
} . "UNION ALL SELECT name FROM sqlite_temp_master "
. "WHERE type='table' ORDER BY name");
/** $info = [];
* SQL指令安全过滤 foreach ($result as $key => $val) {
* @access public $info[$key] = current($val);
* @param string $str SQL指令 }
* @return string return $info;
*/ }
public function escapeString($str) {
return str_ireplace("'", "''", $str); /**
} * SQL指令安全过滤
* @access public
/** * @param string $str SQL指令
* limit * @return string
* @access public */
* @return string public function escapeString($str) {
*/ return str_ireplace("'", "''", $str);
public function parseLimit($limit) { }
$limitStr = '';
if(!empty($limit)) { /**
$limit = explode(',',$limit); * limit
if(count($limit)>1) { * @access public
$limitStr .= ' LIMIT '.$limit[1].' OFFSET '.$limit[0].' '; * @return string
}else{ */
$limitStr .= ' LIMIT '.$limit[0].' '; public function parseLimit($limit) {
} $limitStr = '';
} if(!empty($limit)) {
return $limitStr; $limit = explode(',',$limit);
} if(count($limit)>1) {
} $limitStr .= ' LIMIT '.$limit[1].' OFFSET '.$limit[0].' ';
}else{
$limitStr .= ' LIMIT '.$limit[0].' ';
}
}
return $limitStr;
}
}

View File

@@ -1,131 +1,148 @@
<?php <?php
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
namespace Think\Db\Driver; namespace Think\Db\Driver;
use Think\Db\Driver; use Think\Db\Driver;
/** /**
* Sqlsrv数据库驱动 * Sqlsrv数据库驱动
* @category Extend */
* @package Extend class Sqlsrv extends Driver{
* @subpackage Driver.Db 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%';
* @author liu21st <liu21st@gmail.com> // PDO连接参数
*/ protected $options = [
class Sqlsrv extends Driver{ PDO::ATTR_CASE => PDO::CASE_LOWER,
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%'; PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_STRINGIFY_FETCHES => false,
/** PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
* 取得数据表的字段信息 ];
* @access public
* @return array /**
*/ * 解析pdo连接的dsn信息
public function getFields($tableName) { * @access public
$result = $this->query("SELECT column_name, data_type, column_default, is_nullable * @param array $config 连接信息
FROM information_schema.tables AS t * @return string
JOIN information_schema.columns AS c */
ON t.table_catalog = c.table_catalog protected function parseDsn($config){
AND t.table_schema = c.table_schema $dsn = 'sqlsrv:dbname='.$config['database'].';Server='.$config['hostname'];
AND t.table_name = c.table_name if(!empty($config['hostport'])) {
WHERE t.table_name = '$tableName'"); $dsn .= ','.$config['hostport'];
$info = []; }
if($result) { return $dsn;
foreach ($result as $key => $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 * @access public
'default' => $val['column_default'], * @return array
'primary' => false, */
'autoinc' => false, public function getFields($tableName) {
]; $result = $this->query("SELECT column_name, data_type, column_default, is_nullable
} FROM information_schema.tables AS t
} JOIN information_schema.columns AS c
return $info; 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'");
* 取得数据表的字段信息 $info = [];
* @access public if($result) {
* @return array foreach ($result as $key => $val) {
*/ $info[$val['column_name']] = [
public function getTables($dbName='') { 'name' => $val['column_name'],
$result = $this->query("SELECT TABLE_NAME 'type' => $val['data_type'],
FROM INFORMATION_SCHEMA.TABLES 'notnull' => (bool) ($val['is_nullable'] === ''), // not null is empty, null is yes
WHERE TABLE_TYPE = 'BASE TABLE' 'default' => $val['column_default'],
"); 'primary' => false,
$info = []; 'autoinc' => false,
foreach ($result as $key => $val) { ];
$info[$key] = current($val); }
} }
return $info; return $info;
} }
/** /**
* order分析 * 取得数据表的字段信息
* @access protected * @access public
* @param mixed $order * @return array
* @return string */
*/ public function getTables($dbName='') {
protected function parseOrder($order) { $result = $this->query("SELECT TABLE_NAME
return !empty($order)? ' ORDER BY '.$order:' ORDER BY rand()'; FROM INFORMATION_SCHEMA.TABLES
} WHERE TABLE_TYPE = 'BASE TABLE'
");
/** $info = [];
* limit foreach ($result as $key => $val) {
* @access public $info[$key] = current($val);
* @param mixed $limit }
* @return string return $info;
*/ }
public function parseLimit($limit) {
if(empty($limit)) return ''; /**
$limit = explode(',',$limit); * order分析
if(count($limit)>1) * @access protected
$limitStr = '(T1.ROW_NUMBER BETWEEN '.$limit[0].' + 1 AND '.$limit[0].' + '.$limit[1].')'; * @param mixed $order
else * @return string
$limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND '.$limit[0].")"; */
return 'WHERE '.$limitStr; protected function parseOrder($order) {
} return !empty($order)? ' ORDER BY '.$order:' ORDER BY rand()';
}
/**
* 更新记录 /**
* @access public * limit
* @param mixed $data 数据 * @access public
* @param array $options 表达式 * @param mixed $limit
* @return false | integer * @return string
*/ */
public function update($data,$options) { public function parseLimit($limit) {
$this->model = $options['model']; if(empty($limit)) return '';
$sql = 'UPDATE ' $limit = explode(',',$limit);
.$this->parseTable($options['table']) if(count($limit)>1)
.$this->parseSet($data) $limitStr = '(T1.ROW_NUMBER BETWEEN '.$limit[0].' + 1 AND '.$limit[0].' + '.$limit[1].')';
.$this->parseWhere(!empty($options['where'])?$options['where']:'') else
.$this->parseLock(isset($options['lock'])?$options['lock']:false) $limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND '.$limit[0].")";
.$this->parseComment(!empty($options['comment'])?$options['comment']:''); return 'WHERE '.$limitStr;
return $this->execute($sql); }
}
/**
/** * 更新记录
* 删除记录 * @access public
* @access public * @param mixed $data 数据
* @param array $options 表达式 * @param array $options 表达式
* @return false | integer * @return false | integer
*/ */
public function delete($options=[]) { public function update($data,$options) {
$this->model = $options['model']; $this->model = $options['model'];
$sql = 'DELETE FROM ' $sql = 'UPDATE '
.$this->parseTable($options['table']) .$this->parseTable($options['table'])
.$this->parseWhere(!empty($options['where'])?$options['where']:'') .$this->parseSet($data)
.$this->parseLock(isset($options['lock'])?$options['lock']:false) .$this->parseWhere(!empty($options['where'])?$options['where']:'')
.$this->parseComment(!empty($options['comment'])?$options['comment']:''); .$this->parseLock(isset($options['lock'])?$options['lock']:false)
return $this->execute($sql); .$this->parseComment(!empty($options['comment'])?$options['comment']:'');
} return $this->execute($sql,$this->parseBind(!empty($options['bind'])?$options['bind']:[]));
}
}
/**
* 删除记录
* @access public
* @param array $options 表达式
* @return false | integer
*/
public function delete($options=[]) {
$this->model = $options['model'];
$sql = 'DELETE FROM '
.$this->parseTable($options['table'])
.$this->parseWhere(!empty($options['where'])?$options['where']:'')
.$this->parseLock(isset($options['lock'])?$options['lock']:false)
.$this->parseComment(!empty($options['comment'])?$options['comment']:'');
return $this->execute($sql,$this->parseBind(!empty($options['bind'])?$options['bind']:[]));
}
}