Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
1 <?php 2 /** 3 * Informix driver. 4 * 5 * @deprecated 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 2014 Damien Regad, Mark Newnham and the ADOdb community 22 * @author Mitchell T. Young <mitch@youngfamily.org> 23 * @author Samuel Carriere <samuel_carriere@hotmail.com> 24 */ 25 26 // security - hide paths 27 if (!defined('ADODB_DIR')) die(); 28 29 if (!defined('IFX_SCROLL')) define('IFX_SCROLL',1); 30 31 class ADODB_informix72 extends ADOConnection { 32 var $databaseType = "informix72"; 33 var $dataProvider = "informix"; 34 var $replaceQuote = "''"; // string to use to replace quotes 35 var $fmtDate = "'Y-m-d'"; 36 var $fmtTimeStamp = "'Y-m-d H:i:s'"; 37 var $hasInsertID = true; 38 var $hasAffectedRows = true; 39 var $substr = 'substr'; 40 var $metaTablesSQL="select tabname,tabtype from systables where tabtype in ('T','V') and owner!='informix'"; //Don't get informix tables and pseudo-tables 41 42 43 var $metaColumnsSQL = 44 "select c.colname, c.coltype, c.collength, d.default,c.colno 45 from syscolumns c, systables t,outer sysdefaults d 46 where c.tabid=t.tabid and d.tabid=t.tabid and d.colno=c.colno 47 and tabname='%s' order by c.colno"; 48 49 var $metaPrimaryKeySQL = 50 "select part1,part2,part3,part4,part5,part6,part7,part8 from 51 systables t,sysconstraints s,sysindexes i where t.tabname='%s' 52 and s.tabid=t.tabid and s.constrtype='P' 53 and i.idxname=s.idxname"; 54 55 var $concat_operator = '||'; 56 57 var $lastQuery = false; 58 var $has_insertid = true; 59 60 var $_autocommit = true; 61 var $_bindInputArray = true; // set to true if ADOConnection.Execute() permits binding of array parameters. 62 var $sysDate = 'TODAY'; 63 var $sysTimeStamp = 'CURRENT'; 64 var $cursorType = IFX_SCROLL; // IFX_SCROLL or IFX_HOLD or 0 65 66 function __construct() 67 { 68 // alternatively, use older method: 69 //putenv("DBDATE=Y4MD-"); 70 71 // force ISO date format 72 putenv('GL_DATE=%Y-%m-%d'); 73 74 if (function_exists('ifx_byteasvarchar')) { 75 ifx_byteasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content. 76 ifx_textasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content. 77 ifx_blobinfile_mode(0); // Mode "0" means save Byte-Blobs in memory, and mode "1" means save Byte-Blobs in a file. 78 } 79 } 80 81 function ServerInfo() 82 { 83 $arr['description'] = $this->GetOne("select DBINFO('version','full') from systables where tabid = 1"); 84 $arr['version'] = $this->GetOne("select DBINFO('version','major') || DBINFO('version','minor') from systables where tabid = 1"); 85 return $arr; 86 } 87 88 89 90 protected function _insertID($table = '', $column = '') 91 { 92 $sqlca =ifx_getsqlca($this->lastQuery); 93 return @$sqlca["sqlerrd1"]; 94 } 95 96 function _affectedrows() 97 { 98 if ($this->lastQuery) { 99 return @ifx_affected_rows ($this->lastQuery); 100 } 101 return 0; 102 } 103 104 function BeginTrans() 105 { 106 if ($this->transOff) return true; 107 $this->transCnt += 1; 108 $this->Execute('BEGIN'); 109 $this->_autocommit = false; 110 return true; 111 } 112 113 function CommitTrans($ok=true) 114 { 115 if (!$ok) return $this->RollbackTrans(); 116 if ($this->transOff) return true; 117 if ($this->transCnt) $this->transCnt -= 1; 118 $this->Execute('COMMIT'); 119 $this->_autocommit = true; 120 return true; 121 } 122 123 function RollbackTrans() 124 { 125 if ($this->transOff) return true; 126 if ($this->transCnt) $this->transCnt -= 1; 127 $this->Execute('ROLLBACK'); 128 $this->_autocommit = true; 129 return true; 130 } 131 132 function RowLock($tables,$where,$col='1 as adodbignore') 133 { 134 if ($this->_autocommit) $this->BeginTrans(); 135 return $this->GetOne("select $col from $tables where $where for update"); 136 } 137 138 /* Returns: the last error message from previous database operation 139 Note: This function is NOT available for Microsoft SQL Server. */ 140 141 function ErrorMsg() 142 { 143 if (!empty($this->_logsql)) return $this->_errorMsg; 144 $this->_errorMsg = ifx_errormsg(); 145 return $this->_errorMsg; 146 } 147 148 function ErrorNo() 149 { 150 preg_match("/.*SQLCODE=([^\]]*)/",ifx_error(),$parse); 151 if (is_array($parse) && isset($parse[1])) return (int)$parse[1]; 152 return 0; 153 } 154 155 156 function MetaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null) 157 { 158 // save old fetch mode 159 global $ADODB_FETCH_MODE; 160 161 $false = false; 162 $save = $ADODB_FETCH_MODE; 163 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 164 if ($this->fetchMode !== FALSE) { 165 $savem = $this->SetFetchMode(FALSE); 166 167 } 168 $procedures = array (); 169 170 // get index details 171 172 $likepattern = ''; 173 if ($NamePattern) { 174 $likepattern = " WHERE procname LIKE '".$NamePattern."'"; 175 } 176 177 $rs = $this->Execute('SELECT procname, isproc FROM sysprocedures'.$likepattern); 178 179 if (is_object($rs)) { 180 // parse index data into array 181 182 while ($row = $rs->FetchRow()) { 183 $procedures[$row[0]] = array( 184 'type' => ($row[1] == 'f' ? 'FUNCTION' : 'PROCEDURE'), 185 'catalog' => '', 186 'schema' => '', 187 'remarks' => '' 188 ); 189 } 190 } 191 192 // restore fetchmode 193 if (isset($savem)) { 194 $this->SetFetchMode($savem); 195 } 196 $ADODB_FETCH_MODE = $save; 197 198 return $procedures; 199 } 200 201 function MetaColumns($table, $normalize=true) 202 { 203 global $ADODB_FETCH_MODE; 204 205 $false = false; 206 if (!empty($this->metaColumnsSQL)) { 207 $save = $ADODB_FETCH_MODE; 208 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 209 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 210 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table)); 211 if (isset($savem)) $this->SetFetchMode($savem); 212 $ADODB_FETCH_MODE = $save; 213 if ($rs === false) return $false; 214 $rspkey = $this->Execute(sprintf($this->metaPrimaryKeySQL,$table)); //Added to get primary key colno items 215 216 $retarr = array(); 217 while (!$rs->EOF) { //print_r($rs->fields); 218 $fld = new ADOFieldObject(); 219 $fld->name = $rs->fields[0]; 220 /* //!eos. 221 $rs->fields[1] is not the correct adodb type 222 $rs->fields[2] is not correct max_length, because can include not-null bit 223 224 $fld->type = $rs->fields[1]; 225 $fld->primary_key=$rspkey->fields && array_search($rs->fields[4],$rspkey->fields); //Added to set primary key flag 226 $fld->max_length = $rs->fields[2];*/ 227 $pr=ifx_props($rs->fields[1],$rs->fields[2]); //!eos 228 $fld->type = $pr[0] ;//!eos 229 $fld->primary_key=$rspkey->fields && array_search($rs->fields[4],$rspkey->fields); 230 $fld->max_length = $pr[1]; //!eos 231 $fld->precision = $pr[2] ;//!eos 232 $fld->not_null = $pr[3]=="N"; //!eos 233 234 if (trim($rs->fields[3]) != "AAAAAA 0") { 235 $fld->has_default = 1; 236 $fld->default_value = $rs->fields[3]; 237 } else { 238 $fld->has_default = 0; 239 } 240 241 $retarr[strtolower($fld->name)] = $fld; 242 $rs->MoveNext(); 243 } 244 245 $rs->Close(); 246 $rspkey->Close(); //!eos 247 return $retarr; 248 } 249 250 return $false; 251 } 252 253 function xMetaColumns($table) 254 { 255 return ADOConnection::MetaColumns($table,false); 256 } 257 258 public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false) 259 { 260 $sql = " 261 select tr.tabname,updrule,delrule, 262 i.part1 o1,i2.part1 d1,i.part2 o2,i2.part2 d2,i.part3 o3,i2.part3 d3,i.part4 o4,i2.part4 d4, 263 i.part5 o5,i2.part5 d5,i.part6 o6,i2.part6 d6,i.part7 o7,i2.part7 d7,i.part8 o8,i2.part8 d8 264 from systables t,sysconstraints s,sysindexes i, 265 sysreferences r,systables tr,sysconstraints s2,sysindexes i2 266 where t.tabname='$table' 267 and s.tabid=t.tabid and s.constrtype='R' and r.constrid=s.constrid 268 and i.idxname=s.idxname and tr.tabid=r.ptabid 269 and s2.constrid=r.primary and i2.idxname=s2.idxname"; 270 271 $rs = $this->Execute($sql); 272 if (!$rs || $rs->EOF) return false; 273 $arr = $rs->GetArray(); 274 $a = array(); 275 foreach($arr as $v) { 276 $coldest=$this->metaColumnNames($v["tabname"]); 277 $colorig=$this->metaColumnNames($table); 278 $colnames=array(); 279 for($i=1;$i<=8 && $v["o$i"] ;$i++) { 280 $colnames[]=$coldest[$v["d$i"]-1]."=".$colorig[$v["o$i"]-1]; 281 } 282 if($upper) 283 $a[strtoupper($v["tabname"])] = $colnames; 284 else 285 $a[$v["tabname"]] = $colnames; 286 } 287 return $a; 288 } 289 290 function UpdateBlob($table, $column, $val, $where, $blobtype = 'BLOB') 291 { 292 $type = ($blobtype == 'TEXT') ? 1 : 0; 293 $blobid = ifx_create_blob($type,0,$val); 294 return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blobid)); 295 } 296 297 function BlobDecode($blobid) 298 { 299 return function_exists('ifx_byteasvarchar') ? $blobid : @ifx_get_blob($blobid); 300 } 301 302 // returns true or false 303 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename) 304 { 305 if (!function_exists('ifx_connect')) return null; 306 307 $dbs = $argDatabasename . "@" . $argHostname; 308 if ($argHostname) putenv("INFORMIXSERVER=$argHostname"); 309 putenv("INFORMIXSERVER=".trim($argHostname)); 310 $this->_connectionID = ifx_connect($dbs,$argUsername,$argPassword); 311 if ($this->_connectionID === false) return false; 312 #if ($argDatabasename) return $this->SelectDB($argDatabasename); 313 return true; 314 } 315 316 // returns true or false 317 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) 318 { 319 if (!function_exists('ifx_connect')) return null; 320 321 $dbs = $argDatabasename . "@" . $argHostname; 322 putenv("INFORMIXSERVER=".trim($argHostname)); 323 $this->_connectionID = ifx_pconnect($dbs,$argUsername,$argPassword); 324 if ($this->_connectionID === false) return false; 325 #if ($argDatabasename) return $this->SelectDB($argDatabasename); 326 return true; 327 } 328 /* 329 // ifx_do does not accept bind parameters - weird ??? 330 function Prepare($sql) 331 { 332 $stmt = ifx_prepare($sql); 333 if (!$stmt) return $sql; 334 else return array($sql,$stmt); 335 } 336 */ 337 // returns query ID if successful, otherwise false 338 function _query($sql,$inputarr=false) 339 { 340 global $ADODB_COUNTRECS; 341 342 // String parameters have to be converted using ifx_create_char 343 if ($inputarr) { 344 foreach($inputarr as $v) { 345 if (gettype($v) == 'string') { 346 $tab[] = ifx_create_char($v); 347 } 348 else { 349 $tab[] = $v; 350 } 351 } 352 } 353 354 // In case of select statement, we use a scroll cursor in order 355 // to be able to call "move", or "movefirst" statements 356 if (!$ADODB_COUNTRECS && preg_match("/^\s*select/is", $sql)) { 357 if ($inputarr) { 358 $this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType, $tab); 359 } 360 else { 361 $this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType); 362 } 363 } 364 else { 365 if ($inputarr) { 366 $this->lastQuery = ifx_query($sql,$this->_connectionID, $tab); 367 } 368 else { 369 $this->lastQuery = ifx_query($sql,$this->_connectionID); 370 } 371 } 372 373 // Following line have been commented because autocommit mode is 374 // not supported by informix SE 7.2 375 376 //if ($this->_autocommit) ifx_query('COMMIT',$this->_connectionID); 377 378 return $this->lastQuery; 379 } 380 381 // returns true or false 382 function _close() 383 { 384 $this->lastQuery = false; 385 if($this->_connectionID) { 386 return ifx_close($this->_connectionID); 387 } 388 return true; 389 } 390 } 391 392 393 /*-------------------------------------------------------------------------------------- 394 Class Name: Recordset 395 --------------------------------------------------------------------------------------*/ 396 397 class ADORecordset_informix72 extends ADORecordSet { 398 399 var $databaseType = "informix72"; 400 var $canSeek = true; 401 var $_fieldprops = false; 402 403 function __construct($id,$mode=false) 404 { 405 if ($mode === false) { 406 global $ADODB_FETCH_MODE; 407 $mode = $ADODB_FETCH_MODE; 408 } 409 $this->fetchMode = $mode; 410 parent::__construct($id); 411 } 412 413 414 415 /* Returns: an object containing field information. 416 Get column information in the Recordset object. fetchField() can be used in order to obtain information about 417 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by 418 fetchField() is retrieved. */ 419 function FetchField($fieldOffset = -1) 420 { 421 if (empty($this->_fieldprops)) { 422 $fp = ifx_fieldproperties($this->_queryID); 423 foreach($fp as $k => $v) { 424 $o = new ADOFieldObject; 425 $o->name = $k; 426 $arr = explode(';',$v); //"SQLTYPE;length;precision;scale;ISNULLABLE" 427 $o->type = $arr[0]; 428 $o->max_length = $arr[1]; 429 $this->_fieldprops[] = $o; 430 $o->not_null = $arr[4]=="N"; 431 } 432 } 433 $ret = $this->_fieldprops[$fieldOffset]; 434 return $ret; 435 } 436 437 function _initrs() 438 { 439 $this->_numOfRows = -1; // ifx_affected_rows not reliable, only returns estimate -- ($ADODB_COUNTRECS)? ifx_affected_rows($this->_queryID):-1; 440 $this->_numOfFields = ifx_num_fields($this->_queryID); 441 } 442 443 function _seek($row) 444 { 445 return @ifx_fetch_row($this->_queryID, (int) $row); 446 } 447 448 function MoveLast() 449 { 450 $this->fields = @ifx_fetch_row($this->_queryID, "LAST"); 451 if ($this->fields) $this->EOF = false; 452 $this->_currentRow = -1; 453 454 if ($this->fetchMode == ADODB_FETCH_NUM) { 455 foreach($this->fields as $v) { 456 $arr[] = $v; 457 } 458 $this->fields = $arr; 459 } 460 461 return true; 462 } 463 464 function MoveFirst() 465 { 466 $this->fields = @ifx_fetch_row($this->_queryID, "FIRST"); 467 if ($this->fields) $this->EOF = false; 468 $this->_currentRow = 0; 469 470 if ($this->fetchMode == ADODB_FETCH_NUM) { 471 foreach($this->fields as $v) { 472 $arr[] = $v; 473 } 474 $this->fields = $arr; 475 } 476 477 return true; 478 } 479 480 function _fetch($ignore_fields=false) 481 { 482 483 $this->fields = @ifx_fetch_row($this->_queryID); 484 485 if (!is_array($this->fields)) return false; 486 487 if ($this->fetchMode == ADODB_FETCH_NUM) { 488 foreach($this->fields as $v) { 489 $arr[] = $v; 490 } 491 $this->fields = $arr; 492 } 493 return true; 494 } 495 496 /* close() only needs to be called if you are worried about using too much memory while your script 497 is running. All associated result memory for the specified result identifier will automatically be freed. */ 498 function _close() 499 { 500 if($this->_queryID) { 501 return ifx_free_result($this->_queryID); 502 } 503 return true; 504 } 505 506 } 507 /** !Eos 508 * Auxiliary function to Parse coltype,collength. Used by Metacolumns 509 * return: array ($mtype,$length,$precision,$nullable) (similar to ifx_fieldpropierties) 510 */ 511 function ifx_props($coltype,$collength){ 512 $itype=fmod($coltype+1,256); 513 $nullable=floor(($coltype+1) /256) ?"N":"Y"; 514 $mtype=substr(" CIIFFNNDN TBXCC ",$itype,1); 515 switch ($itype){ 516 case 2: 517 $length=4; 518 case 6: 519 case 9: 520 case 14: 521 $length=floor($collength/256); 522 $precision=fmod($collength,256); 523 break; 524 default: 525 $precision=0; 526 $length=$collength; 527 } 528 return array($mtype,$length,$precision,$nullable); 529 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body