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