Firebird.class.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace Think\Db\Driver;
  12. use Think\Db\Driver;
  13. /**
  14. * Firebird数据库驱动
  15. */
  16. class Firebird extends Driver{
  17. protected $selectSql = 'SELECT %LIMIT% %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%';
  18. /**
  19. * 解析pdo连接的dsn信息
  20. * @access public
  21. * @param array $config 连接信息
  22. * @return string
  23. */
  24. protected function parseDsn($config){
  25. $dsn = 'firebird:dbname='.$config['hostname'].'/'.($config['hostport']?:3050).':'.$config['database'];
  26. return $dsn;
  27. }
  28. /**
  29. * 执行语句
  30. * @access public
  31. * @param string $str sql指令
  32. * @param boolean $fetchSql 不执行只是获取SQL
  33. * @return mixed
  34. */
  35. public function execute($str,$fetchSql=false) {
  36. $this->initConnect(true);
  37. if ( !$this->_linkID ) return false;
  38. $this->queryStr = $str;
  39. if(!empty($this->bind)){
  40. $that = $this;
  41. $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$this->bind));
  42. }
  43. if($fetchSql){
  44. return $this->queryStr;
  45. }
  46. //释放前次的查询结果
  47. if ( !empty($this->PDOStatement) ) $this->free();
  48. $this->executeTimes++;
  49. N('db_write',1); // 兼容代码
  50. // 记录开始执行时间
  51. $this->debug(true);
  52. $this->PDOStatement = $this->_linkID->prepare($str);
  53. if(false === $this->PDOStatement) {
  54. E($this->error());
  55. }
  56. foreach ($this->bind as $key => $val) {
  57. if(is_array($val)){
  58. $this->PDOStatement->bindValue($key, $val[0], $val[1]);
  59. }else{
  60. $this->PDOStatement->bindValue($key, $val);
  61. }
  62. }
  63. $this->bind = array();
  64. $result = $this->PDOStatement->execute();
  65. $this->debug(false);
  66. if ( false === $result) {
  67. $this->error();
  68. return false;
  69. } else {
  70. $this->numRows = $this->PDOStatement->rowCount();
  71. return $this->numRows;
  72. }
  73. }
  74. /**
  75. * 取得数据表的字段信息
  76. * @access public
  77. */
  78. public function getFields($tableName) {
  79. $this->initConnect(true);
  80. list($tableName) = explode(' ', $tableName);
  81. $sql='SELECT RF.RDB$FIELD_NAME AS FIELD,RF.RDB$DEFAULT_VALUE AS DEFAULT1,RF.RDB$NULL_FLAG AS NULL1,TRIM(T.RDB$TYPE_NAME) || \'(\' || F.RDB$FIELD_LENGTH || \')\' as TYPE FROM RDB$RELATION_FIELDS RF LEFT JOIN RDB$FIELDS F ON (F.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE) LEFT JOIN RDB$TYPES T ON (T.RDB$TYPE = F.RDB$FIELD_TYPE) WHERE RDB$RELATION_NAME=UPPER(\''.$tableName.'\') AND T.RDB$FIELD_NAME = \'RDB$FIELD_TYPE\' ORDER By RDB$FIELD_POSITION';
  82. $result = $this->query($sql);
  83. $info = array();
  84. if($result){
  85. foreach($result as $key => $val){
  86. $info[trim($val['field'])] = array(
  87. 'name' => trim($val['field']),
  88. 'type' => $val['type'],
  89. 'notnull' => (bool) ($val['null1'] ==1), // 1表示不为Null
  90. 'default' => $val['default1'],
  91. 'primary' => false,
  92. 'autoinc' => false,
  93. );
  94. }
  95. }
  96. //获取主键
  97. $sql='select b.rdb$field_name as field_name from rdb$relation_constraints a join rdb$index_segments b on a.rdb$index_name=b.rdb$index_name where a.rdb$constraint_type=\'PRIMARY KEY\' and a.rdb$relation_name=UPPER(\''.$tableName.'\')';
  98. $rs_temp = $this->query($sql);
  99. foreach($rs_temp as $row) {
  100. $info[trim($row['field_name'])]['primary']=True;
  101. }
  102. return $info;
  103. }
  104. /**
  105. * 取得数据库的表信息
  106. * @access public
  107. */
  108. public function getTables($dbName='') {
  109. $sql='SELECT DISTINCT RDB$RELATION_NAME FROM RDB$RELATION_FIELDS WHERE RDB$SYSTEM_FLAG=0';
  110. $result = $this->query($sql);
  111. $info = array();
  112. foreach ($result as $key => $val) {
  113. $info[$key] = trim(current($val));
  114. }
  115. return $info;
  116. }
  117. /**
  118. * SQL指令安全过滤
  119. * @access public
  120. * @param string $str SQL指令
  121. * @return string
  122. */
  123. public function escapeString($str) {
  124. return str_replace("'", "''", $str);
  125. }
  126. /**
  127. * limit
  128. * @access public
  129. * @param $limit limit表达式
  130. * @return string
  131. */
  132. public function parseLimit($limit) {
  133. $limitStr = '';
  134. if(!empty($limit)) {
  135. $limit = explode(',',$limit);
  136. if(count($limit)>1) {
  137. $limitStr = ' FIRST '.$limit[1].' SKIP '.$limit[0].' ';
  138. }else{
  139. $limitStr = ' FIRST '.$limit[0].' ';
  140. }
  141. }
  142. return $limitStr;
  143. }
  144. }