Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
	function _query($sql,$inputarr=false)
338
	{
339
	global $ADODB_COUNTRECS;
340
 
341
	  // String parameters have to be converted using ifx_create_char
342
	  if ($inputarr) {
343
		 foreach($inputarr as $v) {
344
			if (gettype($v) == 'string') {
345
			   $tab[] = ifx_create_char($v);
346
			}
347
			else {
348
			   $tab[] = $v;
349
			}
350
		 }
351
	  }
352
 
353
	  // In case of select statement, we use a scroll cursor in order
354
	  // to be able to call "move", or "movefirst" statements
355
	  if (!$ADODB_COUNTRECS && preg_match("/^\s*select/is", $sql)) {
356
		 if ($inputarr) {
357
			$this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType, $tab);
358
		 }
359
		 else {
360
			$this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType);
361
		 }
362
	  }
363
	  else {
364
		 if ($inputarr) {
365
			$this->lastQuery = ifx_query($sql,$this->_connectionID, $tab);
366
		 }
367
		 else {
368
			$this->lastQuery = ifx_query($sql,$this->_connectionID);
369
		 }
370
	  }
371
 
372
	  // Following line have been commented because autocommit mode is
373
	  // not supported by informix SE 7.2
374
 
375
	  //if ($this->_autocommit) ifx_query('COMMIT',$this->_connectionID);
376
 
377
		return $this->lastQuery;
378
	}
379
 
380
	// returns true or false
381
	function _close()
382
	{
383
		$this->lastQuery = false;
384
		if($this->_connectionID) {
385
			return ifx_close($this->_connectionID);
386
		}
387
		return true;
388
	}
389
}
390
 
391
 
392
/*--------------------------------------------------------------------------------------
393
	 Class Name: Recordset
394
--------------------------------------------------------------------------------------*/
395
 
396
class ADORecordset_informix72 extends ADORecordSet {
397
 
398
	var $databaseType = "informix72";
399
	var $canSeek = true;
400
	var $_fieldprops = false;
401
 
402
	function __construct($id,$mode=false)
403
	{
404
		if ($mode === false) {
405
			global $ADODB_FETCH_MODE;
406
			$mode = $ADODB_FETCH_MODE;
407
		}
408
		$this->fetchMode = $mode;
409
		parent::__construct($id);
410
	}
411
 
412
 
413
 
414
	/*	Returns: an object containing field information.
415
		Get column information in the Recordset object. fetchField() can be used in order to obtain information about
416
		fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
417
		fetchField() is retrieved.	*/
418
	function FetchField($fieldOffset = -1)
419
	{
420
		if (empty($this->_fieldprops)) {
421
			$fp = ifx_fieldproperties($this->_queryID);
422
			foreach($fp as $k => $v) {
423
				$o = new ADOFieldObject;
424
				$o->name = $k;
425
				$arr = explode(';',$v); //"SQLTYPE;length;precision;scale;ISNULLABLE"
426
				$o->type = $arr[0];
427
				$o->max_length = $arr[1];
428
				$this->_fieldprops[] = $o;
429
				$o->not_null = $arr[4]=="N";
430
			}
431
		}
432
		$ret = $this->_fieldprops[$fieldOffset];
433
		return $ret;
434
	}
435
 
436
	function _initrs()
437
	{
438
		$this->_numOfRows = -1; // ifx_affected_rows not reliable, only returns estimate -- ($ADODB_COUNTRECS)? ifx_affected_rows($this->_queryID):-1;
439
		$this->_numOfFields = ifx_num_fields($this->_queryID);
440
	}
441
 
442
	function _seek($row)
443
	{
444
		return @ifx_fetch_row($this->_queryID, (int) $row);
445
	}
446
 
447
   function MoveLast()
448
   {
449
	  $this->fields = @ifx_fetch_row($this->_queryID, "LAST");
450
	  if ($this->fields) $this->EOF = false;
451
	  $this->_currentRow = -1;
452
 
453
	  if ($this->fetchMode == ADODB_FETCH_NUM) {
454
		 foreach($this->fields as $v) {
455
			$arr[] = $v;
456
		 }
457
		 $this->fields = $arr;
458
	  }
459
 
460
	  return true;
461
   }
462
 
463
   function MoveFirst()
464
	{
465
	  $this->fields = @ifx_fetch_row($this->_queryID, "FIRST");
466
	  if ($this->fields) $this->EOF = false;
467
	  $this->_currentRow = 0;
468
 
469
	  if ($this->fetchMode == ADODB_FETCH_NUM) {
470
		 foreach($this->fields as $v) {
471
			$arr[] = $v;
472
		 }
473
		 $this->fields = $arr;
474
	  }
475
 
476
	  return true;
477
   }
478
 
479
   function _fetch($ignore_fields=false)
480
   {
481
 
482
		$this->fields = @ifx_fetch_row($this->_queryID);
483
 
484
		if (!is_array($this->fields)) return false;
485
 
486
		if ($this->fetchMode == ADODB_FETCH_NUM) {
487
			foreach($this->fields as $v) {
488
				$arr[] = $v;
489
			}
490
			$this->fields = $arr;
491
		}
492
		return true;
493
	}
494
 
495
	/*	close() only needs to be called if you are worried about using too much memory while your script
496
		is running. All associated result memory for the specified result identifier will automatically be freed.	*/
497
	function _close()
498
	{
499
		if($this->_queryID) {
500
			return ifx_free_result($this->_queryID);
501
		}
502
		return true;
503
	}
504
 
505
}
506
/** !Eos
507
* Auxiliary function to Parse coltype,collength. Used by Metacolumns
508
* return: array ($mtype,$length,$precision,$nullable) (similar to ifx_fieldpropierties)
509
*/
510
function ifx_props($coltype,$collength){
511
	$itype=fmod($coltype+1,256);
512
	$nullable=floor(($coltype+1) /256) ?"N":"Y";
513
	$mtype=substr(" CIIFFNNDN TBXCC     ",$itype,1);
514
	switch ($itype){
515
		case 2:
516
			$length=4;
517
		case 6:
518
		case 9:
519
		case 14:
520
			$length=floor($collength/256);
521
			$precision=fmod($collength,256);
522
			break;
523
		default:
524
			$precision=0;
525
			$length=$collength;
526
	}
527
	return array($mtype,$length,$precision,$nullable);
528
}