Completed
Push — master ( 3360d7...589ba9 )
by Fwolf
04:41
created

Adodb   D

Complexity

Total Complexity 139

Size/Duplication

Total Lines 1112
Duplicated Lines 21.04 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 234
loc 1112
rs 4.4102
c 0
b 0
f 0
wmc 139
lcom 1
cbo 2

30 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 2
B __call() 5 49 5
A __get() 0 3 1
A __set() 0 3 1
F Connect() 9 100 10
A CountDbQueryTimes() 0 4 1
A DelRow() 13 13 3
B EncodingConvert() 13 13 6
B EncodingConvertReverse() 13 13 6
A ExecuteGenSql() 0 3 1
C FindColTs() 11 58 10
A GenSql() 0 8 2
A GenSqlPrepare() 0 6 2
F GetDataByPk() 19 70 16
B GetMetaColumn() 5 21 6
A GetMetaColumnName() 3 6 3
D GetMetaPrimaryKey() 32 86 17
A GetRowCount() 12 12 4
A GetSqlDelimiter() 0 11 3
A GetSqlTransBegin() 0 6 2
A GetSqlTransCommit() 0 3 1
A GetSqlTransRollback() 0 3 1
A IsDbMysql() 0 3 1
A IsDbSybase() 0 4 2
A IsTsUnique() 0 7 2
A PExecute() 8 15 2
A PExecuteGenSql() 0 3 1
B QuoteValue() 39 39 5
A TblExists() 18 18 3
F Write() 34 131 20

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Adodb often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Adodb, and based on these observations, apply Extract Interface, too.

1
<?php
2
// Set include path in __construct
3
//require_once('adodb/adodb.inc.php');
4
require_once(dirname(__FILE__) . '/fwolflib.php');
5
require_once(dirname(__FILE__) . '/sql_generator.php');
6
require_once(dirname(__FILE__) . '/../func/ecl.php');
7
require_once(dirname(__FILE__) . '/../func/string.php');
8
9
10
/**
11
 * Extended ADODB class
12
 *
13
 * Include all ADODB had, and add a little others.
14
 *
15
 * Piror use this class' method and property, if the get/set/call target
16
 * is not exists, use original ADODB's, this can be done by php's mechematic
17
 * of overload __call __get __set.
18
 *
19
 * 这似乎是extend ADODB的一种比较好的方式,比官方网站文档上给的按不同数据库来继承子类的方式,
20
 * 我认为要更方便一些。缺点是没有对RecordSet对象进行处理。
21
 *
22
 * Adodb for Sybase bug:
23
 * Affected_Rows() in windows 2003 不可用,httpd 进程会出错中止
24
 *
25
 * 执行sql查询的系列更改中,限定系统/HTML/PHP使用$sSysCharset指定的编码,涉及函数列在__call()中,
26
 * 但一些通过数组等其它方式传递参数的ADODB方法仍然无法通过这种方式实现sql编码自动转换。
27
 *
28
 * 执行返回的数据还是需要转码的,不过返回数据的种类太多,放在应用中实现更简单一些,这里不自动执行,
29
 * 只提供一个EncodingConvert方法供用户调用。
30
 *
31
 * @deprecated  Use Fwlib\Bridge\Adodb
32
 * @package		fwolflib
33
 * @subpackage	class
34
 * @copyright	Copyright 2008-2012, Fwolf
35
 * @author		Fwolf <[email protected]>
36
 * @since		2008-04-08
37
 */
38
class Adodb extends Fwolflib {
0 ignored issues
show
Deprecated Code introduced by
The class Fwolflib has been deprecated with message: Use classes in Fwlib namespace, see PSR-0/1/2

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
39
40
	/**
41
	 * Real ADODB connection object
42
	 * @var object
43
	 */
44
	protected $__conn = null;
45
46
	/**
47
	 * Db profile
48
	 * @var array
49
	 */
50
	public $aDbProfile = null;
51
52
	/**
53
	 * Table schema
54
	 *
55
	 * array(
56
	 * 	col ->	// ADOFieldObject Object, not Array !
57
	 * 		[name] => ts
58
	 * 		[max_length] => -1
59
	 * 		[type] => timestamp
60
	 * 		[scale] =>
61
	 * 		[not_null] => 1
62
	 * 		[primary_key] =>
63
	 * 		[auto_increment] =>
64
	 * 		[binary] =>
65
	 * 		[unsigned] =>
66
	 * 		[zerofill] =>
67
	 * 		[has_default] => 1
68
	 * 		[default_value] => CURRENT_TIMESTAMP
69
	 * 	)
70
	 * )
71
	 * @var array
72
	 */
73
	public $aMetaColumn = array();
74
75
	/**
76
	 * Table column name array, index is upper case of column name
77
	 *
78
	 * eg: array(
79
	 * 	'COLUMN' => 'column',
80
	 * )
81
	 * @var	array
82
	 */
83
	public $aMetaColumnName = array();
84
85
	/**
86
	 * Primary key columns of table
87
	 *
88
	 * array(
89
	 * 	tbl_name -> 'col_pk',
90
	 * 	tbl_name -> array(pk_col1, pk_col2),
91
	 * )
92
	 * @var	array
93
	 */
94
	public $aMetaPrimaryKey = array();
95
96
	/**
97
	 * Sql generator object
98
	 * @var object
99
	 */
100
	protected $oSg;
101
102
	/**
103
	 * Error msg
104
	 * @var	string
105
	 */
106
	public $sErrorMsg = '';
107
108
	/**
109
	 * System charset
110
	 *
111
	 * In common, this is your php script/operation system charset
112
	 * @var string
113
	 */
114
	public $sSysCharset = 'utf8';
115
116
117
	/**
118
	 * construct
119
	 *
120
	 * <code>
121
	 * $dbprofile = array(type, host, user, pass, name, lang);
122
	 * type is mysql/sybase_ase etc,
123
	 * name is dbname to select,
124
	 * lang is db server charset.
125
	 * </code>
126
	 * @var param	array	$dbprofile
127
	 * @var param	string	$path_adodb		Include path of original ADODB
128
	 */
129
	public function __construct ($dbprofile, $path_adodb = '') {
130
		parent::__construct();
131
132
		// Include original adodb lib
133
		if (empty($path_adodb))
134
			$path_adodb = 'adodb/adodb.inc.php';
135
		require_once($path_adodb);
136
137
		$this->aDbProfile = $dbprofile;
138
		$this->__conn = ADONewConnection($dbprofile['type']);
139
140
		// Sql generator object
141
		$this->oSg = new SqlGenerator($this);
0 ignored issues
show
Deprecated Code introduced by
The class SqlGenerator has been deprecated with message: Use Fwlib\Db\SqlGenerator

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
142
	} // end of class __construct
143
144
145
	/**
146
	 * Overload __call, redirect method call to adodb
147
	 *
148
	 * @var string	$name	Method name
149
	 * @var array	$arg	Method argument
150
	 * @global	int	$i_db_query_times
151
	 * @return mixed
152
	 */
153
	public function __call ($name, $arg) {
154
		// Before call, convert $sql encoding first
155
		if ($this->sSysCharset != $this->aDbProfile['lang']) {
156
			// Method list by ADODB doc order
157
			// $sql is the 1st param
158
			if (in_array($name, array('Execute',
159
									  'CacheExecute',
160
									  'SelectLimit',
161
									  'CacheSelectLimit',
162
									  'Prepare',
163
									  'PrepareSP',
164
									  'GetOne',
165
									  'GetRow',
166
									  'GetAll',
167
									  'GetCol',
168
									  'CacheGetOne',
169
									  'CacheGetRow',
170
									  'CacheGetAll',
171
									  'CacheGetCol',
172
									  'GetAssoc',
173
									  'CacheGetAssoc',
174
									  'ExecuteCursor',
175
									)))
176
				$arg[0] = mb_convert_encoding($arg[0], $this->aDbProfile['lang'], $this->sSysCharset);
177
178
			// $sql is the 2nd param
179
			if (in_array($name, array('CacheExecute',
180
									  'CacheSelectLimit',
181
									  'CacheGetOne',
182
									  'CacheGetRow',
183
									  'CacheGetAll',
184
									  'CacheGetCol',
185
									  'CacheGetAssoc',
186
									)))
187
				$arg[1] = mb_convert_encoding($arg[1], $this->aDbProfile['lang'], $this->sSysCharset);
188
		}
189
190
		// Count db query times
191
		// Use global var so multi Adodb object can be included in count.
192
		//	(Done in func now)
193
		// Use standalone func to can be easy extend by sub class.
194 View Code Duplication
		if (in_array($name, array(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
195
			'Execute', 'SelectLimit', 'GetOne', 'GetRow', 'GetAll',
196
			'GetCol', 'GetAssoc', 'ExecuteCursor'
197
			)))
198
			$this->CountDbQueryTimes();
199
200
		return call_user_func_array(array($this->__conn, $name), $arg);
201
	} // end of func __call
202
203
204
	/**
205
	 * Overload __get, redirect method call to adodb
206
	 *
207
	 * @param string	$name
208
	 * @return mixed
209
	 */
210
	public function __get ($name) {
211
		return $this->__conn->$name;
212
	} // end of func __get
213
214
215
	/**
216
	 * Overload __set, redirect method call to adodb
217
	 *
218
	 * @param string	$name
219
	 * @param mixed		$val
220
	 */
221
	public function __set ($name, $val) {
222
		$this->__conn->$name = $val;
223
	} // end of func __set
224
225
226
	/**
227
}
228
	 * Connect, Add mysql 'set names utf8'
229
	 *
230
	 * <code>
231
	 * Obmit params(dbprofile was set in __construct):
232
	 * param $argHostname		Host to connect to
233
	 * param $argUsername		Userid to login
234
	 * param $argPassword		Associated password
235
	 * param $argDatabaseName	database
236
	 * </code>
237
	 * @param $forcenew			Force new connection
238
	 * @return boolean
239
	 */
240
	public function Connect ($forcenew = false) {
241
		// Mysqli doesn't allow port in host, grab it out and set
242 View Code Duplication
		if ('mysqli' == strtolower($this->__conn->databaseType)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
243
			$ar = array();
244
			$i = preg_match('/:(\d+)$/', $this->aDbProfile['host'], $ar);
245
			if (0 < $i) {
246
				$this->__conn->port = $ar[1];
247
				$this->aDbProfile['host'] = preg_replace('/:(\d+)$/', ''
248
					, $this->aDbProfile['host']);
249
			}
250
		}
251
252
253
		try {
254
			// Disable error display tempratory
255
			$s = ini_get("display_errors");
256
			ini_set("display_errors", "0");
257
258
			// Sybase will echo 'change to master' warning msg
259
			// :THINK: Will this problem solved if we drop default
260
			// database master from sa user ?
261
			if ($this->IsDbSybase()) {
262
				$rs = $this->__conn->Connect($this->aDbProfile['host'],
263
										 $this->aDbProfile['user'],
264
										 $this->aDbProfile['pass'],
265
										 $this->aDbProfile['name'],
266
										 $forcenew);
267
			}
268
			else {
269
				$rs = $this->__conn->Connect($this->aDbProfile['host'],
270
										 $this->aDbProfile['user'],
271
										 $this->aDbProfile['pass'],
272
										 $this->aDbProfile['name'],
273
										 $forcenew);
274
			}
275
276
			// Recover original error display setting
277
			ini_set("display_errors", $s);
278
279
			if (empty($rs)) {
280
				throw new Exception('Db connect fail, please check php errorlog.', -1);
281
			}
282
		} catch (Exception $e) {
283
			// Get error trace message
284
			$i_ob = ob_get_level();
285
			if (0 != $i_ob)
286
				$s_t = ob_get_clean();
287
288
			ob_start();
289
			adodb_backtrace($e->getTrace());
290
			$s_trace = ob_get_clean();
291
292
			if (0 != $i_ob) {
293
				// Maybe cause error if output handle of ob_start used before
294
				ob_start();
295
				echo $s_t;
0 ignored issues
show
Bug introduced by
The variable $s_t does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
296
			}
297
298
299
			// Log error
300
			$s_trace = "======== Adodb db connect error\n"
301
				. str_replace('&nbsp;', '>', strip_tags($s_trace))
302
				. $this->ErrorMsg() . "\n";
0 ignored issues
show
Documentation Bug introduced by
The method ErrorMsg does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
303
			$this->sErrorMsg = $s_trace;
304
			error_log($s_trace);
305
306
/*
307
			// Print error
308
			$this->sErrorMsg = 'Error, code '
309
				. $e->getCode()
310
				. ', msg: ' . $e->getMessage();
311
312
			// Log error
313
			$s_trace = str_replace('&nbsp;', '>', strip_tags($s_trace));
314
			error_log('');
315
			error_log('======== Adodb db connect error');
316
			error_log("\n" . $s_trace);
317
			error_log($this->sErrorMsg);
318
			//error_log('');
319
*/
320
321
			//var_dump($e);
322
			//echo $e;
323
			if (0 != $i_ob) {
324
				ob_end_flush();
325
			}
326
			//exit();
327
			return false;
328
		}
329
330
		// 针对mysql 4.1以上,UTF8编码的数据库,需要在连接后指定编码
331
		// Can also use $this->aDbProfile['type']
332
		// mysql, mysqli
333
		if ($this->IsDbMysql()) {
334
			$this->__conn->Execute('set names "' . str_replace('utf-8', 'utf8', $this->aDbProfile['lang']) . '"');
335
		}
336
337
		//return $rs;
338
		return true;
339
	} // end of func Connect
340
341
342
	/**
343
	 * Count how many db query have executed
344
	 *
345
	 * This function can be extend by subclass if you want to count on multi db objects.
346
	 *
347
	 * Can't count in Adodb::property, because need display is done by Controler,
348
	 * which will call View, but Adodb is property of Module,
349
	 * so we can only use global vars to save this value.
350
	 * @global	int	$i_db_query_times
351
	 */
352
	protected function CountDbQueryTimes () {
353
		global $i_db_query_times;
354
		$i_db_query_times ++;
355
	} // end of func CountDbQueryTimes
356
357
358
	/**
359
	 * Delete rows by condition user given
360
	 *
361
	 * @param	string	$tbl
362
	 * @param	string	$cond	Condition, can be where, having etc, raw sql string, not null.
363
	 * @return	int		-1 error/0 not found/N > 0 number of rows
364
	 */
365 View Code Duplication
	public function DelRow ($tbl, $cond) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
366
		$cond = trim($cond);
367
		if (empty($cond))
368
			return -1;
369
		$this->PExecute($this->GenSql(array(
370
			'DELETE' => $tbl,
371
			)) . ' ' . $cond);
372
		if (0 != $this->ErrorNo())
0 ignored issues
show
Documentation Bug introduced by
The method ErrorNo does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
373
			// Execute error
374
			return -1;
375
		else
376
			return $this->Affected_Rows();
0 ignored issues
show
Documentation Bug introduced by
The method Affected_Rows does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
377
	} // end of func DelRow
378
379
380
	/**
381
	 * Convert recordset(simple array) or other string
382
	 * from db encoding to system encoding
383
	 *
384
	 * Use recursive mechanism, beware of loop hole.
385
	 * @param mixed	&$s	Source to convert
386
	 * @return mixed
387
	 */
388 View Code Duplication
	public function EncodingConvert (&$s) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
389
		if (is_array($s) && !empty($s)) {
390
			foreach ($s as &$val)
391
				$this->EncodingConvert($val);
392
			unset($val);
393
		}
394
395
		if (is_string($s)) {
396
			if ($this->sSysCharset != $this->aDbProfile['lang'])
397
				$s = mb_convert_encoding($s, $this->sSysCharset, $this->aDbProfile['lang']);
398
		}
399
		return $s;
400
	} // end of func EncodingConvert
401
402
403
	/**
404
	 * Convert data encoding
405
	 * from system(usually utf-8) to db
406
	 *
407
	 * Use recursive mechanism, beware of loop hole.
408
	 * @param mixed	&$s	Source to convert
409
	 * @return mixed
410
	 */
411 View Code Duplication
	public function EncodingConvertReverse (&$s) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
412
		if (is_array($s) && !empty($s)) {
413
			foreach ($s as &$val)
414
				$this->EncodingConvertReverse($val);
415
			unset($val);
416
		}
417
418
		if (is_string($s)) {
419
			if ($this->sSysCharset != $this->aDbProfile['lang'])
420
				$s = mb_convert_encoding($s, $this->aDbProfile['lang'], $this->sSysCharset);
421
		}
422
		return $s;
423
	} // end of func EncodingConvertReverse
424
425
426
	/**
427
	 * Generate SQL then exec it
428
	 *
429
	 * @param	array	$ar_sql		Same as GenSql()
430
	 * @return	object
431
	 * @see	GenSql()
432
	 */
433
	public function ExecuteGenSql ($ar_sql) {
434
		return $this->Execute($this->GenSql($ar_sql));
0 ignored issues
show
Bug introduced by
The method Execute() does not exist on Adodb. Did you maybe mean ExecuteGenSql()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
435
	} // end of func ExecuteGenSql
436
437
438
	/**
439
	 * Find name of timestamp column of a table
440
	 *
441
	 * @param	$tbl	Table name
442
	 * @return	string
443
	 */
444
	public function FindColTs ($tbl) {
445
		$ar_col = $this->GetMetaColumn($tbl);
446
		if (empty($ar_col))
447
			return '';
448
449
		if ($this->IsDbSybase()) {
450
			// Sybase's timestamp column must be lower cased
451
			// Can name as others, but name as 'timestamp' will auto got )timestamp) type.
452
			/*
453
			if (isset($ar_col['timestamp']))
454
				return 'timestamp';
455
			else
456
				return '';
457
			*/
458
			// New way:
459
			// http://bbs.chinaunix.net/archiver/tid-930729.html
460
			$rs = $this->ExecuteGenSql(array(
461
				'SELECT' => array(
462
					'name'		=> 'a.name',
463
					'length' 	=> 'a.length',
464
					'usertype'	=> 'a.usertype',
465
					'type'		=> 'b.name',
466
					'tableName' => 'c.name',
467
					),
468
				'FROM'	=> array(
469
					'a' => 'syscolumns',
470
					'b' => 'systypes',
471
					'c' => 'sysobjects',
472
					),
473
				'WHERE' => array(
474
					"a.id = c.id",
475
					'a.type = b.type',
476
					'a.usertype = b.usertype',
477
                    'b.type = 37',
478
                    'b.usertype = 80',
479
					),
480
				));
481 View Code Duplication
			while (!empty($rs) && !$rs->EOF) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
482
				if ($tbl == $rs->fields['tableName']) {
483
                    return $rs->fields['name'];
484
				}
485
			}
486
487
			return '';
488
			//select a.name,a.length,a.usertype,b.name AS type from syscolumns a ,systypes b
489
			//where id = object_id('ztb_yh') and a.type=b.type and a.usertype = b.usertype
490
491
		}
492 View Code Duplication
		elseif ($this->IsDbMysql()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
493
			// Check 'type'
494
			foreach ($ar_col as $k => $v)
495
				if (isset($v->type) && 'timestamp' == $v->type)
496
					return $k;
497
		}
498
		else {
499
			die("FindColTs not implemented!\n");
500
		}
501
	} // end of func FindColTs
502
503
504
	/**
505
	 * Generate SQL statement
506
	 *
507
	 * User should avoid use SELECT/UPDATE/INSERT/DELETE simultaneously.
508
	 *
509
	 * Generate order by SQL statement format order.
510
	 *
511
	 * UPDATE/INSERT/DELETE is followed by [TBL_NAME],
512
	 * so need not use FROM.
513
	 * @param array	$ar_sql	Array(select=>..., from=>...)
514
	 * @return string
515
	 * @see	SqlGenerator
516
	 */
517
	public function GenSql ($ar_sql) {
518
		// Changed to use SqlGenerator
519
		if (!empty($ar_sql)) {
520
			return $this->oSg->GetSql($ar_sql);
521
		}
522
		else
523
			return '';
524
	} // end of func GenSql
525
526
527
	/**
528
	 * Generate SQL statement for Prepare
529
	 *
530
	 * value -> ? or :name, and quote chars removed
531
	 * @param	array	$ar_sql	Same as GenSql()
532
	 * @return	string
533
	 * @see	GenSql()
534
	 * @see	SqlGenerator
535
	 */
536
	public function GenSqlPrepare ($ar_sql) {
537
		if (!empty($ar_sql))
538
			return $this->oSg->GetSqlPrepare($ar_sql);
539
		else
540
			return '';
541
	} // end of func GenSqlPrepare
542
543
544
	/**
545
	 * Get data from single table using PK
546
	 *
547
	 * $m_pk, $col, $col_pk support string split by ',' or array, like:
548
	 * 1. 'val'
549
	 * 2. 'val1, val2'
550
	 * 3. array('val1', 'val2')
551
	 *
552
	 * '*' can be used for $col, means all cols in table, this way can't use
553
	 * cache, not recommend.
554
	 *
555
	 * Notice: $col must indexed by number start from 0.
556
	 *
557
	 * Also, this function can be used to retrieve data from a table with
558
	 * single unique index, by assigning $col_pk to non-PK column.
559
	 *
560
	 * @param	string	$s_tbl
561
	 * @param	mixed	$m_pk			PK value
562
	 * @param	mixed	$col			Cols need to retrieve.
563
	 * @param	mixed	$col_pk			PK column name, NULL to auto get.
564
	 * @return	mixed					Single/array, NULL if error occur.
565
	 */
566
	public function GetDataByPk ($s_tbl, $m_pk, $col = NULL, $col_pk = NULL) {
567
		// Treat PK col
568
		if (empty($col_pk)) {
569
			$col_pk = $this->GetMetaPrimaryKey($s_tbl);
570
		}
571
572
		// PK and col name all convert to array
573 View Code Duplication
		if (!is_array($m_pk)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
574
			if (is_string($m_pk))
575
				$m_pk = StrToArray($m_pk, ',');
0 ignored issues
show
Deprecated Code introduced by
The function StrToArray() has been deprecated with message: Use Fwlib\Util\StringUtil::toArray()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
576
			else
577
				$m_pk = array($m_pk);
578
		}
579 View Code Duplication
		if (!is_array($col_pk)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
580
			if (is_string($col_pk))
581
				$col_pk = StrToArray($col_pk, ',');
0 ignored issues
show
Deprecated Code introduced by
The function StrToArray() has been deprecated with message: Use Fwlib\Util\StringUtil::toArray()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
582
			else
583
				$col_pk = array($col_pk);
584
		}
585
586
		// $col_pk need to be array same count with $m_pk
587
		if (count($m_pk) != count($col_pk)) {
588
			$this->Log('PK value and column not match.', 4);
589
			return NULL;
590
		}
591
592
		// Treat col
593
		if (empty($col))
594
			$col = '*';
595
		if ('*' == $col)
596
			// Drop uppercased index
597
			$col = array_values($this->GetMetaColumnName($s_tbl));
598 View Code Duplication
		if (!is_array($col)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
599
			if (is_string($col))
600
				// String split by ',', style 'col AS col_alias' allowed
601
				$col = StrToArray($col, ',');
0 ignored issues
show
Deprecated Code introduced by
The function StrToArray() has been deprecated with message: Use Fwlib\Util\StringUtil::toArray()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
602
			else
603
				$col = array($col);
604
		}
605
606
		// $m_pk, $col, $col_pk all converted to array
607
608
		// Retrieve from db
609
		$ar_sql = array(
610
			'SELECT'	=> $col,
611
			'FROM'		=> $s_tbl,
612
			'LIMIT'		=> 1,
613
		);
614
		while (!empty($m_pk)) {
615
			$s_col_pk = array_shift($col_pk);
616
			$ar_sql['WHERE'][] = $s_col_pk . ' = '
617
				. $this->QuoteValue($s_tbl, $s_col_pk, array_shift($m_pk));
618
			unset($s_col_pk);
619
		}
620
		$rs = $this->ExecuteGenSql($ar_sql);
621
		$ar_rs = array();
622
		if (!empty($rs) && !$rs->EOF) {
623
			$ar_rs = $rs->GetRowAssoc(false);
624
		}
625
626
		// Return value
627
		if (empty($ar_rs))
628
			return NULL;
629
		else {
630
			if (1 == count($ar_rs))
631
				return array_pop($ar_rs);
632
			else
633
				return $ar_rs;
634
		}
635
	} // end of func GetDataByPk
636
637
638
	/**
639
	 * Get table schema
640
	 *
641
	 * @param	string	$table
642
	 * @param	boolean	$forcenew	Force to retrieve instead of read from cache
643
	 * @return	array
644
	 * @see $aMetaColumn
645
	 */
646
	public function GetMetaColumn ($table, $forcenew = false) {
647
		if (!isset($this->aMetaColumn[$table]) || (true == $forcenew)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
648
			$this->aMetaColumn[$table] = $this->MetaColumns($table);
0 ignored issues
show
Documentation Bug introduced by
The method MetaColumns does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
649
650
			// Convert columns to native case
651
			$col_name = $this->GetMetaColumnName($table);
652
			// $col_name = array(COLUMN => column), $c is UPPER CASED
653
			foreach ($this->aMetaColumn[$table] as $c => $ar) {
654
				$this->aMetaColumn[$table][$col_name[$c]] = $ar;
655
				unset($this->aMetaColumn[$table][$c]);
656
			}
657
			// Fix: sybase db display timestamp column as varbinary
658 View Code Duplication
			if ($this->IsDbSybase()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
659
				$s = $this->FindColTs($table);
660
				if (!empty($s))
661
					$this->aMetaColumn[$table][$s]->type = 'timestamp';
662
			}
663
			//print_r($this->aMetaColumn);
664
		}
665
		return $this->aMetaColumn[$table];
666
	} // end of func GetMetaColumn
667
668
669
	/**
670
	 * Get table column name
671
	 *
672
	 * @param	string	$table
673
	 * @param	boolean	$forcenew	Force to retrieve instead of read from cache
674
	 * @return	array
675
	 * @see $aMetaColumnName
676
	 */
677
	public function GetMetaColumnName ($table, $forcenew = false) {
678 View Code Duplication
		if (!isset($this->aMetaColumnName[$table]) || (true == $forcenew)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
679
			$this->aMetaColumnName[$table] = $this->MetaColumnNames($table);
0 ignored issues
show
Documentation Bug introduced by
The method MetaColumnNames does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
680
		}
681
		return $this->aMetaColumnName[$table];
682
	} // end of func GetMetaColumnName
683
684
685
	/**
686
	 * Get primary key column of a table
687
	 *
688
	 * @param	string	$table
689
	 * @param	boolean	$forcenew	Force to retrieve instead of read from cache
690
	 * @return	mixed	Single string value or array when primary key contain multi columns.
691
	 * @see $aMetaPrimaryKey
692
	 */
693
	public function GetMetaPrimaryKey ($table, $forcenew = false) {
694
		if (!isset($this->aMetaPrimaryKey[$table]) || (true == $forcenew)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
695
			// Find using Adodb first
696
			$ar = $this->MetaPrimaryKeys($table);
0 ignored issues
show
Documentation Bug introduced by
The method MetaPrimaryKeys does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
697
			if (false == $ar || empty($ar)) {
698
				// Adodb not support, find by hand
699
				// Sybase
700
				// 	keys1、keys2、keys3的描述不清,应该是:
701
				//	select name ,keycnt
702
				//		,index_col(YourTableName,indid,1)   --主键中的第一列
703
				//		,index_col(YourTableName,indid,2)   --主键中的第二列,如果有的话
704
				//	from   sysindexes
705
				//	where   status   &   2048=2048
706
				//		and   id=object_id(YourTableName)
707
				// 主键涉及的列的数量在keycnt中。如果主键索引不是簇集索引(由status中的0x10位决定)的话,则为keycnt-1。
708
				// http://topic.csdn.net/t/20030117/17/1369396.html
709
				// 根据这种方法,目前好像只能用于主键包含三个以下字段的情况?
710
				// 已测试过主键包含两个字段的情况下能取出来
711
				/*
712
				 select name, keycnt, index_col('sgqyjbqk', indid, 1)
713
				, index_col('sgqyjbqk', indid, 2)
714
				, index_col('sgqyjbqk', indid, 3)
715
				from sysindexes
716
				where status & 2048 = 2048
717
					and id = object_id('sgqyjbqk')
718
				 */
719 View Code Duplication
				if ($this->IsDbSybase()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
720
					$rs = $this->PExecuteGenSql(array(
721
						'select' => array(
722
							'name' => 'a.name',
723
							'keycnt' => 'a.keycnt',
724
							'k1' => "index_col('$table', indid, 1)",
725
							'k2' => "index_col('$table', indid, 2)",
726
							'k3' => "index_col('$table', indid, 3)",
727
							),
728
						'from'	=> array(
729
							'a' => 'sysindexes',
730
							'b' => 'sysobjects',
731
						),
732
						'where' => array(
733
							'a.status & 2048 = 2048 ',
734
							"b.name = '$table'",
735
							"a.id = b.id"
736
							)
737
						));
738
					if (true == $rs && 0 < $rs->RowCount()) {
739
						// Got
740
						$ar = array($rs->fields['k1']);
741
						if (!empty($rs->fields['k2']))
742
							$ar[] = $rs->fields['k2'];
743
						if (!empty($rs->fields['k3']))
744
							$ar[] = $rs->fields['k3'];
745
					}
746
					else {
747
						// Table have no primary key
748
						$ar = '';
749
					}
750
				}
751
			}
752
753
			// Convert columns to native case
754
			if (!empty($ar)) {
755
				$col_name = $this->GetMetaColumnName($table);
756
				// $col_name = array(COLUMN => column), $c is UPPER CASED
757
				foreach ($ar as $idx => &$col) {
758
					if ($col != $col_name[strtoupper($col)]) {
759
						unset($ar[$idx]);
760
						$ar[] = $col_name[strtoupper($col)];
761
					}
762
				}
763
				unset($col);
764
			}
765
766
			if (is_array($ar) && 1 == count($ar))
767
				// Only 1 primary key column
768
				$ar = $ar[0];
769
770
			// Set to cache
771
			if (!empty($ar))
772
				$this->aMetaPrimaryKey[$table] = $ar;
773
		}
774
		if (isset($this->aMetaPrimaryKey[$table]))
775
			return $this->aMetaPrimaryKey[$table];
776
		else
777
			return '';
778
	} // end of func GetMetaPrimaryKey
779
780
781
	/**
782
	 * Get rows count by condition user given
783
	 *
784
	 * @param	string	$tbl
785
	 * @param	string	$cond	Condition, can be where, having etc, raw sql string.
786
	 * @return	int		-1: error/N >= 0: number of rows
787
	 */
788 View Code Duplication
	public function GetRowCount ($tbl, $cond = '') {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
789
		$rs = $this->PExecute($this->GenSql(array(
790
			'SELECT' => array('c' => 'count(1)'),
791
			'FROM'	=> $tbl,
792
			)) . ' ' . $cond);
793
		if (false == $rs || 0 != $this->ErrorNo()
0 ignored issues
show
Documentation Bug introduced by
The method ErrorNo does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
794
				|| 0 == $rs->RowCount())
795
			// Execute error
796
			return -1;
797
		else
798
			return $rs->fields['c'];
799
	} // end of func GetRowCount
800
801
802
	/**
803
	 * Get delimiter between SQL for various db
804
	 *
805
	 * @return	string
806
	 */
807
	public function GetSqlDelimiter () {
808
		if ($this->IsDbMysql())
809
			return ";\n";
810
		elseif ($this->IsDbSybase())
811
			return "\n";
812
		else {
813
			$this->Log('GetSqlDelimiter() for this kind of db not implement.'
814
				, 5);
815
			return "\n";
816
		}
817
	} // end of func GetSqlDelimiter
818
819
820
	/**
821
	 * Get SQL: begin transaction
822
	 *
823
	 * @return	string
824
	 */
825
	public function GetSqlTransBegin () {
826
		if ($this->IsDbMysql())
827
			return 'START TRANSACTION' . $this->GetSqlDelimiter();
828
		else
829
			return 'BEGIN TRANSACTION' . $this->GetSqlDelimiter();
830
	} // end of func GetSqlTransBegin
831
832
833
	/**
834
	 * Get SQL: commit transaction
835
	 *
836
	 * @return	string
837
	 */
838
	public function GetSqlTransCommit () {
839
		return 'COMMIT' . $this->GetSqlDelimiter();
840
	} // end of func GetSqlTransCommit
841
842
843
	/**
844
	 * Get SQL: rollback transaction
845
	 *
846
	 * @return	string
847
	 */
848
	public function GetSqlTransRollback () {
849
		return 'ROLLBACK' . $this->GetSqlDelimiter();
850
	} // end of func GetSqlTransRollback
851
852
853
	/**
854
	 * If current db is a mysql db.
855
	 *
856
	 * @return	boolean
857
	 */
858
	public function IsDbMysql () {
859
		return ('mysql' == substr($this->__conn->databaseType, 0, 5));
860
	} // end of func IsDbMysql
861
862
863
	/**
864
	 * If current db is a sybase db.
865
	 *
866
	 * @return	boolean
867
	 */
868
	public function IsDbSybase () {
869
        return ('sybase' == substr($this->aDbProfile['type'], 0, 6)) ||
870
            ('pdo_sybase' == substr($this->aDbProfile['type'], 0, 10));
871
	}
872
873
874
	/**
875
	 * Is timestamp column's value is unique
876
	 *
877
	 * @return	boolean
878
	 */
879
	public function IsTsUnique () {
880
		if ('sybase' == $this->IsDbSybase())
881
			return true;
882
		else
883
			// Mysql
884
			return false;
885
	} // end of func IsTsUnique
886
887
888
	/**
889
	 * Prepare and execute sql
890
	 *
891
	 * @param	string	$sql
892
	 * @param	array	$inputarr	Optional parameters in sql
893
	 * @return	object
894
	 */
895
	public function PExecute ($sql, $inputarr = false) {
896
		$stmt = $this->Prepare($sql);
0 ignored issues
show
Bug introduced by
The method Prepare() does not exist on Adodb. Did you maybe mean GenSqlPrepare()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
897
		$this->BeginTrans();
0 ignored issues
show
Documentation Bug introduced by
The method BeginTrans does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
898
		$rs = $this->Execute($stmt, $inputarr);
0 ignored issues
show
Bug introduced by
The method Execute() does not exist on Adodb. Did you maybe mean ExecuteGenSql()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
899 View Code Duplication
		if (0 != $this->ErrorNo()) {
0 ignored issues
show
Documentation Bug introduced by
The method ErrorNo does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
900
			// Log to error log file
901
			error_log('ErrorNo: ' . $this->ErrorNo()
0 ignored issues
show
Documentation Bug introduced by
The method ErrorNo does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
902
				. "\nErrorMsg: " . $this->ErrorMsg()
0 ignored issues
show
Documentation Bug introduced by
The method ErrorMsg does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
903
				);
904
			$this->RollbackTrans();
0 ignored issues
show
Documentation Bug introduced by
The method RollbackTrans does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
905
			return -1;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return -1; (integer) is incompatible with the return type documented by Adodb::PExecute of type object.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
906
		}
907
		$this->CommitTrans();
0 ignored issues
show
Documentation Bug introduced by
The method CommitTrans does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
908
		return $rs;
909
	} // end of PExecute
910
911
912
	/**
913
	 * Generate, prepare and exec SQL
914
	 *
915
	 * @param	array	$ar_sql		Same as GenSql()
916
	 * @param	array	$inputarr	Optional parameters in sql
917
	 * @return	object
918
	 * @see	GenSql()
919
	 */
920
	public function PExecuteGenSql ($ar_sql, $inputarr = false) {
921
		return $this->PExecute($this->GenSqlPrepare($ar_sql), $inputarr);
922
	} // end of func PExecuteGenSql
923
924
925
	/**
926
	 * Smarty quote string in sql, by check columns type
927
	 *
928
	 * @param	string	$table
929
	 * @param	string	$column
930
	 * @param	mixed	$val
931
	 * @return	string
932
	 */
933 View Code Duplication
	public function QuoteValue ($table, $column, $val) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
934
		$this->GetMetaColumn($table);
935
		if (!isset($this->aMetaColumn[$table][$column]->type)) {
936
			error_log("Column to quote not exists($table.$column).\n");
937
			// Return quoted value for safety
938
			$val = stripslashes($val);
939
			return $this->qstr($val, false);
0 ignored issues
show
Documentation Bug introduced by
The method qstr does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
940
		}
941
942
		//print_r($this->aMetaColumn[$table][$column]);
943
		$type = $this->aMetaColumn[$table][$column]->type;
944
		//var_dump($type);
945
		if (in_array($type, array(
946
				'bigint',
947
				'bit',
948
				'decimal',
949
				'double',
950
				'float',
951
				'int',
952
				'intn', // Sybase - tinyint
953
				'mediumint',
954
				'numeric',
955
				'numericn',	// Sybase - numeric
956
				'real',
957
				'smallint',
958
				'tinyint',
959
			)))
960
			// Need not quote, output directly
961
			return $val;
962
		// Sybase timestamp
963
		//elseif ($this->IsDbSybase() && 'varbinary' == $type && 'timestamp' == $column)
964
		elseif ($this->IsDbSybase() && 'timestamp' == $type)
965
			return '0x' . $val;
966
		else {
967
			// Need quote, use db's quote method
968
			$val = stripslashes($val);
969
			return $this->qstr($val, false);
0 ignored issues
show
Documentation Bug introduced by
The method qstr does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
970
		}
971
	} // end of func GenSqlQuote
972
973
974
	/**
975
	 * If a table exists in db ?
976
	 *
977
	 * @param	string	$tbl
978
	 * @return	boolean
979
	 */
980 View Code Duplication
	public function TblExists ($tbl) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
981
		if ($this->IsDbSybase()) {
982
			$sql = "select count(1) as c from sysobjects where name = '$tbl' and type = 'U'";
983
			$rs = $this->Execute($sql);
0 ignored issues
show
Bug introduced by
The method Execute() does not exist on Adodb. Did you maybe mean ExecuteGenSql()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
984
			return (0 != $rs->fields['c']);
985
		}
986
		elseif ($this->IsDbMysql()) {
987
			$sql = "SHOW TABLES LIKE '$tbl'";
988
			$rs = $this->Execute($sql);
0 ignored issues
show
Bug introduced by
The method Execute() does not exist on Adodb. Did you maybe mean ExecuteGenSql()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
989
			return (0 != $rs->RowCount());
990
		}
991
		else {
992
			// :NOTICE: Un-tested method
993
			$sql = "select 1 from $tbl";
994
			$rs = $this->Execute($sql);
0 ignored issues
show
Unused Code introduced by
$rs is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
Bug introduced by
The method Execute() does not exist on Adodb. Did you maybe mean ExecuteGenSql()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
995
			return (0 == $this->ErrorNo());
0 ignored issues
show
Documentation Bug introduced by
The method ErrorNo does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
996
		}
997
	} // end of func TblExists
998
999
1000
	/**
1001
	 * Smart write data row(s) to table
1002
	 *
1003
	 * Will auto check row existence, and decide to use INSERT or UPDATE,
1004
	 * so PRIMARY KEY column must include in $data array.
1005
	 * Also, table must have primary key defined.
1006
	 * @param	string	$tbl	Table which rows to write to
1007
	 * @param	array	$data	Row(s) data, only one row(1-dim array, index is column name)
1008
	 * 							or some rows(2-dim array, index layer 1 MUST be number and
1009
	 * 							will not write to db).
1010
	 * @param	string	$mode	A auto detect/U update/I insert, ignore case.
1011
	 * 							If you assign some rows, it's better not to set this to 0,
1012
	 * 							because it will only detect by the FIRST row data.
1013
	 * @return	int		Number of inserted or updated rows, -1 means some error,
1014
	 * 					0 and upper are normal result.
1015
	 */
1016
	public function Write ($tbl, $data, $mode = 'A') {
1017
		// Find primary key column first
1018
		$pk = $this->GetMetaPrimaryKey($tbl);
1019
1020
		// Convert single row data to multi row mode
1021
		if (!isset($data[0]))
1022
			$data = array(0 => $data);
1023
		// Convert primary key to array if it's single string now
1024
		if (!is_array($pk))
1025
			$pk = array(0 => $pk);
1026
1027
		// Columns in $data
1028
		$ar_cols = array_keys($data[0]);
1029
		// Check if primary key is assigned in $data
1030
		$b_data_ok = true;
1031
		foreach ($pk as $key)
1032
			if (!in_array($key, $ar_cols))
1033
				$b_data_ok = false;
1034
		// If no primary key column in $data, return -1
1035
		if (false == $b_data_ok)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1036
			return -1;
1037
1038
		$mode = strtoupper($mode);
1039
		// Consider mode if user not assigned
1040 View Code Duplication
		if ('A' == $mode) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1041
			$s_where = ' WHERE ';
1042
			foreach ($pk as $key)
1043
				$s_where .= " $key = " . $this->QuoteValue($tbl, $key, $data[0][$key])
1044
					. ' AND ';
1045
			$s_where = substr($s_where, 0, strlen($s_where) - 5);
1046
			if (0 < $this->GetRowCount($tbl, $s_where))
1047
				$mode = 'U';
1048
			else
1049
				$mode = 'I';
1050
		}
1051
1052
		// Do batch update or insert, prepare stmt first
1053
		$sql = '';
0 ignored issues
show
Unused Code introduced by
$sql is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1054
		if ('U' == $mode) {
1055
			$ar_conf = array(
1056
				'UPDATE' => $tbl,
1057
				'LIMIT' => 1,
1058
				);
1059
			foreach ($pk as $key) {
1060
				// Primary key need remove from 'SET' clause
1061
				// Actual value will assign later, do quote then.
1062
				// :NOTICE: Remember to put pk data to end of row data when assign,
1063
				//	because where clause is after set clause.
1064
				$ar_conf['WHERE'][] = "$key = "
1065
					. $this->Param($key);
0 ignored issues
show
Documentation Bug introduced by
The method Param does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1066
				unset($ar_cols[array_search($key, $ar_cols)]);
1067
			}
1068
			// Convert array $ar_cols with to prepare param
1069
			$ar_set = array();
1070
			foreach ($ar_cols as $key)
1071
				$ar_set[$key] = $this->Param($key);
0 ignored issues
show
Documentation Bug introduced by
The method Param does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1072
			// Fin, assign 'SET' clause
1073
			$ar_conf['SET'] = $ar_set;
1074
		}
1075
		elseif ('I' == $mode) {
1076
			$ar_set = array();
1077
			foreach ($ar_cols as $key) {
1078
				$ar_set[$key] = $this->Param($key);
0 ignored issues
show
Documentation Bug introduced by
The method Param does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1079
			}
1080
			$ar_conf = array(
1081
				'INSERT' => $tbl,
1082
				'VALUES' => $ar_set,
1083
				);
1084
		}
1085
		$sql = $this->GenSqlPrepare($ar_conf);
0 ignored issues
show
Bug introduced by
The variable $ar_conf does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1086
1087
		/* Treat moved to  SqlGenerator
1088
		//$sql = $this->GenSql($ar_conf);
1089
		// Remove duplicate ' in sql add by SqlGenerator,
1090
		// Execute after Prepare will auto recoginize variant type and quote,
1091
		// but notice, it's VAR TYPE and NOT DB COLUMN TYPE.
1092
		// replaceQuote: The string used to escape quotes. Eg. double single-quotes for
1093
		// Microsoft SQL, and backslash-quote for MySQL. Used by qstr.
1094
		if ("''" == $this->replaceQuote)
1095
			$s_quote = "'";
1096
		else
1097
			$s_quote = $this->replaceQuote;
1098
		$sql = preg_replace(
1099
			"/ {$s_quote}([\?\:\w\-_]+){$s_quote}([, ])/i",
1100
			" $1$2", $sql);
1101
		*/
1102
1103
		if (!empty($sql)) {
1104
			// Do prepare
1105
			$stmt = $this->Prepare($sql);
0 ignored issues
show
Bug introduced by
The method Prepare() does not exist on Adodb. Did you maybe mean GenSqlPrepare()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1106
			// Execute
1107 View Code Duplication
			if ('U' == $mode) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1108
				foreach ($data as &$row) {
1109
					// Change pk's value position when update mode
1110
					foreach ($pk as $key) {
1111
						$v = $row[$key];
1112
						unset($row[$key]);
1113
						$row[$key] = $v;
1114
					}
1115
				}
1116
				unset($row);
1117
			}
1118
			// Now, finanly, actual write data
1119
			// Auto convert encoding ?
1120
			// Use of prepare we must convert $data manually, because $data is not sql.
1121
			$this->EncodingConvert($data);
1122
			try {
1123
				$this->Execute($stmt, $data);
0 ignored issues
show
Bug introduced by
The method Execute() does not exist on Adodb. Did you maybe mean ExecuteGenSql()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1124
			}
1125
			catch (Exception $e) {
1126
				// Show error message ?
1127
				$this->RollbackTrans();
0 ignored issues
show
Documentation Bug introduced by
The method RollbackTrans does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1128
				return -1;
1129
			}
1130
			// Any error ?
1131 View Code Duplication
			if (0 != $this->ErrorNo()) {
0 ignored issues
show
Documentation Bug introduced by
The method ErrorNo does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1132
				// Log to error log file
1133
				error_log('ErrorNo: ' . $this->ErrorNo()
0 ignored issues
show
Documentation Bug introduced by
The method ErrorNo does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1134
					. "\nErrorMsg: " . $this->ErrorMsg()
0 ignored issues
show
Documentation Bug introduced by
The method ErrorMsg does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1135
					);
1136
				$this->RollbackTrans();
0 ignored issues
show
Documentation Bug introduced by
The method RollbackTrans does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1137
				return -1;
1138
			}
1139
			else {
1140
				$this->CommitTrans();
0 ignored issues
show
Documentation Bug introduced by
The method CommitTrans does not exist on object<Adodb>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1141
				return count($data);
1142
			}
1143
		}
1144
		else
1145
			return -1;
1146
	} // end of func Write
1147
1148
1149
} // end of class Adodb
1150
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
1151