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 (jlim#natsoft.com.my). 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
  Requires ODBC. Works on Windows and Unix.
12
 
13
	Problems: 
14
		Where is float/decimal type in pdo_param_type
15
		LOB handling for CLOB/BLOB differs significantly
16
*/
17
// security - hide paths
18
if (!defined('ADODB_DIR')) die();
19
 
20
 
21
/*
22
enum pdo_param_type {
23
PDO::PARAM_NULL, 0
24
 
25
/* int as in long (the php native int type).
26
 * If you mark a column as an int, PDO expects get_col to return
27
 * a pointer to a long 
28
PDO::PARAM_INT, 1
29
 
30
/* get_col ptr should point to start of the string buffer 
31
PDO::PARAM_STR, 2
32
 
33
/* get_col: when len is 0 ptr should point to a php_stream *,
34
 * otherwise it should behave like a string. Indicate a NULL field
35
 * value by setting the ptr to NULL 
36
PDO::PARAM_LOB, 3
37
 
38
/* get_col: will expect the ptr to point to a new PDOStatement object handle,
39
 * but this isn't wired up yet 
40
PDO::PARAM_STMT, 4 /* hierarchical result set 
41
 
42
/* get_col ptr should point to a zend_bool 
43
PDO::PARAM_BOOL, 5
44
 
45
 
46
/* magic flag to denote a parameter as being input/output 
47
PDO::PARAM_INPUT_OUTPUT = 0x80000000
48
};
49
*/
50
 
51
function adodb_pdo_type($t)
52
{
53
	switch($t) {
54
	case 2: return 'VARCHAR';
55
	case 3: return 'BLOB';
56
	default: return 'NUMERIC';
57
	}
58
}
59
 
60
/*--------------------------------------------------------------------------------------
61
--------------------------------------------------------------------------------------*/
62
 
63
////////////////////////////////////////////////
64
 
65
 
66
 
67
class ADODB_pdo_base extends ADODB_pdo {
68
 
69
	var $sysDate = "'?'";
70
	var $sysTimeStamp = "'?'";
71
 
72
 
73
	function _init($parentDriver)
74
	{
75
		$parentDriver->_bindInputArray = true;
76
		#$parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true);
77
	}
78
 
79
	function ServerInfo()
80
	{
81
		return ADOConnection::ServerInfo();
82
	}
83
 
84
	function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
85
	{
86
		$ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
87
		return $ret;
88
	}
89
 
90
	function MetaTables()
91
	{
92
		return false;
93
	}
94
 
95
	function MetaColumns()
96
	{
97
		return false;
98
	}
99
}
100
 
101
 
102
class ADODB_pdo extends ADOConnection {
103
	var $databaseType = "pdo";	
104
	var $dataProvider = "pdo";
105
	var $fmtDate = "'Y-m-d'";
106
	var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
107
	var $replaceQuote = "''"; // string to use to replace quotes
108
	var $hasAffectedRows = true;
109
	var $_bindInputArray = true;	
110
	var $_genSeqSQL = "create table %s (id integer)";
111
	var $_autocommit = true;
112
	var $_haserrorfunctions = true;
113
	var $_lastAffectedRows = 0;
114
 
115
	var $_errormsg = false;
116
	var $_errorno = false;
117
 
118
	var $dsnType = '';
119
	var $stmt = false;
120
 
121
	function ADODB_pdo()
122
	{
123
	}
124
 
125
	function _UpdatePDO()
126
	{
127
		$d = &$this->_driver;
128
		$this->fmtDate = $d->fmtDate;
129
		$this->fmtTimeStamp = $d->fmtTimeStamp;
130
		$this->replaceQuote = $d->replaceQuote;
131
		$this->sysDate = $d->sysDate;
132
		$this->sysTimeStamp = $d->sysTimeStamp;
133
		$this->random = $d->random;
134
		$this->concat_operator = $d->concat_operator;
135
		$this->nameQuote = $d->nameQuote;
136
 
137
		$d->_init($this);
138
	}
139
 
140
	function Time()
141
	{
142
		if (!empty($this->_driver->_hasdual)) $sql = "select $this->sysTimeStamp from dual";
143
		else $sql = "select $this->sysTimeStamp";
144
 
145
		$rs =& $this->_Execute($sql);
146
		if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
147
 
148
		return false;
149
	}
150
 
151
	// returns true or false
152
	function _connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persist=false)
153
	{
154
		$at = strpos($argDSN,':');
155
		$this->dsnType = substr($argDSN,0,$at);
156
 
157
		if ($argDatabasename) {
158
			$argDSN .= ';dbname='.$argDatabasename;
159
		}
160
		try {
161
			$this->_connectionID = new PDO($argDSN, $argUsername, $argPassword);
162
		} catch (Exception $e) {
163
			$this->_connectionID = false;
164
			$this->_errorno = -1;
165
			//var_dump($e);
166
			$this->_errormsg = 'Connection attempt failed: '.$e->getMessage();
167
			return false;
168
		}
169
 
170
		if ($this->_connectionID) {
171
			switch(ADODB_ASSOC_CASE){
172
			case 0: $m = PDO::CASE_LOWER; break;
173
			case 1: $m = PDO::CASE_UPPER; break;
174
			default:
175
			case 2: $m = PDO::CASE_NATURAL; break;
176
			}
177
 
178
			//$this->_connectionID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT );
179
			$this->_connectionID->setAttribute(PDO::ATTR_CASE,$m);
180
 
181
			$class = 'ADODB_pdo_'.$this->dsnType;
182
			//$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
183
			switch($this->dsnType) {
184
			case 'oci':
185
			case 'mysql':
186
			case 'pgsql':
187
			case 'mssql':
188
				include_once(ADODB_DIR.'/drivers/adodb-pdo_'.$this->dsnType.'.inc.php');
189
				break;
190
			}
191
			if (class_exists($class))
192
				$this->_driver = new $class();
193
			else
194
				$this->_driver = new ADODB_pdo_base();
195
 
196
			$this->_driver->_connectionID = $this->_connectionID;
197
			$this->_UpdatePDO();
198
			return true;
199
		}
200
		$this->_driver = new ADODB_pdo_base();
201
		return false;
202
	}
203
 
204
	// returns true or false
205
	function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
206
	{
207
		return $this->_connect($argDSN, $argUsername, $argPassword, $argDatabasename, true);
208
	}
209
 
210
	/*------------------------------------------------------------------------------*/
211
 
212
 
213
	function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
214
	{	
215
		$save = $this->_driver->fetchMode;
216
		$this->_driver->fetchMode = $this->fetchMode;
217
	 	$this->_driver->debug = $this->debug;
218
		$ret = $this->_driver->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
219
		$this->_driver->fetchMode = $save;
220
		return $ret;
221
	}
222
 
223
 
224
	function ServerInfo()
225
	{
226
		return $this->_driver->ServerInfo();
227
	}
228
 
229
	function MetaTables($ttype=false,$showSchema=false,$mask=false)
230
	{
231
		return $this->_driver->MetaTables($ttype,$showSchema,$mask);
232
	}
233
 
234
	function MetaColumns($table,$normalize=true)
235
	{
236
		return $this->_driver->MetaColumns($table,$normalize);
237
	}
238
 
239
	function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
240
	{
241
		$obj = $stmt[1];
242
		if ($type) $obj->bindParam($name,$var,$type,$maxLen);
243
		else $obj->bindParam($name, $var);
244
	}
245
 
246
 
247
	function ErrorMsg()
248
	{
249
		if ($this->_errormsg !== false) return $this->_errormsg;
250
		if (!empty($this->_stmt)) $arr = $this->_stmt->errorInfo();
251
		else if (!empty($this->_connectionID)) $arr = $this->_connectionID->errorInfo();
252
		else return 'No Connection Established';
253
 
254
 
255
		if ($arr) {
256
		 	if (sizeof($arr)<2) return '';
257
			if ((integer)$arr[1]) return $arr[2];
258
			else return '';
259
		} else return '-1';
260
	}
261
 
262
 
263
	function ErrorNo()
264
	{
265
		if ($this->_errorno !== false) return $this->_errorno;
266
		if (!empty($this->_stmt)) $err = $this->_stmt->errorCode();
267
		else if (!empty($this->_connectionID)) {
268
			$arr = $this->_connectionID->errorInfo();
269
			if (isset($arr[0])) $err = $arr[0];
270
			else $err = -1;
271
		} else
272
			return 0;
273
 
274
		if ($err == '00000') return 0; // allows empty check
275
		return $err;
276
	}
277
 
278
	function BeginTrans()
279
	{	
280
		if (!$this->hasTransactions) return false;
281
		if ($this->transOff) return true; 
282
		$this->transCnt += 1;
283
		$this->_autocommit = false;
284
		$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,false);
285
		return $this->_connectionID->beginTransaction();
286
	}
287
 
288
	function CommitTrans($ok=true) 
289
	{ 
290
		if (!$this->hasTransactions) return false;
291
		if ($this->transOff) return true; 
292
		if (!$ok) return $this->RollbackTrans();
293
		if ($this->transCnt) $this->transCnt -= 1;
294
		$this->_autocommit = true;
295
 
296
		$ret = $this->_connectionID->commit();
297
		$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
298
		return $ret;
299
	}
300
 
301
	function RollbackTrans()
302
	{
303
		if (!$this->hasTransactions) return false;
304
		if ($this->transOff) return true; 
305
		if ($this->transCnt) $this->transCnt -= 1;
306
		$this->_autocommit = true;
307
 
308
		$ret = $this->_connectionID->rollback();
309
		$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
310
		return $ret;
311
	}
312
 
313
	function Prepare($sql)
314
	{
315
		$this->_stmt = $this->_connectionID->prepare($sql);
316
		if ($this->_stmt) return array($sql,$this->_stmt);
317
 
318
		return false;
319
	}
320
 
321
	function PrepareStmt($sql)
322
	{
323
		$stmt = $this->_connectionID->prepare($sql);
324
		if (!$stmt) return false;
325
		$obj = new ADOPDOStatement($stmt,$this);
326
		return $obj;
327
	}
328
 
329
	/* returns queryID or false */
330
	function _query($sql,$inputarr=false) 
331
	{
332
		if (is_array($sql)) {
333
			$stmt = $sql[1];
334
		} else {
335
			$stmt = $this->_connectionID->prepare($sql);
336
		}
337
 
338
		if ($stmt) {
339
			$this->_driver->debug = $this->debug;
340
			if ($inputarr) $ok = $stmt->execute($inputarr);
341
			else $ok = $stmt->execute();
342
		} 
343
 
344
 
345
		$this->_errormsg = false;
346
		$this->_errorno = false;
347
 
348
		if ($ok) {
349
			$this->_stmt = $stmt;
350
			return $stmt;
351
		}
352
 
353
		if ($stmt) {
354
 
355
			$arr = $stmt->errorinfo();
356
			if ((integer)$arr[1]) {
357
				$this->_errormsg = $arr[2];
358
				$this->_errorno = $arr[1];
359
			}
360
 
361
		} else {
362
			$this->_errormsg = false;
363
			$this->_errorno = false;
364
		}
365
		return false;
366
	}
367
 
368
	// returns true or false
369
	function _close()
370
	{
371
		$this->_stmt = false;
372
		return true;
373
	}
374
 
375
	function _affectedrows()
376
	{
377
		return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
378
	}
379
 
380
	function _insertid()
381
	{
382
		return ($this->_connectionID) ? $this->_connectionID->lastInsertId() : 0;
383
	}
384
}
385
 
386
class ADOPDOStatement {
387
 
388
	var $databaseType = "pdo";		
389
	var $dataProvider = "pdo";
390
	var $_stmt;
391
	var $_connectionID;
392
 
393
	function ADOPDOStatement($stmt,$connection)
394
	{
395
		$this->_stmt = $stmt;
396
		$this->_connectionID = $connection;
397
	}
398
 
399
	function Execute($inputArr=false)
400
	{
401
		$savestmt = $this->_connectionID->_stmt;
402
		$rs = $this->_connectionID->Execute(array(false,$this->_stmt),$inputArr);
403
		$this->_connectionID->_stmt = $savestmt;
404
		return $rs;
405
	}
406
 
407
	function InParameter(&$var,$name,$maxLen=4000,$type=false)
408
	{
409
 
410
		if ($type) $this->_stmt->bindParam($name,$var,$type,$maxLen);
411
		else $this->_stmt->bindParam($name, $var);
412
	}
413
 
414
	function Affected_Rows()
415
	{
416
		return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
417
	}
418
 
419
	function ErrorMsg()
420
	{
421
		if ($this->_stmt) $arr = $this->_stmt->errorInfo();
422
		else $arr = $this->_connectionID->errorInfo();
423
 
424
		if (is_array($arr)) {
425
			if ((integer) $arr[0] && isset($arr[2])) return $arr[2];
426
			else return '';
427
		} else return '-1';
428
	}
429
 
430
	function NumCols()
431
	{
432
		return ($this->_stmt) ? $this->_stmt->columnCount() : 0;
433
	}
434
 
435
	function ErrorNo()
436
	{
437
		if ($this->_stmt) return $this->_stmt->errorCode();
438
		else return $this->_connectionID->errorInfo();
439
	}
440
}
441
 
442
/*--------------------------------------------------------------------------------------
443
	 Class Name: Recordset
444
--------------------------------------------------------------------------------------*/
445
 
446
class ADORecordSet_pdo extends ADORecordSet {	
447
 
448
	var $bind = false;
449
	var $databaseType = "pdo";		
450
	var $dataProvider = "pdo";
451
 
452
	function ADORecordSet_pdo($id,$mode=false)
453
	{
454
		if ($mode === false) {  
455
			global $ADODB_FETCH_MODE;
456
			$mode = $ADODB_FETCH_MODE;
457
		}
458
		$this->adodbFetchMode = $mode;
459
		switch($mode) {
460
		case ADODB_FETCH_NUM: $mode = PDO::FETCH_NUM; break;
461
		case ADODB_FETCH_ASSOC:  $mode = PDO::FETCH_ASSOC; break;
462
 
463
		case ADODB_FETCH_BOTH: 
464
		default: $mode = PDO::FETCH_BOTH; break;
465
		}
466
		$this->fetchMode = $mode;
467
 
468
		$this->_queryID = $id;
469
		$this->ADORecordSet($id);
470
	}
471
 
472
 
473
	function Init()
474
	{
475
		if ($this->_inited) return;
476
		$this->_inited = true;
477
		if ($this->_queryID) @$this->_initrs();
478
		else {
479
			$this->_numOfRows = 0;
480
			$this->_numOfFields = 0;
481
		}
482
		if ($this->_numOfRows != 0 && $this->_currentRow == -1) {
483
			$this->_currentRow = 0;
484
			if ($this->EOF = ($this->_fetch() === false)) {
485
				$this->_numOfRows = 0; // _numOfRows could be -1
486
			}
487
		} else {
488
			$this->EOF = true;
489
		}
490
	}
491
 
492
	function _initrs()
493
	{
494
	global $ADODB_COUNTRECS;
495
 
496
		$this->_numOfRows = ($ADODB_COUNTRECS) ? @$this->_queryID->rowCount() : -1;
497
		if (!$this->_numOfRows) $this->_numOfRows = -1;
498
		$this->_numOfFields = $this->_queryID->columnCount();
499
	}
500
 
501
	// returns the field object
502
	function &FetchField($fieldOffset = -1) 
503
	{
504
		$off=$fieldOffset+1; // offsets begin at 1
505
 
506
		$o= new ADOFieldObject();
507
		$arr = @$this->_queryID->getColumnMeta($fieldOffset);
508
		if (!$arr) {
509
			$o->name = 'bad getColumnMeta()';
510
			$o->max_length = -1;
511
			$o->type = 'VARCHAR';
512
			$o->precision = 0;
513
	#		$false = false;
514
			return $o;
515
		}
516
		//adodb_pr($arr);
517
		$o->name = $arr['name'];
518
		if (isset($arr['native_type'])) $o->type = $arr['native_type'];
519
		else $o->type = adodb_pdo_type($arr['pdo_type']);
520
		$o->max_length = $arr['len'];
521
		$o->precision = $arr['precision'];
522
 
523
		if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
524
		else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
525
		return $o;
526
	}
527
 
528
	function _seek($row)
529
	{
530
		return false;
531
	}
532
 
533
	function _fetch()
534
	{
535
		if (!$this->_queryID) return false;
536
 
537
		$this->fields = $this->_queryID->fetch($this->fetchMode);
538
		return !empty($this->fields);
539
	}
540
 
541
	function _close() 
542
	{
543
		$this->_queryID = false;
544
	}
545
 
546
	function Fields($colname)
547
	{
548
		if ($this->adodbFetchMode != ADODB_FETCH_NUM) return @$this->fields[$colname];
549
 
550
		if (!$this->bind) {
551
			$this->bind = array();
552
			for ($i=0; $i < $this->_numOfFields; $i++) {
553
				$o = $this->FetchField($i);
554
				$this->bind[strtoupper($o->name)] = $i;
555
			}
556
		}
557
		 return $this->fields[$this->bind[strtoupper($colname)]];
558
	}
559
 
560
}
561
 
562
?>