Test Failed
Push — master ( 347f78...843bd1 )
by Joe
05:03
created
src/Mysqli/Db.php 2 patches
Indentation   +495 added lines, -495 removed lines patch added patch discarded remove patch
@@ -19,505 +19,505 @@
 block discarded – undo
19 19
  */
20 20
 class Db extends Generic implements Db_Interface
21 21
 {
22
-    /**
23
-     * @var string
24
-     */
25
-    public $type = 'mysqli';
26
-
27
-    /**
28
-     * alias function of select_db, changes the database we are working with.
29
-     *
30
-     * @param string $database the name of the database to use
31
-     * @return void
32
-     */
33
-    public function useDb($database)
34
-    {
35
-        $this->selectDb($database);
36
-    }
37
-
38
-    /**
39
-     * changes the database we are working with.
40
-     *
41
-     * @param string $database the name of the database to use
42
-     * @return void
43
-     */
44
-    public function selectDb($database)
45
-    {
46
-        $this->connect();
47
-        mysqli_select_db($this->linkId, $database);
48
-    }
49
-
50
-    /* public: connection management */
51
-
52
-    /**
53
-     * Db::connect()
54
-     * @param string $database
55
-     * @param string $host
56
-     * @param string $user
57
-     * @param string $password
58
-     * @return int|\mysqli
59
-     */
60
-    public function connect($database = '', $host = '', $user = '', $password = '', $port = '')
61
-    {
62
-        /* Handle defaults */
63
-        if ($database == '') {
64
-            $database = $this->database;
65
-        }
66
-        if ($host == '') {
67
-            $host = $this->host;
68
-        }
69
-        if ($user == '') {
70
-            $user = $this->user;
71
-        }
72
-        if ($password == '') {
73
-            $password = $this->password;
74
-        }
75
-        if ($port == '') {
76
-            $port = $this->port;
77
-        }
78
-        /* establish connection, select database */
79
-        if (!is_object($this->linkId)) {
80
-            $this->connectionAttempt++;
81
-            if ($this->connectionAttempt >= $this->maxConnectErrors - 1) {
82
-                error_log("MySQLi Connection Attempt #{$this->connectionAttempt}/{$this->maxConnectErrors}");
83
-            }
84
-            if ($this->connectionAttempt >= $this->maxConnectErrors) {
22
+	/**
23
+	 * @var string
24
+	 */
25
+	public $type = 'mysqli';
26
+
27
+	/**
28
+	 * alias function of select_db, changes the database we are working with.
29
+	 *
30
+	 * @param string $database the name of the database to use
31
+	 * @return void
32
+	 */
33
+	public function useDb($database)
34
+	{
35
+		$this->selectDb($database);
36
+	}
37
+
38
+	/**
39
+	 * changes the database we are working with.
40
+	 *
41
+	 * @param string $database the name of the database to use
42
+	 * @return void
43
+	 */
44
+	public function selectDb($database)
45
+	{
46
+		$this->connect();
47
+		mysqli_select_db($this->linkId, $database);
48
+	}
49
+
50
+	/* public: connection management */
51
+
52
+	/**
53
+	 * Db::connect()
54
+	 * @param string $database
55
+	 * @param string $host
56
+	 * @param string $user
57
+	 * @param string $password
58
+	 * @return int|\mysqli
59
+	 */
60
+	public function connect($database = '', $host = '', $user = '', $password = '', $port = '')
61
+	{
62
+		/* Handle defaults */
63
+		if ($database == '') {
64
+			$database = $this->database;
65
+		}
66
+		if ($host == '') {
67
+			$host = $this->host;
68
+		}
69
+		if ($user == '') {
70
+			$user = $this->user;
71
+		}
72
+		if ($password == '') {
73
+			$password = $this->password;
74
+		}
75
+		if ($port == '') {
76
+			$port = $this->port;
77
+		}
78
+		/* establish connection, select database */
79
+		if (!is_object($this->linkId)) {
80
+			$this->connectionAttempt++;
81
+			if ($this->connectionAttempt >= $this->maxConnectErrors - 1) {
82
+				error_log("MySQLi Connection Attempt #{$this->connectionAttempt}/{$this->maxConnectErrors}");
83
+			}
84
+			if ($this->connectionAttempt >= $this->maxConnectErrors) {
85 85
 exit;
86
-                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
87
-                return 0;
88
-            }
89
-            //error_log("real_connect($host, $user, $password, $database, $port)");
90
-            $this->linkId = mysqli_init();
91
-            $this->linkId->options(MYSQLI_INIT_COMMAND, "SET NAMES {$this->characterSet} COLLATE {$this->collation}, COLLATION_CONNECTION = {$this->collation}, COLLATION_DATABASE = {$this->collation}");
92
-            if (!$this->linkId->real_connect($host, $user, $password, $database, $port != '' ? $port : NULL)) {
93
-                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
94
-                return 0;
95
-            }
96
-            $this->linkId->set_charset($this->characterSet);
97
-            if ($this->linkId->connect_errno) {
98
-                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
99
-                return 0;
100
-            }
101
-        }
102
-        return $this->linkId;
103
-    }
104
-
105
-    /**
106
-     * Db::disconnect()
107
-     * @return bool
108
-     */
109
-    public function disconnect()
110
-    {
111
-        $return = !is_int($this->linkId) && method_exists($this->linkId, 'close') ? $this->linkId->close() : false;
112
-        $this->linkId = 0;
113
-        return $return;
114
-    }
115
-
116
-    /**
117
-     * @param $string
118
-     * @return string
119
-     */
120
-    public function real_escape($string = '')
121
-    {
122
-        if ((!is_resource($this->linkId) || $this->linkId == 0) && !$this->connect()) {
123
-            return $this->escape($string);
124
-        }
125
-        return mysqli_real_escape_string($this->linkId, $string);
126
-    }
127
-
128
-    /**
129
-     * discard the query result
130
-     * @return void
131
-     */
132
-    public function free()
133
-    {
134
-        if (is_resource($this->queryId)) {
135
-            @mysqli_free_result($this->queryId);
136
-        }
137
-        $this->queryId = 0;
138
-    }
139
-
140
-    /**
141
-     * Db::queryReturn()
142
-     *
143
-     * Sends an SQL query to the server like the normal query() command but iterates through
144
-     * any rows and returns the row or rows immediately or FALSE on error
145
-     *
146
-     * @param mixed $query SQL Query to be used
147
-     * @param string $line optionally pass __LINE__ calling the query for logging
148
-     * @param string $file optionally pass __FILE__ calling the query for logging
149
-     * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
150
-     */
151
-    public function queryReturn($query, $line = '', $file = '')
152
-    {
153
-        $this->query($query, $line, $file);
154
-        if ($this->num_rows() == 0) {
155
-            return false;
156
-        } elseif ($this->num_rows() == 1) {
157
-            $this->next_record(MYSQLI_ASSOC);
158
-            return $this->Record;
159
-        } else {
160
-            $out = [];
161
-            while ($this->next_record(MYSQLI_ASSOC)) {
162
-                $out[] = $this->Record;
163
-            }
164
-            return $out;
165
-        }
166
-    }
167
-
168
-    /**
169
-     * db:qr()
170
-     *
171
-     *  alias of queryReturn()
172
-     *
173
-     * @param mixed $query SQL Query to be used
174
-     * @param string $line optionally pass __LINE__ calling the query for logging
175
-     * @param string $file optionally pass __FILE__ calling the query for logging
176
-     * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
177
-     */
178
-    public function qr($query, $line = '', $file = '')
179
-    {
180
-        return $this->queryReturn($query, $line, $file);
181
-    }
182
-
183
-    /**
184
-     * creates a prepaired statement from query
185
-     *
186
-     * @param string $query sql query like INSERT INTO table (col) VALUES (?)  or  SELECT * from table WHERE col1 = ? and col2 = ?  or  UPDATE table SET col1 = ?, col2 = ? WHERE col3 = ?
187
-     * @return int|\MyDb\Mysqli\mysqli_stmt
188
-     * @param string $line
189
-     * @param string $file
190
-     */
191
-    public function prepare($query, $line = '', $file = '')
192
-    {
193
-        if (!$this->connect()) {
194
-            return 0;
195
-        }
196
-        $haltPrev = $this->haltOnError;
197
-        $this->haltOnError = 'no';
198
-        $start = microtime(true);
199
-        $prepare = mysqli_prepare($this->linkId, $query);
200
-        if (!isset($GLOBALS['disable_db_queries'])) {
201
-            $this->addLog($query, microtime(true) - $start, $line, $file);
202
-        }
203
-        return $prepare;
204
-    }
205
-
206
-    /**
207
-     * Db::query()
208
-     *
209
-     *  Sends an SQL query to the database
210
-     *
211
-     * @param mixed $queryString
212
-     * @param int $line
213
-     * @param string $file
214
-     * @param bool $log
215
-     * @return mixed 0 if no query or query id handler, safe to ignore this return
216
-     */
217
-    public function query($queryString, $line = '', $file = '', $log = false)
218
-    {
219
-        /* No empty queries, please, since PHP4 chokes on them. */
220
-        /* The empty query string is passed on from the constructor,
86
+				$this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
87
+				return 0;
88
+			}
89
+			//error_log("real_connect($host, $user, $password, $database, $port)");
90
+			$this->linkId = mysqli_init();
91
+			$this->linkId->options(MYSQLI_INIT_COMMAND, "SET NAMES {$this->characterSet} COLLATE {$this->collation}, COLLATION_CONNECTION = {$this->collation}, COLLATION_DATABASE = {$this->collation}");
92
+			if (!$this->linkId->real_connect($host, $user, $password, $database, $port != '' ? $port : NULL)) {
93
+				$this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
94
+				return 0;
95
+			}
96
+			$this->linkId->set_charset($this->characterSet);
97
+			if ($this->linkId->connect_errno) {
98
+				$this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
99
+				return 0;
100
+			}
101
+		}
102
+		return $this->linkId;
103
+	}
104
+
105
+	/**
106
+	 * Db::disconnect()
107
+	 * @return bool
108
+	 */
109
+	public function disconnect()
110
+	{
111
+		$return = !is_int($this->linkId) && method_exists($this->linkId, 'close') ? $this->linkId->close() : false;
112
+		$this->linkId = 0;
113
+		return $return;
114
+	}
115
+
116
+	/**
117
+	 * @param $string
118
+	 * @return string
119
+	 */
120
+	public function real_escape($string = '')
121
+	{
122
+		if ((!is_resource($this->linkId) || $this->linkId == 0) && !$this->connect()) {
123
+			return $this->escape($string);
124
+		}
125
+		return mysqli_real_escape_string($this->linkId, $string);
126
+	}
127
+
128
+	/**
129
+	 * discard the query result
130
+	 * @return void
131
+	 */
132
+	public function free()
133
+	{
134
+		if (is_resource($this->queryId)) {
135
+			@mysqli_free_result($this->queryId);
136
+		}
137
+		$this->queryId = 0;
138
+	}
139
+
140
+	/**
141
+	 * Db::queryReturn()
142
+	 *
143
+	 * Sends an SQL query to the server like the normal query() command but iterates through
144
+	 * any rows and returns the row or rows immediately or FALSE on error
145
+	 *
146
+	 * @param mixed $query SQL Query to be used
147
+	 * @param string $line optionally pass __LINE__ calling the query for logging
148
+	 * @param string $file optionally pass __FILE__ calling the query for logging
149
+	 * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
150
+	 */
151
+	public function queryReturn($query, $line = '', $file = '')
152
+	{
153
+		$this->query($query, $line, $file);
154
+		if ($this->num_rows() == 0) {
155
+			return false;
156
+		} elseif ($this->num_rows() == 1) {
157
+			$this->next_record(MYSQLI_ASSOC);
158
+			return $this->Record;
159
+		} else {
160
+			$out = [];
161
+			while ($this->next_record(MYSQLI_ASSOC)) {
162
+				$out[] = $this->Record;
163
+			}
164
+			return $out;
165
+		}
166
+	}
167
+
168
+	/**
169
+	 * db:qr()
170
+	 *
171
+	 *  alias of queryReturn()
172
+	 *
173
+	 * @param mixed $query SQL Query to be used
174
+	 * @param string $line optionally pass __LINE__ calling the query for logging
175
+	 * @param string $file optionally pass __FILE__ calling the query for logging
176
+	 * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
177
+	 */
178
+	public function qr($query, $line = '', $file = '')
179
+	{
180
+		return $this->queryReturn($query, $line, $file);
181
+	}
182
+
183
+	/**
184
+	 * creates a prepaired statement from query
185
+	 *
186
+	 * @param string $query sql query like INSERT INTO table (col) VALUES (?)  or  SELECT * from table WHERE col1 = ? and col2 = ?  or  UPDATE table SET col1 = ?, col2 = ? WHERE col3 = ?
187
+	 * @return int|\MyDb\Mysqli\mysqli_stmt
188
+	 * @param string $line
189
+	 * @param string $file
190
+	 */
191
+	public function prepare($query, $line = '', $file = '')
192
+	{
193
+		if (!$this->connect()) {
194
+			return 0;
195
+		}
196
+		$haltPrev = $this->haltOnError;
197
+		$this->haltOnError = 'no';
198
+		$start = microtime(true);
199
+		$prepare = mysqli_prepare($this->linkId, $query);
200
+		if (!isset($GLOBALS['disable_db_queries'])) {
201
+			$this->addLog($query, microtime(true) - $start, $line, $file);
202
+		}
203
+		return $prepare;
204
+	}
205
+
206
+	/**
207
+	 * Db::query()
208
+	 *
209
+	 *  Sends an SQL query to the database
210
+	 *
211
+	 * @param mixed $queryString
212
+	 * @param int $line
213
+	 * @param string $file
214
+	 * @param bool $log
215
+	 * @return mixed 0 if no query or query id handler, safe to ignore this return
216
+	 */
217
+	public function query($queryString, $line = '', $file = '', $log = false)
218
+	{
219
+		/* No empty queries, please, since PHP4 chokes on them. */
220
+		/* The empty query string is passed on from the constructor,
221 221
         * when calling the class without a query, e.g. in situations
222 222
         * like these: '$db = new db_Subclass;'
223 223
         */
224
-        if ($queryString == '') {
225
-            return 0;
226
-        }
227
-        if (!$this->connect()) {
228
-            return 0;
229
-            /* we already complained in connect() about that. */
230
-        }
231
-        $haltPrev = $this->haltOnError;
232
-        $this->haltOnError = 'no';
233
-        // New query, discard previous result.
234
-        if (is_resource($this->queryId)) {
235
-            $this->free();
236
-        }
237
-        if ($this->Debug) {
238
-            printf("Debug: query = %s<br>\n", $queryString);
239
-        }
240
-        if ($log === true || (isset($GLOBALS['log_queries']) && $GLOBALS['log_queries'] !== false)) {
241
-            $this->log($queryString, $line, $file);
242
-        }
243
-        $tries = 2;
244
-        $try = 0;
245
-        $this->queryId = false;
246
-        while ((null === $this->queryId || $this->queryId === false) && $try <= $tries) {
247
-            $try++;
248
-            if ($try > 1) {
249
-                @mysqli_close($this->linkId);
250
-                $this->linkId = 0;
251
-            }
252
-            $start = microtime(true);
253
-            $onlyRollback = true;
254
-            $fails = -1;
255
-            while ($fails < 30 && (null === $this->queryId || $this->queryId === false)) {
256
-                $this->connect();
257
-                $fails++;
258
-                try {
259
-                    $this->queryId = @mysqli_query($this->linkId, $queryString, MYSQLI_STORE_RESULT);
260
-                    if (in_array((int)@mysqli_errno($this->linkId), [1213, 2006, 3101, 1180])) {
261
-                        //error_log("got ".@mysqli_errno($this->linkId)." sql error fails {$fails} on query {$queryString} from {$line}:{$file}");
262
-                        usleep(250000); // 0.25 second
263
-                    } else {
264
-                        $onlyRollback = false;
265
-                        if (in_array((int)@mysqli_errno($this->linkId), [1064])) {
266
-                            $tries = 0;
267
-                        }
268
-                        break;
269
-                    }
270
-                } catch (\mysqli_sql_exception $e) {
271
-                    if (in_array((int)$e->getCode(), [1213, 2006, 3101, 1180])) {
272
-                        //error_log("got ".$e->getCode()." sql error fails {$fails}");
273
-                        usleep(250000); // 0.25 second
274
-                    } else {
275
-                        error_log('Got mysqli_sql_exception code '.$e->getCode().' error '.$e->getMessage().' on query '.$queryString.' from '.$line.':'.$file);
276
-                        $onlyRollback = false;
277
-                        if (in_array((int)@mysqli_errno($this->linkId), [1064])) {
278
-                            $tries = 0;
279
-                        }
280
-                        break;
281
-                    }
282
-                }
283
-            }
284
-            if (!isset($GLOBALS['disable_db_queries'])) {
285
-                $this->addLog($queryString, microtime(true) - $start, $line, $file);
286
-            }
287
-            $this->Row = 0;
288
-            $this->Errno = @mysqli_errno($this->linkId);
289
-            $this->Error = @mysqli_error($this->linkId);
290
-            if ($try == 1 && (null === $this->queryId || $this->queryId === false)) {
291
-                //$this->emailError($queryString, 'Error #'.$this->Errno.': '.$this->Error, $line, $file);
292
-            }
293
-        }
294
-        $this->haltOnError = $haltPrev;
295
-        if ($onlyRollback === true && false === $this->queryId) {
296
-            error_log('Got MySQLi 3101 Rollback Error '.$fails.' Times, Giving Up on '.$queryString.' from '.$line.':'.$file.' on '.__LINE__.':'.__FILE__);
297
-        }
298
-        if (null === $this->queryId || $this->queryId === false) {
299
-            $this->emailError($queryString, 'Error #'.$this->Errno.': '.$this->Error, $line, $file);
300
-            $this->halt('', $line, $file);
301
-        }
302
-
303
-        // Will return nada if it fails. That's fine.
304
-        return $this->queryId;
305
-    }
306
-
307
-    /**
308
-     * @return array|null|object
309
-     */
310
-    public function fetchObject()
311
-    {
312
-        $this->Record = @mysqli_fetch_object($this->queryId);
313
-        return $this->Record;
314
-    }
315
-
316
-    /* public: walk result set */
317
-
318
-    /**
319
-     * Db::next_record()
320
-     *
321
-     * @param mixed $resultType
322
-     * @return bool
323
-     */
324
-    public function next_record($resultType = MYSQLI_BOTH)
325
-    {
326
-        if ($this->queryId === false) {
327
-            $this->haltmsg('next_record called with no query pending.');
328
-            return 0;
329
-        }
330
-
331
-        $this->Record = @mysqli_fetch_array($this->queryId, $resultType);
332
-        ++$this->Row;
333
-        $this->Errno = mysqli_errno($this->linkId);
334
-        $this->Error = mysqli_error($this->linkId);
335
-
336
-        $stat = is_array($this->Record);
337
-        if (!$stat && $this->autoFree && is_resource($this->queryId)) {
338
-            $this->free();
339
-        }
340
-        return $stat;
341
-    }
342
-
343
-    /**
344
-     * switch to position in result set
345
-     *
346
-     * @param integer $pos the row numbe starting at 0 to switch to
347
-     * @return bool whetherit was successfu or not.
348
-     */
349
-    public function seek($pos = 0)
350
-    {
351
-        $status = @mysqli_data_seek($this->queryId, $pos);
352
-        if ($status) {
353
-            $this->Row = $pos;
354
-        } else {
355
-            $this->haltmsg("seek({$pos}) failed: result has ".$this->num_rows().' rows', __LINE__, __FILE__);
356
-            /* half assed attempt to save the day, but do not consider this documented or even desirable behaviour. */
357
-            $rows = $this->num_rows();
358
-            @mysqli_data_seek($this->queryId, $rows);
359
-            $this->Row = $rows;
360
-            return false;
361
-        }
362
-        return true;
363
-    }
364
-
365
-    /**
366
-     * Initiates a transaction
367
-     *
368
-     * @return bool
369
-     */
370
-    public function transactionBegin()
371
-    {
372
-        if (version_compare(PHP_VERSION, '5.5.0') < 0) {
373
-            return true;
374
-        }
375
-        if (!$this->connect()) {
376
-            return 0;
377
-        }
378
-        return mysqli_begin_transaction($this->linkId);
379
-    }
380
-
381
-    /**
382
-     * Commits a transaction
383
-     *
384
-     * @return bool
385
-     */
386
-    public function transactionCommit()
387
-    {
388
-        if (version_compare(PHP_VERSION, '5.5.0') < 0 || $this->linkId === 0) {
389
-            return true;
390
-        }
391
-        return mysqli_commit($this->linkId);
392
-    }
393
-
394
-    /**
395
-     * Rolls back a transaction
396
-     *
397
-     * @return bool
398
-     */
399
-    public function transactionAbort()
400
-    {
401
-        if (version_compare(PHP_VERSION, '5.5.0') < 0 || $this->linkId === 0) {
402
-            return true;
403
-        }
404
-        return mysqli_rollback($this->linkId);
405
-    }
406
-
407
-    /**
408
-     * This will get the last insert ID created on the current connection.  Should only be called after an insert query is
409
-     * run on a table that has an auto incrementing field.  $table and $field are required, but unused here since it's
410
-     * unnecessary for mysql.  For compatibility with pgsql, the params must be supplied.
411
-     *
412
-     * @param string $table
413
-     * @param string $field
414
-     * @return int|string
415
-     */
416
-    public function getLastInsertId($table, $field)
417
-    {
418
-        if (!isset($table) || $table == '' || !isset($field) || $field == '') {
419
-            return -1;
420
-        }
421
-
422
-        return @mysqli_insert_id($this->linkId);
423
-    }
424
-
425
-    /* public: table locking */
426
-
427
-    /**
428
-     * Db::lock()
429
-     * @param mixed  $table
430
-     * @param string $mode
431
-     * @return bool|int|\mysqli_result
432
-     */
433
-    public function lock($table, $mode = 'write')
434
-    {
435
-        $this->connect();
436
-        $query = 'lock tables ';
437
-        if (is_array($table)) {
438
-            foreach ($table as $key => $value) {
439
-                if ($key == 'read' && $key != 0) {
440
-                    $query .= "$value read, ";
441
-                } else {
442
-                    $query .= "$value $mode, ";
443
-                }
444
-            }
445
-            $query = mb_substr($query, 0, -2);
446
-        } else {
447
-            $query .= "$table $mode";
448
-        }
449
-        $res = @mysqli_query($this->linkId, $query);
450
-        if (!$res) {
451
-            $this->halt("lock($table, $mode) failed.");
452
-            return 0;
453
-        }
454
-        return $res;
455
-    }
456
-
457
-    /**
458
-     * Db::unlock()
459
-     * @param bool $haltOnError optional, defaults to TRUE, whether or not to halt on error
460
-     * @return bool|int|\mysqli_result
461
-     */
462
-    public function unlock($haltOnError = true)
463
-    {
464
-        $this->connect();
465
-
466
-        $res = @mysqli_query($this->linkId, 'unlock tables');
467
-        if ($haltOnError === true && !$res) {
468
-            $this->halt('unlock() failed.');
469
-            return 0;
470
-        }
471
-        return $res;
472
-    }
473
-
474
-    /* public: evaluate the result (size, width) */
475
-
476
-    /**
477
-     * Db::affectedRows()
478
-     * @return int
479
-     */
480
-    public function affectedRows()
481
-    {
482
-        return @mysqli_affected_rows($this->linkId);
483
-    }
484
-
485
-    /**
486
-     * Db::num_rows()
487
-     * @return int
488
-     */
489
-    public function num_rows()
490
-    {
491
-        return @mysqli_num_rows($this->queryId);
492
-    }
493
-
494
-    /**
495
-     * Db::num_fields()
496
-     * @return int
497
-     */
498
-    public function num_fields()
499
-    {
500
-        return @mysqli_num_fields($this->queryId);
501
-    }
502
-
503
-    /**
504
-     * gets an array of the table names in teh current datase
505
-     *
506
-     * @return array
507
-     */
508
-    public function tableNames()
509
-    {
510
-        $return = [];
511
-        $this->query('SHOW TABLES');
512
-        $i = 0;
513
-        while ($info = $this->queryId->fetch_row()) {
514
-            $return[$i]['table_name'] = $info[0];
515
-            $return[$i]['tablespace_name'] = $this->database;
516
-            $return[$i]['database'] = $this->database;
517
-            ++$i;
518
-        }
519
-        return $return;
520
-    }
224
+		if ($queryString == '') {
225
+			return 0;
226
+		}
227
+		if (!$this->connect()) {
228
+			return 0;
229
+			/* we already complained in connect() about that. */
230
+		}
231
+		$haltPrev = $this->haltOnError;
232
+		$this->haltOnError = 'no';
233
+		// New query, discard previous result.
234
+		if (is_resource($this->queryId)) {
235
+			$this->free();
236
+		}
237
+		if ($this->Debug) {
238
+			printf("Debug: query = %s<br>\n", $queryString);
239
+		}
240
+		if ($log === true || (isset($GLOBALS['log_queries']) && $GLOBALS['log_queries'] !== false)) {
241
+			$this->log($queryString, $line, $file);
242
+		}
243
+		$tries = 2;
244
+		$try = 0;
245
+		$this->queryId = false;
246
+		while ((null === $this->queryId || $this->queryId === false) && $try <= $tries) {
247
+			$try++;
248
+			if ($try > 1) {
249
+				@mysqli_close($this->linkId);
250
+				$this->linkId = 0;
251
+			}
252
+			$start = microtime(true);
253
+			$onlyRollback = true;
254
+			$fails = -1;
255
+			while ($fails < 30 && (null === $this->queryId || $this->queryId === false)) {
256
+				$this->connect();
257
+				$fails++;
258
+				try {
259
+					$this->queryId = @mysqli_query($this->linkId, $queryString, MYSQLI_STORE_RESULT);
260
+					if (in_array((int)@mysqli_errno($this->linkId), [1213, 2006, 3101, 1180])) {
261
+						//error_log("got ".@mysqli_errno($this->linkId)." sql error fails {$fails} on query {$queryString} from {$line}:{$file}");
262
+						usleep(250000); // 0.25 second
263
+					} else {
264
+						$onlyRollback = false;
265
+						if (in_array((int)@mysqli_errno($this->linkId), [1064])) {
266
+							$tries = 0;
267
+						}
268
+						break;
269
+					}
270
+				} catch (\mysqli_sql_exception $e) {
271
+					if (in_array((int)$e->getCode(), [1213, 2006, 3101, 1180])) {
272
+						//error_log("got ".$e->getCode()." sql error fails {$fails}");
273
+						usleep(250000); // 0.25 second
274
+					} else {
275
+						error_log('Got mysqli_sql_exception code '.$e->getCode().' error '.$e->getMessage().' on query '.$queryString.' from '.$line.':'.$file);
276
+						$onlyRollback = false;
277
+						if (in_array((int)@mysqli_errno($this->linkId), [1064])) {
278
+							$tries = 0;
279
+						}
280
+						break;
281
+					}
282
+				}
283
+			}
284
+			if (!isset($GLOBALS['disable_db_queries'])) {
285
+				$this->addLog($queryString, microtime(true) - $start, $line, $file);
286
+			}
287
+			$this->Row = 0;
288
+			$this->Errno = @mysqli_errno($this->linkId);
289
+			$this->Error = @mysqli_error($this->linkId);
290
+			if ($try == 1 && (null === $this->queryId || $this->queryId === false)) {
291
+				//$this->emailError($queryString, 'Error #'.$this->Errno.': '.$this->Error, $line, $file);
292
+			}
293
+		}
294
+		$this->haltOnError = $haltPrev;
295
+		if ($onlyRollback === true && false === $this->queryId) {
296
+			error_log('Got MySQLi 3101 Rollback Error '.$fails.' Times, Giving Up on '.$queryString.' from '.$line.':'.$file.' on '.__LINE__.':'.__FILE__);
297
+		}
298
+		if (null === $this->queryId || $this->queryId === false) {
299
+			$this->emailError($queryString, 'Error #'.$this->Errno.': '.$this->Error, $line, $file);
300
+			$this->halt('', $line, $file);
301
+		}
302
+
303
+		// Will return nada if it fails. That's fine.
304
+		return $this->queryId;
305
+	}
306
+
307
+	/**
308
+	 * @return array|null|object
309
+	 */
310
+	public function fetchObject()
311
+	{
312
+		$this->Record = @mysqli_fetch_object($this->queryId);
313
+		return $this->Record;
314
+	}
315
+
316
+	/* public: walk result set */
317
+
318
+	/**
319
+	 * Db::next_record()
320
+	 *
321
+	 * @param mixed $resultType
322
+	 * @return bool
323
+	 */
324
+	public function next_record($resultType = MYSQLI_BOTH)
325
+	{
326
+		if ($this->queryId === false) {
327
+			$this->haltmsg('next_record called with no query pending.');
328
+			return 0;
329
+		}
330
+
331
+		$this->Record = @mysqli_fetch_array($this->queryId, $resultType);
332
+		++$this->Row;
333
+		$this->Errno = mysqli_errno($this->linkId);
334
+		$this->Error = mysqli_error($this->linkId);
335
+
336
+		$stat = is_array($this->Record);
337
+		if (!$stat && $this->autoFree && is_resource($this->queryId)) {
338
+			$this->free();
339
+		}
340
+		return $stat;
341
+	}
342
+
343
+	/**
344
+	 * switch to position in result set
345
+	 *
346
+	 * @param integer $pos the row numbe starting at 0 to switch to
347
+	 * @return bool whetherit was successfu or not.
348
+	 */
349
+	public function seek($pos = 0)
350
+	{
351
+		$status = @mysqli_data_seek($this->queryId, $pos);
352
+		if ($status) {
353
+			$this->Row = $pos;
354
+		} else {
355
+			$this->haltmsg("seek({$pos}) failed: result has ".$this->num_rows().' rows', __LINE__, __FILE__);
356
+			/* half assed attempt to save the day, but do not consider this documented or even desirable behaviour. */
357
+			$rows = $this->num_rows();
358
+			@mysqli_data_seek($this->queryId, $rows);
359
+			$this->Row = $rows;
360
+			return false;
361
+		}
362
+		return true;
363
+	}
364
+
365
+	/**
366
+	 * Initiates a transaction
367
+	 *
368
+	 * @return bool
369
+	 */
370
+	public function transactionBegin()
371
+	{
372
+		if (version_compare(PHP_VERSION, '5.5.0') < 0) {
373
+			return true;
374
+		}
375
+		if (!$this->connect()) {
376
+			return 0;
377
+		}
378
+		return mysqli_begin_transaction($this->linkId);
379
+	}
380
+
381
+	/**
382
+	 * Commits a transaction
383
+	 *
384
+	 * @return bool
385
+	 */
386
+	public function transactionCommit()
387
+	{
388
+		if (version_compare(PHP_VERSION, '5.5.0') < 0 || $this->linkId === 0) {
389
+			return true;
390
+		}
391
+		return mysqli_commit($this->linkId);
392
+	}
393
+
394
+	/**
395
+	 * Rolls back a transaction
396
+	 *
397
+	 * @return bool
398
+	 */
399
+	public function transactionAbort()
400
+	{
401
+		if (version_compare(PHP_VERSION, '5.5.0') < 0 || $this->linkId === 0) {
402
+			return true;
403
+		}
404
+		return mysqli_rollback($this->linkId);
405
+	}
406
+
407
+	/**
408
+	 * This will get the last insert ID created on the current connection.  Should only be called after an insert query is
409
+	 * run on a table that has an auto incrementing field.  $table and $field are required, but unused here since it's
410
+	 * unnecessary for mysql.  For compatibility with pgsql, the params must be supplied.
411
+	 *
412
+	 * @param string $table
413
+	 * @param string $field
414
+	 * @return int|string
415
+	 */
416
+	public function getLastInsertId($table, $field)
417
+	{
418
+		if (!isset($table) || $table == '' || !isset($field) || $field == '') {
419
+			return -1;
420
+		}
421
+
422
+		return @mysqli_insert_id($this->linkId);
423
+	}
424
+
425
+	/* public: table locking */
426
+
427
+	/**
428
+	 * Db::lock()
429
+	 * @param mixed  $table
430
+	 * @param string $mode
431
+	 * @return bool|int|\mysqli_result
432
+	 */
433
+	public function lock($table, $mode = 'write')
434
+	{
435
+		$this->connect();
436
+		$query = 'lock tables ';
437
+		if (is_array($table)) {
438
+			foreach ($table as $key => $value) {
439
+				if ($key == 'read' && $key != 0) {
440
+					$query .= "$value read, ";
441
+				} else {
442
+					$query .= "$value $mode, ";
443
+				}
444
+			}
445
+			$query = mb_substr($query, 0, -2);
446
+		} else {
447
+			$query .= "$table $mode";
448
+		}
449
+		$res = @mysqli_query($this->linkId, $query);
450
+		if (!$res) {
451
+			$this->halt("lock($table, $mode) failed.");
452
+			return 0;
453
+		}
454
+		return $res;
455
+	}
456
+
457
+	/**
458
+	 * Db::unlock()
459
+	 * @param bool $haltOnError optional, defaults to TRUE, whether or not to halt on error
460
+	 * @return bool|int|\mysqli_result
461
+	 */
462
+	public function unlock($haltOnError = true)
463
+	{
464
+		$this->connect();
465
+
466
+		$res = @mysqli_query($this->linkId, 'unlock tables');
467
+		if ($haltOnError === true && !$res) {
468
+			$this->halt('unlock() failed.');
469
+			return 0;
470
+		}
471
+		return $res;
472
+	}
473
+
474
+	/* public: evaluate the result (size, width) */
475
+
476
+	/**
477
+	 * Db::affectedRows()
478
+	 * @return int
479
+	 */
480
+	public function affectedRows()
481
+	{
482
+		return @mysqli_affected_rows($this->linkId);
483
+	}
484
+
485
+	/**
486
+	 * Db::num_rows()
487
+	 * @return int
488
+	 */
489
+	public function num_rows()
490
+	{
491
+		return @mysqli_num_rows($this->queryId);
492
+	}
493
+
494
+	/**
495
+	 * Db::num_fields()
496
+	 * @return int
497
+	 */
498
+	public function num_fields()
499
+	{
500
+		return @mysqli_num_fields($this->queryId);
501
+	}
502
+
503
+	/**
504
+	 * gets an array of the table names in teh current datase
505
+	 *
506
+	 * @return array
507
+	 */
508
+	public function tableNames()
509
+	{
510
+		$return = [];
511
+		$this->query('SHOW TABLES');
512
+		$i = 0;
513
+		while ($info = $this->queryId->fetch_row()) {
514
+			$return[$i]['table_name'] = $info[0];
515
+			$return[$i]['tablespace_name'] = $this->database;
516
+			$return[$i]['database'] = $this->database;
517
+			++$i;
518
+		}
519
+		return $return;
520
+	}
521 521
 }
522 522
 
523 523
 /**
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -83,19 +83,19 @@  discard block
 block discarded – undo
83 83
             }
84 84
             if ($this->connectionAttempt >= $this->maxConnectErrors) {
85 85
 exit;
86
-                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
86
+                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset($this->linkId->connect_error) ? $this->linkId->connect_error : ''));
87 87
                 return 0;
88 88
             }
89 89
             //error_log("real_connect($host, $user, $password, $database, $port)");
90 90
             $this->linkId = mysqli_init();
91 91
             $this->linkId->options(MYSQLI_INIT_COMMAND, "SET NAMES {$this->characterSet} COLLATE {$this->collation}, COLLATION_CONNECTION = {$this->collation}, COLLATION_DATABASE = {$this->collation}");
92 92
             if (!$this->linkId->real_connect($host, $user, $password, $database, $port != '' ? $port : NULL)) {
93
-                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
93
+                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset($this->linkId->connect_error) ? $this->linkId->connect_error : ''));
94 94
                 return 0;
95 95
             }
96 96
             $this->linkId->set_charset($this->characterSet);
97 97
             if ($this->linkId->connect_errno) {
98
-                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
98
+                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset($this->linkId->connect_error) ? $this->linkId->connect_error : ''));
99 99
                 return 0;
100 100
             }
101 101
         }
@@ -257,24 +257,24 @@  discard block
 block discarded – undo
257 257
                 $fails++;
258 258
                 try {
259 259
                     $this->queryId = @mysqli_query($this->linkId, $queryString, MYSQLI_STORE_RESULT);
260
-                    if (in_array((int)@mysqli_errno($this->linkId), [1213, 2006, 3101, 1180])) {
260
+                    if (in_array((int) @mysqli_errno($this->linkId), [1213, 2006, 3101, 1180])) {
261 261
                         //error_log("got ".@mysqli_errno($this->linkId)." sql error fails {$fails} on query {$queryString} from {$line}:{$file}");
262 262
                         usleep(250000); // 0.25 second
263 263
                     } else {
264 264
                         $onlyRollback = false;
265
-                        if (in_array((int)@mysqli_errno($this->linkId), [1064])) {
265
+                        if (in_array((int) @mysqli_errno($this->linkId), [1064])) {
266 266
                             $tries = 0;
267 267
                         }
268 268
                         break;
269 269
                     }
270 270
                 } catch (\mysqli_sql_exception $e) {
271
-                    if (in_array((int)$e->getCode(), [1213, 2006, 3101, 1180])) {
271
+                    if (in_array((int) $e->getCode(), [1213, 2006, 3101, 1180])) {
272 272
                         //error_log("got ".$e->getCode()." sql error fails {$fails}");
273 273
                         usleep(250000); // 0.25 second
274 274
                     } else {
275 275
                         error_log('Got mysqli_sql_exception code '.$e->getCode().' error '.$e->getMessage().' on query '.$queryString.' from '.$line.':'.$file);
276 276
                         $onlyRollback = false;
277
-                        if (in_array((int)@mysqli_errno($this->linkId), [1064])) {
277
+                        if (in_array((int) @mysqli_errno($this->linkId), [1064])) {
278 278
                             $tries = 0;
279 279
                         }
280 280
                         break;
Please login to merge, or discard this patch.