Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

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