Differences Between: [Versions 311 and 402] [Versions 400 and 402] [Versions 401 and 402]
1 <?php 2 /** 3 * PDO Firebird driver 4 * 5 * This version has only been tested on Firebird 3.0 and PHP 7 6 * 7 * This file is part of ADOdb, a Database Abstraction Layer library for PHP. 8 * 9 * @package ADOdb 10 * @link https://adodb.org Project's web site and documentation 11 * @link https://github.com/ADOdb/ADOdb Source code and issue tracker 12 * 13 * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause 14 * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, 15 * any later version. This means you can use it in proprietary products. 16 * See the LICENSE.md file distributed with this source code for details. 17 * @license BSD-3-Clause 18 * @license LGPL-2.1-or-later 19 * 20 * @copyright 2000-2013 John Lim 21 * @copyright 2019 Damien Regad, Mark Newnham and the ADOdb community 22 */ 23 24 /** 25 * Class ADODB_pdo_firebird 26 */ 27 class ADODB_pdo_firebird extends ADODB_pdo 28 { 29 public $dialect = 3; 30 public $metaTablesSQL = "select lower(rdb\$relation_name) from rdb\$relations where rdb\$relation_name not like 'RDB\$%'"; 31 public $metaColumnsSQL = "select lower(a.rdb\$field_name), a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc"; 32 33 var $arrayClass = 'ADORecordSet_array_pdo_firebird'; 34 35 /** 36 * Gets the version iformation from the server 37 * 38 * @return string[] 39 */ 40 public function serverInfo() 41 { 42 $arr['dialect'] = $this->dialect; 43 switch ($arr['dialect']) { 44 case '': 45 case '1': 46 $s = 'Firebird Dialect 1'; 47 break; 48 case '2': 49 $s = 'Firebird Dialect 2'; 50 break; 51 default: 52 case '3': 53 $s = 'Firebird Dialect 3'; 54 break; 55 } 56 $arr['version'] = ADOConnection::_findvers($s); 57 $arr['description'] = $s; 58 return $arr; 59 } 60 61 /** 62 * Returns the tables in the database. 63 * 64 * @param mixed $ttype 65 * @param bool $showSchema 66 * @param mixed $mask 67 * 68 * @return string[] 69 */ 70 public function metaTables($ttype = false, $showSchema = false, $mask = false) 71 { 72 $ret = ADOConnection::MetaTables($ttype, $showSchema); 73 74 return $ret; 75 } 76 77 public function metaColumns($table, $normalize = true) 78 { 79 global $ADODB_FETCH_MODE; 80 81 $save = $ADODB_FETCH_MODE; 82 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 83 84 $rs = $this->Execute(sprintf($this->metaColumnsSQL, strtoupper($table))); 85 86 $ADODB_FETCH_MODE = $save; 87 88 if ($rs === false) { 89 return false; 90 } 91 92 $retarr = array(); 93 $dialect3 = $this->dialect == 3; 94 while (!$rs->EOF) { //print_r($rs->fields); 95 $fld = new ADOFieldObject(); 96 $fld->name = trim($rs->fields[0]); 97 $this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], 98 $rs->fields[6], $dialect3); 99 if (isset($rs->fields[1]) && $rs->fields[1]) { 100 $fld->not_null = true; 101 } 102 if (isset($rs->fields[2])) { 103 104 $fld->has_default = true; 105 $d = substr($rs->fields[2], strlen('default ')); 106 switch ($fld->type) { 107 case 'smallint': 108 case 'integer': 109 $fld->default_value = (int)$d; 110 break; 111 case 'char': 112 case 'blob': 113 case 'text': 114 case 'varchar': 115 $fld->default_value = (string)substr($d, 1, strlen($d) - 2); 116 break; 117 case 'double': 118 case 'float': 119 $fld->default_value = (float)$d; 120 break; 121 default: 122 $fld->default_value = $d; 123 break; 124 } 125 } 126 if ((isset($rs->fields[5])) && ($fld->type == 'blob')) { 127 $fld->sub_type = $rs->fields[5]; 128 } else { 129 $fld->sub_type = null; 130 } 131 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) { 132 $retarr[] = $fld; 133 } else { 134 $retarr[strtoupper($fld->name)] = $fld; 135 } 136 137 $rs->MoveNext(); 138 } 139 $rs->Close(); 140 if (empty($retarr)) { 141 return false; 142 } else { 143 return $retarr; 144 } 145 } 146 147 public function metaIndexes($table, $primary = false, $owner = false) 148 { 149 // save old fetch mode 150 global $ADODB_FETCH_MODE; 151 $save = $ADODB_FETCH_MODE; 152 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 153 if ($this->fetchMode !== false) { 154 $savem = $this->SetFetchMode(false); 155 } 156 $table = strtoupper($table); 157 $sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '" . $table . "'"; 158 if (!$primary) { 159 $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'"; 160 } else { 161 $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'"; 162 } 163 164 // get index details 165 $rs = $this->Execute($sql); 166 if (!is_object($rs)) { 167 // restore fetchmode 168 if (isset($savem)) { 169 $this->SetFetchMode($savem); 170 } 171 $ADODB_FETCH_MODE = $save; 172 return false; 173 } 174 175 $indexes = array(); 176 while ($row = $rs->FetchRow()) { 177 $index = $row[0]; 178 if (!isset($indexes[$index])) { 179 if (is_null($row[3])) { 180 $row[3] = 0; 181 } 182 $indexes[$index] = array( 183 'unique' => ($row[3] == 1), 184 'columns' => array() 185 ); 186 } 187 $sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '" . $index . "' ORDER BY RDB\$FIELD_POSITION ASC"; 188 $rs1 = $this->Execute($sql); 189 while ($row1 = $rs1->FetchRow()) { 190 $indexes[$index]['columns'][$row1[2]] = $row1[1]; 191 } 192 } 193 // restore fetchmode 194 if (isset($savem)) { 195 $this->SetFetchMode($savem); 196 } 197 $ADODB_FETCH_MODE = $save; 198 199 return $indexes; 200 } 201 202 public function metaPrimaryKeys($table, $owner_notused = false, $internalKey = false) 203 { 204 if ($internalKey) { 205 return array('RDB$DB_KEY'); 206 } 207 208 $table = strtoupper($table); 209 210 $sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME 211 FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME 212 WHERE I.RDB$RELATION_NAME=\'' . $table . '\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\' 213 ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION'; 214 215 $a = $this->GetCol($sql, false, true); 216 if ($a && sizeof($a) > 0) { 217 return $a; 218 } 219 return false; 220 } 221 222 public function createSequence($seqname = 'adodbseq', $startID = 1) 223 { 224 $ok = $this->execute("CREATE SEQUENCE $seqname"); 225 if (!$ok) { 226 return false; 227 } 228 229 return $this->execute("ALTER SEQUENCE $seqname RESTART WITH " . ($startID - 1)); 230 } 231 232 public function dropSequence($seqname = 'adodbseq') 233 { 234 $seqname = strtoupper($seqname); 235 return $this->Execute("DROP SEQUENCE $seqname"); 236 } 237 238 public function genId($seqname = 'adodbseq', $startID = 1) 239 { 240 $getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE"); 241 $rs = @$this->execute($getnext); 242 if (!$rs) { 243 $this->execute(("CREATE SEQUENCE $seqname")); 244 $this->execute("ALTER SEQUENCE $seqname RESTART WITH " . ($startID - 1) . ';'); 245 $rs = $this->execute($getnext); 246 } 247 if ($rs && !$rs->EOF) { 248 $this->genID = (integer)reset($rs->fields); 249 } else { 250 $this->genID = 0; // false 251 } 252 253 if ($rs) { 254 $rs->Close(); 255 } 256 257 return $this->genID; 258 } 259 260 public function selectLimit($sql, $nrows = -1, $offset = -1, $inputarr = false, $secs = 0) 261 { 262 $nrows = (integer)$nrows; 263 $offset = (integer)$offset; 264 $str = 'SELECT '; 265 if ($nrows >= 0) { 266 $str .= "FIRST $nrows "; 267 } 268 $str .= ($offset >= 0) ? "SKIP $offset " : ''; 269 270 $sql = preg_replace('/^[ \t]*select/i', $str, $sql); 271 if ($secs) { 272 $rs = $this->cacheExecute($secs, $sql, $inputarr); 273 } else { 274 $rs = $this->execute($sql, $inputarr); 275 } 276 277 return $rs; 278 } 279 280 /** 281 * Sets the appropriate type into the $fld variable 282 * 283 * @param ADOFieldObject $fld By reference 284 * @param int $ftype 285 * @param int $flen 286 * @param int $fscale 287 * @param int $fsubtype 288 * @param int $fprecision 289 * @param bool $dialect3 290 */ 291 private function _convertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $dialect3) 292 { 293 $fscale = abs($fscale); 294 $fld->max_length = $flen; 295 $fld->scale = null; 296 switch ($ftype) { 297 case 7: 298 case 8: 299 if ($dialect3) { 300 switch ($fsubtype) { 301 case 0: 302 $fld->type = ($ftype == 7 ? 'smallint' : 'integer'); 303 break; 304 case 1: 305 $fld->type = 'numeric'; 306 $fld->max_length = $fprecision; 307 $fld->scale = $fscale; 308 break; 309 case 2: 310 $fld->type = 'decimal'; 311 $fld->max_length = $fprecision; 312 $fld->scale = $fscale; 313 break; 314 } // switch 315 } else { 316 if ($fscale != 0) { 317 $fld->type = 'decimal'; 318 $fld->scale = $fscale; 319 $fld->max_length = ($ftype == 7 ? 4 : 9); 320 } else { 321 $fld->type = ($ftype == 7 ? 'smallint' : 'integer'); 322 } 323 } 324 break; 325 case 16: 326 if ($dialect3) { 327 switch ($fsubtype) { 328 case 0: 329 $fld->type = 'decimal'; 330 $fld->max_length = 18; 331 $fld->scale = 0; 332 break; 333 case 1: 334 $fld->type = 'numeric'; 335 $fld->max_length = $fprecision; 336 $fld->scale = $fscale; 337 break; 338 case 2: 339 $fld->type = 'decimal'; 340 $fld->max_length = $fprecision; 341 $fld->scale = $fscale; 342 break; 343 } // switch 344 } 345 break; 346 case 10: 347 $fld->type = 'float'; 348 break; 349 case 14: 350 $fld->type = 'char'; 351 break; 352 case 27: 353 if ($fscale != 0) { 354 $fld->type = 'decimal'; 355 $fld->max_length = 15; 356 $fld->scale = 5; 357 } else { 358 $fld->type = 'double'; 359 } 360 break; 361 case 35: 362 if ($dialect3) { 363 $fld->type = 'timestamp'; 364 } else { 365 $fld->type = 'date'; 366 } 367 break; 368 case 12: 369 $fld->type = 'date'; 370 break; 371 case 13: 372 $fld->type = 'time'; 373 break; 374 case 37: 375 $fld->type = 'varchar'; 376 break; 377 case 40: 378 $fld->type = 'cstring'; 379 break; 380 case 261: 381 $fld->type = 'blob'; 382 $fld->max_length = -1; 383 break; 384 } // switch 385 } 386 } 387 388 /** 389 * Class ADORecordSet_pdo_firebird 390 */ 391 class ADORecordSet_pdo_firebird extends ADORecordSet_pdo 392 { 393 394 public $databaseType = "pdo_firebird"; 395 396 /** 397 * returns the field object 398 * 399 * @param int $fieldOffset Optional field offset 400 * 401 * @return object The ADOFieldObject describing the field 402 */ 403 public function fetchField($fieldOffset = 0) 404 { 405 } 406 } 407 408 /** 409 * Class ADORecordSet_array_pdo_firebird 410 */ 411 class ADORecordSet_array_pdo_firebird extends ADORecordSet_array_pdo 412 { 413 public $databaseType = "pdo_firebird"; 414 public $canSeek = true; 415 416 /** 417 * returns the field object 418 * 419 * @param int $fieldOffset Optional field offset 420 * 421 * @return object The ADOFieldObject describing the field 422 */ 423 public function fetchField($fieldOffset = 0) 424 { 425 426 $fld = new ADOFieldObject; 427 $fld->name = $fieldOffset; 428 $fld->type = 'C'; 429 $fld->max_length = 0; 430 431 // This needs to be populated from the metadata 432 $fld->not_null = false; 433 $fld->has_default = false; 434 $fld->default_value = 'null'; 435 436 return $fld; 437 } 438 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body