Changeset 235

User picture

Author: Mighty Gorgon

(2010/08/20 22:58) Over 1 year ago

Fixed some bugs in update procedure

Affected files

Updated ip/trunk/install/common.php Download diff

234235
62
	include(IP_ROOT_PATH . 'config.' . PHP_EXT);
62
	include(IP_ROOT_PATH . 'config.' . PHP_EXT);
63
	include('includes/constants.' . PHP_EXT);
63
	include('includes/constants.' . PHP_EXT);
64
	include('includes/functions.' . PHP_EXT);
64
	include('includes/functions.' . PHP_EXT);
65
	//include('includes/db.' . PHP_EXT);
65
	include('includes/db.' . PHP_EXT);
66
	//include('includes/utf/utf_tools.' . PHP_EXT);
67
	/*
66
	include(IP_ROOT_PATH . 'includes/db.' . PHP_EXT);
68
	include(IP_ROOT_PATH . 'includes/db.' . PHP_EXT);
69
	*/
67
	include(IP_ROOT_PATH . 'includes/utf/utf_tools.' . PHP_EXT);
70
	include(IP_ROOT_PATH . 'includes/utf/utf_tools.' . PHP_EXT);
68
}
71
}
69
72

Updated ip/trunk/install/includes/db.php Download diff

234235
26
		include('includes/mysql.' . PHP_EXT);
26
		include('includes/mysql.' . PHP_EXT);
27
		break;
27
		break;
28
	case 'mysql4':
28
	case 'mysql4':
29
		include('includes/mysql4.' . PHP_EXT);
29
		include('includes/mysql.' . PHP_EXT);
30
		break;
30
		break;
31
}
31
}
32
32

Updated ip/trunk/install/includes/mysql.php Download diff

234235
15
*
15
*
16
*/
16
*/
17
17
18
if(!defined('SQL_LAYER'))
18
if (!defined('IN_ICYPHOENIX'))
19
{
19
{
20
	exit;
21
}
20
22
21
define('SQL_LAYER', 'mysql');
22
23
class sql_db
23
class sql_db
24
{
24
{
25
26
	var $db_connect_id;
25
	var $db_connect_id;
26
	var $query_string = '';
27
	var $query_result;
27
	var $query_result;
28
	var $row = array();
28
	var $row = array();
29
	var $rowset = array();
29
	var $rowset = array();
30
	var $num_queries = 0;
30
	var $num_queries = array();
31
	var $open_queries = array();
32
	var $transaction = false;
33
	var $transactions = 0;
34
	var $persistency = false;
35
	var $multi_insert = false;
31
36
32
	//
37
	var $cache_folder = '';
38
39
	var $curtime = 0;
40
	var $sql_time = 0;
41
	var $sql_init_time = 0;
42
	var $sql_start_time = 0;
43
	var $sql_end_time = 0;
44
45
	var $query_hold = '';
46
	var $html_hold = '';
47
	var $sql_report = '';
48
49
	var $return_on_error = false;
50
	var $sql_error_triggered = false; // Set to true if error triggered
51
	var $sql_error_sql = ''; // Holding the last sql query on sql error
52
	var $sql_error_returned = array(); // Holding the error information - only populated if sql_error_triggered is set
53
54
	/**
55
	* Exact version of the DBAL, directly queried
56
	*/
57
	var $sql_server_version = false;
58
59
	/**
60
	* Wildcards for matching any (%) or exactly one (_) character within LIKE expressions
61
	*/
62
	var $any_char;
63
	var $one_char;
64
33
	// Constructor
65
	// Constructor
34
	//
35
	function sql_db($sqlserver, $sqluser, $sqlpassword, $database, $persistency = true)
66
	function sql_db($sqlserver, $sqluser, $sqlpassword, $database, $persistency = true)
36
	{
67
	{
68
		$this->sql_start_time = $this->sql_get_time();
69
		$this->sql_init_time = $this->sql_start_time;
37
70
71
		$this->num_queries = array(
72
			'cached'		=> 0,
73
			'normal'		=> 0,
74
			'total'			=> 0,
75
		);
76
77
		// Fill default sql layer based on the class being called.
78
		// This can be changed by the specified layer itself later if needed.
79
		$this->sql_layer = SQL_LAYER;
80
81
		// Do not change this please! This variable is used to easy the use of it - and is hardcoded.
82
		$this->any_char = chr(0) . '%';
83
		$this->one_char = chr(0) . '_';
84
38
		$this->persistency = $persistency;
85
		$this->persistency = $persistency;
39
		$this->user = $sqluser;
86
		$this->user = $sqluser;
40
		$this->password = $sqlpassword;
87
		$this->password = $sqlpassword;
41
		$this->server = $sqlserver;
88
		$this->server = $sqlserver;
42
		$this->dbname = $database;
89
		$this->dbname = $database;
43
90
44
		if($this->persistency)
91
		$this->db_connect_id = ($this->persistency) ? @mysql_pconnect($this->server, $this->user, $this->password) : @mysql_connect($this->server, $this->user, $this->password);
45
		{
92
46
			$this->db_connect_id = @mysql_pconnect($this->server, $this->user, $this->password);
47
		}
48
		else
49
		{
50
			$this->db_connect_id = @mysql_connect($this->server, $this->user, $this->password);
51
		}
52
		if($this->db_connect_id)
93
		if($this->db_connect_id)
53
		{
94
		{
54
			if($database != "")
95
			if($database != '')
55
			{
96
			{
56
				$this->dbname = $database;
97
				$this->dbname = $database;
57
				$dbselect = @mysql_select_db($this->dbname);
98
				$dbselect = @mysql_select_db($this->dbname);
99
58
				if(!$dbselect)
100
				if(!$dbselect)
59
				{
101
				{
60
					@mysql_close($this->db_connect_id);
102
					@mysql_close($this->db_connect_id);
61
					$this->db_connect_id = $dbselect;
103
					$this->db_connect_id = $dbselect;
62
				}
104
				}
63
			}
105
			}
64
			return $this->db_connect_id;
106
107
			$result = $this->db_connect_id;
65
		}
108
		}
66
		else
109
		else
67
		{
110
		{
68
			return false;
111
			$this->sql_error('');
112
			$result = false;
69
		}
113
		}
114
115
		// make db connection UTF-8 aware
116
		if ($this->db_connect_id)
117
		{
118
			@mysql_query("SET NAMES 'utf8'");
119
		}
120
121
		$this->sql_server_version = $this->sql_server_info(true);
122
123
		$this->sql_end_time = $this->sql_get_time();
124
		$this->sql_time += $this->sql_end_time - $this->sql_start_time;
125
126
		return $result;
70
	}
127
	}
71
128
72
	//
129
	/**
73
	// Other base methods
130
	* Version information about used database
74
	//
131
	* @param bool $raw if true, only return the fetched sql_server_version
132
	* @return string sql server version
133
	*/
134
	function sql_server_info($raw = false)
135
	{
136
		global $cache;
137
138
		if (empty($cache) || ($this->sql_server_version = $cache->get('mysql_version')) === false)
139
		{
140
			$result = @mysql_query('SELECT VERSION() AS version', $this->db_connect_id);
141
			$row = @mysql_fetch_assoc($result);
142
			@mysql_free_result($result);
143
144
			$this->sql_server_version = $row['version'];
145
146
			if (!empty($cache))
147
			{
148
				$cache->put('mysql_version', $this->sql_server_version);
149
			}
150
		}
151
152
		return ($raw) ? $this->sql_server_version : 'MySQL ' . $this->sql_server_version;
153
	}
154
155
	/**
156
	* Get microtime
157
	*/
158
	function sql_get_time()
159
	{
160
		$mtime = explode(' ', microtime());
161
		return $mtime[1] + $mtime[0];
162
	}
163
164
	/**
165
	* Close DB connection
166
	*/
75
	function sql_close()
167
	function sql_close()
76
	{
168
	{
169
		$this->sql_start_time = $this->sql_get_time();
170
77
		if($this->db_connect_id)
171
		if($this->db_connect_id)
78
		{
172
		{
79
			if($this->query_result)
173
			// Commit any remaining transactions
174
			if($this->transaction)
80
			{
175
			{
81
				@mysql_free_result($this->query_result);
176
				do
177
				{
178
					$this->sql_transaction('commit');
179
				}
180
				while ($this->transaction);
82
			}
181
			}
83
			$result = @mysql_close($this->db_connect_id);
182
84
			return $result;
183
			foreach ($this->open_queries as $query_id)
184
			{
185
				$this->sql_freeresult($query_id);
186
			}
187
188
			// Connection closed correctly. Set db_connect_id to false to prevent errors
189
			if ($result = $this->_sql_close())
190
			{
191
				$this->db_connect_id = false;
192
			}
85
		}
193
		}
86
		else
194
		else
87
		{
195
		{
196
			$result = false;
197
		}
198
199
		$this->sql_end_time = $this->sql_get_time();
200
		$this->sql_time += $this->sql_end_time - $this->sql_start_time;
201
202
		return $result;
203
	}
204
205
	/**
206
	* Return number of sql queries and cached sql queries used
207
	*/
208
	function sql_num_queries($cached = false)
209
	{
210
		return ($cached) ? $this->num_queries['cached'] : $this->num_queries['normal'];
211
	}
212
213
	/**
214
	* Add to query count
215
	*/
216
	function sql_add_num_queries($cached = false)
217
	{
218
		$this->num_queries['cached'] += ($cached !== false) ? 1 : 0;
219
		$this->num_queries['normal'] += ($cached !== false) ? 0 : 1;
220
		$this->num_queries['total'] += 1;
221
	}
222
223
	/**
224
	* Build LIMIT query
225
	* Doing some validation here.
226
	*/
227
	function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
228
	{
229
		if (empty($query))
230
		{
88
			return false;
231
			return false;
89
		}
232
		}
233
234
		// Never use a negative total or offset
235
		$total = ($total < 0) ? 0 : $total;
236
		$offset = ($offset < 0) ? 0 : $offset;
237
238
		return $this->_sql_query_limit($query, $total, $offset, $cache_ttl);
90
	}
239
	}
91
240
92
	//
241
	/**
93
	// Base query method
242
	* Base query method
94
	//
243
	*/
95
	function sql_query($query = "", $transaction = FALSE)
244
	function sql_query($query = '', $cache_ttl = 0, $cache_prefix = false, $cache_folder = SQL_CACHE_FOLDER)
96
	{
245
	{
97
		// Remove any pre-existing queries
246
		if (empty($query))
98
		unset($this->query_result);
99
		if($query != "")
100
		{
247
		{
101
			$this->num_queries++;
248
			return false;
249
		}
102
250
103
			$this->query_result = @mysql_query($query, $this->db_connect_id);
251
		global $cache;
252
253
		$this->sql_start_time = $this->sql_get_time();
254
255
		$cache_folder = (empty($cache_folder) ? SQL_CACHE_FOLDER : $cache_folder);
256
257
		if (defined('DEBUG_EXTRA'))
258
		{
259
			$this->sql_report('start', $query);
104
		}
260
		}
105
		if($this->query_result)
261
262
		if (CACHE_SQL == false)
106
		{
263
		{
107
			unset($this->row[$this->query_result]);
264
			$cache_prefix = false;
108
			unset($this->rowset[$this->query_result]);
109
			return $this->query_result;
110
		}
265
		}
111
		else
266
267
		$cache_ttl = empty($cache_prefix) ? 0 : (empty($cache_ttl) ? CACHE_SQL_EXPIRY : $cache_ttl);
268
269
		// Cache SQL to the same file plus underscore
270
		if (defined('SQL_DEBUG_LOG') && SQL_DEBUG_LOG && !defined('IN_ADMIN'))
112
		{
271
		{
113
			return ( $transaction == END_TRANSACTION ) ? true : false;
272
			$f = fopen($this->cache_folder . 'sql_history.' . PHP_EXT, 'a+');
273
			@flock($f, LOCK_EX);
274
			@fwrite($f, gmdate('Y/m/d - H:i:s') . ' => ' . $hash . "\n\n" . $query . "\n\n\n=========================\n\n");
275
			@flock($f, LOCK_UN);
276
			@fclose($f);
114
		}
277
		}
278
279
		$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query, $cache_prefix, $cache_folder) : false;
280
		$this->sql_add_num_queries($this->query_result);
281
282
		if ($this->query_result === false)
283
		{
284
			if ((($this->query_result = @mysql_query($query, $this->db_connect_id)) === false) && !defined('IN_INSTALL'))
285
			{
286
				$this->sql_end_time = $this->sql_get_time();
287
				$this->sql_time += $this->sql_end_time - $this->sql_start_time;
288
289
				$this->sql_error($query);
290
			}
291
292
			if (defined('DEBUG_EXTRA'))
293
			{
294
				$this->sql_end_time = $this->sql_get_time();
295
				$this->sql_time += $this->sql_end_time - $this->sql_start_time;
296
297
				$this->sql_report('stop', $query);
298
			}
299
300
			if ($cache_ttl && method_exists($cache, 'sql_save'))
301
			{
302
				$this->open_queries[(int) $this->query_result] = $this->query_result;
303
				$cache->sql_save($query, $this->query_result, $cache_ttl, $cache_prefix, $cache_folder);
304
			}
305
			elseif (strpos($query, 'SELECT') === 0 && $this->query_result)
306
			{
307
				$this->open_queries[(int) $this->query_result] = $this->query_result;
308
			}
309
		}
310
		elseif (defined('DEBUG_EXTRA'))
311
		{
312
			$this->sql_report('fromcache', $query);
313
		}
314
315
		$this->sql_end_time = $this->sql_get_time();
316
		$this->sql_time += $this->sql_end_time - $this->sql_start_time;
317
318
		return $this->query_result;
115
	}
319
	}
116
320
117
	//
321
	/**
118
	// Other query methods
322
	* Get numrows
119
	//
323
	*/
120
	function sql_numrows($query_id = 0)
324
	function sql_numrows($query_id = 0)
121
	{
325
	{
122
		if(!$query_id)
326
		if(!$query_id)
123
		{
327
		{
124
			$query_id = $this->query_result;
328
			$query_id = $this->query_result;
125
		}
329
		}
126
		if($query_id)
330
127
		{
331
		return ($query_id) ? @mysql_num_rows($query_id) : false;
128
			$result = @mysql_num_rows($query_id);
129
			return $result;
130
		}
131
		else
132
		{
133
			return false;
134
		}
135
	}
332
	}
136
333
334
	/**
335
	* Get affected rows
336
	*/
137
	function sql_affectedrows()
337
	function sql_affectedrows()
138
	{
338
	{
139
		if($this->db_connect_id)
339
		return ($this->db_connect_id) ? @mysql_affected_rows($this->db_connect_id) : false;
340
	}
341
342
	/**
343
	* Fetch current row
344
	*/
345
	function sql_fetchrow($query_id = false)
346
	{
347
		global $cache;
348
349
		if ($query_id === false)
140
		{
350
		{
141
			$result = @mysql_affected_rows($this->db_connect_id);
351
			$query_id = $this->query_result;
142
			return $result;
143
		}
352
		}
144
		else
353
354
		if (isset($cache->sql_rowset[$query_id]))
145
		{
355
		{
146
			return false;
356
			return $cache->sql_fetchrow($query_id);
147
		}
357
		}
358
359
		return ($query_id !== false) ? @mysql_fetch_assoc($query_id) : false;
148
	}
360
	}
149
361
150
	function sql_numfields($query_id = 0)
362
	/**
363
	* Fetch all rows
364
	*/
365
	function sql_fetchrowset($query_id = false)
151
	{
366
	{
152
		if(!$query_id)
367
		$result = false;
368
		if ($query_id === false)
153
		{
369
		{
154
			$query_id = $this->query_result;
370
			$query_id = $this->query_result;
155
		}
371
		}
156
		if($query_id)
372
373
		if ($query_id !== false)
157
		{
374
		{
158
			$result = @mysql_num_fields($query_id);
375
			$result = array();
376
			while ($row = $this->sql_fetchrow($query_id))
377
			{
378
				$result[] = $row;
379
			}
380
159
			return $result;
381
			return $result;
160
		}
382
		}
161
		else
383
162
		{
384
		return false;
163
			return false;
164
		}
165
	}
385
	}
166
386
167
	function sql_fieldname($offset, $query_id = 0)
387
	/**
388
	* Fetch field
389
	* if rownum is false, the current row is used, else it is pointing to the row (zero-based)
390
	*/
391
	function sql_fetchfield($field, $rownum = false, $query_id = false)
168
	{
392
	{
169
		if(!$query_id)
393
		global $cache;
394
395
		$result = false;
396
		if ($query_id === false)
170
		{
397
		{
171
			$query_id = $this->query_result;
398
			$query_id = $this->query_result;
172
		}
399
		}
173
		if($query_id)
400
401
		if ($query_id !== false)
174
		{
402
		{
175
			$result = @mysql_field_name($query_id, $offset);
403
			if ($rownum !== false)
176
			return $result;
404
			{
405
				$this->sql_rowseek($rownum, $query_id);
406
			}
407
408
			if (!is_object($query_id) && isset($cache->sql_rowset[$query_id]))
409
			{
410
				return $cache->sql_fetchfield($query_id, $field);
411
			}
412
413
			$row = $this->sql_fetchrow($query_id);
414
			$result = (isset($row[$field])) ? $row[$field] : false;
177
		}
415
		}
178
		else
416
179
		{
417
		return $result;
180
			return false;
181
		}
182
	}
418
	}
183
419
184
	function sql_fieldtype($offset, $query_id = 0)
420
	/**
421
	* Get num fields
422
	*/
423
	function sql_numfields($query_id = 0)
185
	{
424
	{
186
		if(!$query_id)
425
		if(!$query_id)
187
		{
426
		{
188
			$query_id = $this->query_result;
427
			$query_id = $this->query_result;
189
		}
428
		}
190
		if($query_id)
429
191
		{
430
		return ($query_id) ? @mysql_num_fields($query_id) : false;
192
			$result = @mysql_field_type($query_id, $offset);
193
			return $result;
194
		}
195
		else
196
		{
197
			return false;
198
		}
199
	}
431
	}
200
432
201
	function sql_fetchrow($query_id = 0)
433
	/**
434
	* Get field name
435
	*/
436
	function sql_fieldname($offset, $query_id = 0)
202
	{
437
	{
203
		if(!$query_id)
438
		if(!$query_id)
204
		{
439
		{
205
			$query_id = $this->query_result;
440
			$query_id = $this->query_result;
206
		}
441
		}
207
		if($query_id)
442
208
		{
443
		return ($query_id) ? @mysql_field_name($query_id, $offset) : false;
209
			$this->row[$query_id] = @mysql_fetch_array($query_id);
210
			return $this->row[$query_id];
211
		}
212
		else
213
		{
214
			return false;
215
		}
216
	}
444
	}
217
445
218
	function sql_fetchrowset($query_id = 0)
446
	/**
447
	* Get field type
448
	*/
449
	function sql_fieldtype($offset, $query_id = 0)
219
	{
450
	{
220
		if(!$query_id)
451
		if(!$query_id)
221
		{
452
		{
222
			$query_id = $this->query_result;
453
			$query_id = $this->query_result;
223
		}
454
		}
224
		if($query_id)
455
225
		{
456
		return ($query_id) ? @mysql_field_type($query_id, $offset) : false;
226
			unset($this->rowset[$query_id]);
227
			unset($this->row[$query_id]);
228
			while($this->rowset[$query_id] = @mysql_fetch_array($query_id))
229
			{
230
				$result[] = $this->rowset[$query_id];
231
			}
232
			return $result;
233
		}
234
		else
235
		{
236
			return false;
237
		}
238
	}
457
	}
239
458
240
	function sql_fetchfield($field, $rownum = -1, $query_id = 0)
459
	/**
460
	* Seek to given row number
461
	* rownum is zero-based
462
	*/
463
	function sql_rowseek($rownum, &$query_id)
241
	{
464
	{
242
		if(!$query_id)
465
		global $cache;
466
467
		if ($query_id === false)
243
		{
468
		{
244
			$query_id = $this->query_result;
469
			$query_id = $this->query_result;
245
		}
470
		}
246
		if($query_id)
471
472
		if (isset($cache->sql_rowset[$query_id]))
247
		{
473
		{
248
			if($rownum > -1)
474
			return $cache->sql_rowseek($rownum, $query_id);
249
			{
250
				$result = @mysql_result($query_id, $rownum, $field);
251
			}
252
			else
253
			{
254
				if(empty($this->row[$query_id]) && empty($this->rowset[$query_id]))
255
				{
256
					if($this->sql_fetchrow())
257
					{
258
						$result = $this->row[$query_id][$field];
259
					}
260
				}
261
				else
262
				{
263
					if($this->rowset[$query_id])
264
					{
265
						$result = $this->rowset[$query_id][0][$field];
266
					}
267
					else if($this->row[$query_id])
268
					{
269
						$result = $this->row[$query_id][$field];
270
					}
271
				}
272
			}
273
			return $result;
274
		}
475
		}
275
		else
476
276
		{
477
		return ($query_id !== false) ? @mysql_data_seek($query_id, $rownum) : false;
277
			return false;
278
		}
279
	}
478
	}
280
479
281
	/**
480
	/**
481
	* Get last inserted id after insert statement
482
	*/
483
	function sql_nextid()
484
	{
485
		return ($this->db_connect_id) ? @mysql_insert_id($this->db_connect_id) : false;
486
	}
487
488
	/**
282
	* Function for validating values
489
	* Function for validating values
283
	*/
490
	*/
284
	function sql_validate_value($var)
491
	function sql_validate_value($var)
...
...
311
	}
518
	}
312
519
313
	/**
520
	/**
521
	* Correctly adjust LIKE expression for special characters
522
	* Some DBMS are handling them in a different way
523
	*
524
	* @param string $expression The expression to use. Every wildcard is escaped, except $this->any_char and $this->one_char
525
	* @return string LIKE expression including the keyword!
526
	*/
527
	function sql_like_expression($expression)
528
	{
529
		$expression = str_replace(array('_', '%'), array("\_", "\%"), $expression);
530
		$expression = str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression);
531
532
		return $this->_sql_like_expression('LIKE \'' . $this->sql_escape($expression) . '\'');
533
	}
534
535
	/**
536
	* Build sql statement from array for select and select distinct statements
537
	*
538
	* Possible query values: SELECT, SELECT_DISTINCT
539
	*/
540
	function sql_build_query($query, $array)
541
	{
542
		$sql = '';
543
		switch ($query)
544
		{
545
			case 'SELECT':
546
			case 'SELECT_DISTINCT';
547
548
				$sql = str_replace('_', ' ', $query) . ' ' . $array['SELECT'] . ' FROM ';
549
550
				// Build table array. We also build an alias array for later checks.
551
				$table_array = $aliases = array();
552
				$used_multi_alias = false;
553
554
				foreach ($array['FROM'] as $table_name => $alias)
555
				{
556
					if (is_array($alias))
557
					{
558
						$used_multi_alias = true;
559
560
						foreach ($alias as $multi_alias)
561
						{
562
							$table_array[] = $table_name . ' ' . $multi_alias;
563
							$aliases[] = $multi_alias;
564
						}
565
					}
566
					else
567
					{
568
						$table_array[] = $table_name . ' ' . $alias;
569
						$aliases[] = $alias;
570
					}
571
				}
572
573
				// We run the following code to determine if we need to re-order the table array. ;)
574
				// The reason for this is that for multi-aliased tables (two equal tables) in the FROM statement the last table need to match the first comparison.
575
				// DBMS who rely on this: Oracle, PostgreSQL and MSSQL. For all other DBMS it makes absolutely no difference in which order the table is.
576
				if (!empty($array['LEFT_JOIN']) && sizeof($array['FROM']) > 1 && $used_multi_alias !== false)
577
				{
578
					// Take first LEFT JOIN
579
					$join = current($array['LEFT_JOIN']);
580
581
					// Determine the table used there (even if there are more than one used, we only want to have one
582
					preg_match('/(' . implode('|', $aliases) . ')\.[^\s]+/U', str_replace(array('(', ')', 'AND', 'OR', ' '), '', $join['ON']), $matches);
583
584
					// If there is a first join match, we need to make sure the table order is correct
585
					if (!empty($matches[1]))
586
					{
587
						$first_join_match = trim($matches[1]);
588
						$table_array = $last = array();
589
590
						foreach ($array['FROM'] as $table_name => $alias)
591
						{
592
							if (is_array($alias))
593
							{
594
								foreach ($alias as $multi_alias)
595
								{
596
									($multi_alias === $first_join_match) ? $last[] = $table_name . ' ' . $multi_alias : $table_array[] = $table_name . ' ' . $multi_alias;
597
								}
598
							}
599
							else
600
							{
601
								($alias === $first_join_match) ? $last[] = $table_name . ' ' . $alias : $table_array[] = $table_name . ' ' . $alias;
602
							}
603
						}
604
605
						$table_array = array_merge($table_array, $last);
606
					}
607
				}
608
609
				$sql .= $this->_sql_custom_build('FROM', implode(', ', $table_array));
610
611
				if (!empty($array['LEFT_JOIN']))
612
				{
613
					foreach ($array['LEFT_JOIN'] as $join)
614
					{
615
						$sql .= ' LEFT JOIN ' . key($join['FROM']) . ' ' . current($join['FROM']) . ' ON (' . $join['ON'] . ')';
616
					}
617
				}
618
619
				if (!empty($array['WHERE']))
620
				{
621
					$sql .= ' WHERE ' . $this->_sql_custom_build('WHERE', $array['WHERE']);
622
				}
623
624
				if (!empty($array['GROUP_BY']))
625
				{
626
					$sql .= ' GROUP BY ' . $array['GROUP_BY'];
627
				}
628
629
				if (!empty($array['ORDER_BY']))
630
				{
631
					$sql .= ' ORDER BY ' . $array['ORDER_BY'];
632
				}
633
634
			break;
635
		}
636
637
		return $sql;
638
	}
639
640
	/**
641
	* Build SQL to INSERT or UPDATE from the provided array
642
	*/
643
	function sql_build_insert_update($sql_input_array, $sql_insert = true)
644
	{
645
		$insert_fields_sql = '';
646
		$insert_values_sql = '';
647
		$update_sql = '';
648
		foreach ($sql_input_array as $k => $v)
649
		{
650
			$insert_fields_sql .= (($insert_fields_sql == '') ? '' : ', ') . $k;
651
			$insert_values_sql .= (($insert_values_sql == '') ? '' : ', ') . $this->sql_validate_value($v);
652
			$update_sql .= (($update_sql == '') ? '' : ', ') . $k . ' = ' . $this->sql_validate_value($v);
653
		}
654
655
		$sql_string = $sql_insert ? (' (' . $insert_fields_sql . ') VALUES (' . $insert_values_sql . ')') : $update_sql;
656
657
		return $sql_string;
658
	}
659
660
	/**
314
	* Build sql statement from array for insert/update/select statements
661
	* Build sql statement from array for insert/update/select statements
315
	*
662
	*
316
	* Idea for this from Ikonboard
663
	* Idea for this from Ikonboard
...
...
362
		return $query;
709
		return $query;
363
	}
710
	}
364
711
365
	function sql_rowseek($rownum, $query_id = 0){
712
	/**
366
		if(!$query_id)
713
	* Build IN or NOT IN sql comparison string, uses <> or = on single element arrays to improve comparison speed
714
	*
715
	* @access public
716
	* @param string $field name of the sql column that shall be compared
717
	* @param array $array array of values that are allowed (IN) or not allowed (NOT IN)
718
	* @param bool $negate true for NOT IN (), false for IN () (default)
719
	* @param bool $allow_empty_set If true, allow $array to be empty, this function will return 1=1 or 1=0 then. Default to false.
720
	*/
721
	function sql_in_set($field, $array, $negate = false, $allow_empty_set = false)
722
	{
723
		if (!sizeof($array))
367
		{
724
		{
368
			$query_id = $this->query_result;
725
			if (!$allow_empty_set)
726
			{
727
				// Print the backtrace to help identifying the location of the problematic code
728
				$this->sql_error('No values specified for SQL IN comparison');
729
			}
730
			else
731
			{
732
				// NOT IN () actually means everything so use a tautology
733
				if ($negate)
734
				{
735
					return '1=1';
736
				}
737
				// IN () actually means nothing so use a contradiction
738
				else
739
				{
740
					return '1=0';
741
				}
742
			}
369
		}
743
		}
370
		if($query_id)
744
745
		if (!is_array($array))
371
		{
746
		{
372
			$result = @mysql_data_seek($query_id, $rownum);
747
			$array = array($array);
373
			return $result;
374
		}
748
		}
749
750
		if (sizeof($array) == 1)
751
		{
752
			@reset($array);
753
			$var = current($array);
754
755
			return $field . ($negate ? ' <> ' : ' = ') . $this->sql_validate_value($var);
756
		}
375
		else
757
		else
376
		{
758
		{
377
			return false;
759
			return $field . ($negate ? ' NOT IN ' : ' IN ') . '(' . implode(', ', array_map(array($this, 'sql_validate_value'), $array)) . ')';
378
		}
760
		}
379
	}
761
	}
380
762
381
	function sql_nextid(){
763
	/**
382
		if($this->db_connect_id)
764
	* Run more than one insert statement.
765
	*
766
	* @param string $table table name to run the statements on
767
	* @param array &$sql_ary multi-dimensional array holding the statement data.
768
	*
769
	* @return bool false if no statements were executed.
770
	* @access public
771
	*/
772
	function sql_multi_insert($table, &$sql_ary)
773
	{
774
		if (!sizeof($sql_ary))
383
		{
775
		{
384
			$result = @mysql_insert_id($this->db_connect_id);
776
			return false;
385
			return $result;
386
		}
777
		}
778
779
		if ($this->multi_insert)
780
		{
781
			$ary = array();
782
			foreach ($sql_ary as $id => $_sql_ary)
783
			{
784
				// If by accident the sql array is only one-dimensional we build a normal insert statement
785
				if (!is_array($_sql_ary))
786
				{
787
					$this->sql_query('INSERT INTO ' . $table . ' ' . $this->sql_build_array('INSERT', $sql_ary));
788
					return true;
789
				}
790
791
				$values = array();
792
				foreach ($_sql_ary as $key => $var)
793
				{
794
					$values[] = $this->_sql_validate_value($var);
795
				}
796
				$ary[] = '(' . implode(', ', $values) . ')';
797
			}
798
799
			$this->sql_query('INSERT INTO ' . $table . ' ' . ' (' . implode(', ', array_keys($sql_ary[0])) . ') VALUES ' . implode(', ', $ary));
800
		}
387
		else
801
		else
388
		{
802
		{
389
			return false;
803
			foreach ($sql_ary as $ary)
804
			{
805
				if (!is_array($ary))
806
				{
807
					return false;
808
				}
809
810
				$this->sql_query('INSERT INTO ' . $table . ' ' . $this->sql_build_array('INSERT', $ary));
811
			}
390
		}
812
		}
813
814
		return true;
391
	}
815
	}
392
816
393
	function sql_freeresult($query_id = 0){
817
	/**
394
		if(!$query_id)
818
	* Free sql result
819
	*/
820
	function sql_freeresult($query_id = false)
821
	{
822
		global $cache;
823
824
		if ($query_id === false)
395
		{
825
		{
396
			$query_id = $this->query_result;
826
			$query_id = $this->query_result;
397
		}
827
		}
398
828
399
		if ( $query_id )
829
		if (isset($cache->sql_rowset[$query_id]))
400
		{
830
		{
401
			unset($this->row[$query_id]);
831
			return $cache->sql_freeresult($query_id);
402
			unset($this->rowset[$query_id]);
832
		}
403
833
404
			@mysql_free_result($query_id);
834
		if (isset($this->open_queries[(int) $query_id]))
835
		{
836
			unset($this->open_queries[(int) $query_id]);
837
			return @mysql_free_result($query_id);
838
		}
405
839
406
			return true;
840
		return false;
841
	}
842
843
	/**
844
	* Errors handling
845
	*/
846
	function sql_error($sql = '')
847
	{
848
		global $lang;
849
850
		// Set var to retrieve errored status
851
		$this->sql_error_triggered = true;
852
		$this->sql_error_sql = $sql;
853
854
		$this->sql_error_returned = $this->_sql_error();
855
856
		if (!$this->return_on_error && !defined('IN_INSTALL'))
857
		{
858
			$message = '<b>SQL ERROR [ ' . SQL_LAYER . ' ]</b><br /><br />' . $this->sql_error_returned['message'] . ' [' . $this->sql_error_returned['code'] . ']';
859
860
			// Show complete SQL error and path to administrators only
861
			// Additionally show complete error on installation or if extended debug mode is enabled
862
			// The DEBUG_EXTRA constant is for development only!
863
			if (defined('IN_INSTALL') || (defined('DEBUG_EXTRA') && (DEBUG_EXTRA == true)))
864
			{
865
				$backtrace = get_backtrace();
866
867
				$message .= ($sql) ? '<br /><br /><b>SQL</b><br /><br />' . htmlspecialchars($sql) : '';
868
				$message .= ($backtrace) ? '<br /><br /><b>BACKTRACE</b><br />' . $backtrace : '';
869
				$message .= '<br />';
870
			}
871
			else
872
			{
873
				// If error occurs in initiating the session we need to use a pre-defined language string
874
				// This could happen if the connection could not be established for example (then we are not able to grab the default language)
875
				if (!isset($lang['SQL_ERROR_OCCURRED']))
876
				{
877
					$message .= '<br /><br />An sql error occurred while fetching this page. Please contact site administrator if this problem persists.';
878
				}
879
				else
880
				{
881
					$message .= '<br /><br />' . $lang['SQL_ERROR_OCCURRED'];
882
				}
883
			}
884
885
			if ($this->transaction)
886
			{
887
				$this->sql_transaction('rollback');
888
			}
889
890
			global $msg_code;
891
			$msg_code = CRITICAL_MESSAGE;
892
			$message = '<div style="text-align: left;">' . $message . '</div>';
893
894
			if (strlen($message) > 1024)
895
			{
896
				// We need to define $msg_long_text here to circumvent text stripping.
897
				global $msg_long_text;
898
				$msg_long_text = $message;
899
900
				trigger_error(false, E_USER_NOTICE);
901
			}
902
903
			trigger_error($message, E_USER_NOTICE);
904
			/*
905
			$msg_text = $message;
906
			$msg_title = isset($lang['Error']) ? $lang['Error'] : 'Error';
907
			message_die($msg_code, $msg_text, $msg_title, __LINE__, __FILE__, $sql);
908
			*/
407
		}
909
		}
408
		else
910
911
		if ($this->transaction)
409
		{
912
		{
410
			return false;
913
			$this->sql_transaction('rollback');
411
		}
914
		}
915
916
		return $this->sql_error_returned;
412
	}
917
	}
413
918
414
	/**
919
	/**
...
...
416
	*/
921
	*/
417
	function sql_return_on_error($fail = false)
922
	function sql_return_on_error($fail = false)
418
	{
923
	{
419
		return true;
924
		$this->sql_error_triggered = false;
925
		$this->sql_error_sql = '';
926
927
		$this->return_on_error = $fail;
420
	}
928
	}
421
929
422
	function sql_error($query_id = 0)
930
	/**
931
	* SQL Transaction
932
	* @access private
933
	*/
934
	function sql_transaction($status = 'begin')
423
	{
935
	{
424
		$result["message"] = @mysql_error($this->db_connect_id);
936
		switch ($status)
425
		$result["code"] = @mysql_errno($this->db_connect_id);
937
		{
938
			case 'begin':
939
				// If we are within a transaction we will not open another one, but enclose the current one to not loose data (prevening auto commit)
940
				if ($this->transaction)
941
				{
942
					$this->transactions++;
943
					return true;
944
				}
426
945
946
				$result = $this->_sql_transaction('begin');
947
948
				if (!$result)
949
				{
950
					$this->sql_error();
951
				}
952
953
				$this->transaction = true;
954
			break;
955
956
			case 'commit':
957
				// If there was a previously opened transaction we do not commit yet... but count back the number of inner transactions
958
				if ($this->transaction && $this->transactions)
959
				{
960
					$this->transactions--;
961
					return true;
962
				}
963
964
				// Check if there is a transaction (no transaction can happen if there was an error, with a combined rollback and error returning enabled)
965
				// This implies we have transaction always set for autocommit db's
966
				if (!$this->transaction)
967
				{
968
					return false;
969
				}
970
971
				$result = $this->_sql_transaction('commit');
972
973
				if (!$result)
974
				{
975
					$this->sql_error();
976
				}
977
978
				$this->transaction = false;
979
				$this->transactions = 0;
980
			break;
981
982
			case 'rollback':
983
				$result = $this->_sql_transaction('rollback');
984
				$this->transaction = false;
985
				$this->transactions = 0;
986
			break;
987
988
			default:
989
				$result = $this->_sql_transaction($status);
990
			break;
991
		}
992
427
		return $result;
993
		return $result;
428
	}
994
	}
429
995
430
} // class sql_db
996
	/**
997
	* Explain queries
998
	*/
999
	function sql_report($mode, $query = '')
1000
	{
1001
		if (empty($_REQUEST['explain']))
1002
		{
1003
			return false;
1004
		}
431
1005
432
} // if ... define
1006
		if (!$query && ($this->query_hold != ''))
1007
		{
1008
			$query = $this->query_hold;
1009
		}
433
1010
1011
		switch ($mode)
1012
		{
1013
			case 'display':
1014
				if (!empty($cache))
1015
				{
1016
					$cache->unload();
1017
				}
1018
				$this->sql_close();
1019
1020
				$mtime = explode(' ', microtime());
1021
				$totaltime = $mtime[0] + $mtime[1] - $this->sql_init_time;
1022
				echo ('
1023
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1024
<html xmlns="http://www.w3.org/1999/xhtml">
1025
<head>
1026
	<link rel="stylesheet" href="' . IP_ROOT_PATH . 'templates/common/acp.css" type="text/css" />
1027
	<meta name="author" content="Mighty Gorgon" />
1028
	<title>Icy Phoenix</title>
1029
	<!--[if lt IE 7]>
1030
	<script type="text/javascript" src="' . IP_ROOT_PATH . 'templates/common/js/pngfix.js"></script>
1031
	<![endif]-->
1032
</head>
1033
1034
<body>
1035
<a name="top"></a>
1036
<div id="global-wrapper" style="width: 960px; clear: both; margin: 0 auto;">
1037
<div class="leftshadow"><div class="rightshadow"><div id="wrapper-inner">
1038
<table id="forumtable" width="100%" cellspacing="0" cellpadding="0">
1039
<tr>
1040
	<td width="100%" colspan="3" valign="top">
1041
	<div id="top_logo">
1042
	<table class="" width="100%" cellspacing="0" cellpadding="0" border="0">
1043
	<tr>
1044
	<td height="150" align="left" valign="middle">
1045
		<a href="http://www.icyphoenix.com" title="Icy Phoenix"><img src="' . IP_ROOT_PATH . 'images/logo_ip.png" alt="Icy
Phoenix" title="Icy Phoenix" border="0" /></a>
1046
	</td>
1047
	</tr>
1048
	</table>
1049
	</div>
1050
	</td>
1051
</tr>
1052
<tr><td colspan="3" class="forum-buttons" valign="middle">Icy Phoenix Extra Debug</td></tr>
1053
<tr>
1054
	<td colspan="3" id="content">
1055
	<div class="post-text">
1056
		<br />
1057
		<h1>SQL Report</h1>
1058
		<br />
1059
		<p><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries['normal']} queries" .
(($this->num_queries['cached']) ? " + {$this->num_queries['cached']} " . (($this->num_queries['cached'] == 1) ? 'query' : 'queries') . '
returning data from cache' : '') . '</b></p>
1060
		<p>Time spent on ' . $this->num_queries['total'] . ' queries: <b>' . round($this->sql_time, 5) . 's</b></p>
1061
		<p>Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></p>
1062
		<br /><br />
1063
		' . $this->sql_report . '
1064
	</div>
1065
	</td>
1066
</tr>
1067
<tr>
1068
	<td width="100%" colspan="3">
1069
	<div id="bottom_logo_ext">
1070
	<div id="bottom_logo">
1071
		<table class="empty-table" width="100%" cellspacing="0" cellpadding="0" border="0">
1072
			<tr>
1073
				<td nowrap="nowrap" width="45%" align="left">
1074
					<br /><span class="copyright">&nbsp;Powered by <a href="http://www.icyphoenix.com/" target="_blank">Icy
Phoenix</a> based on <a href="http://www.phpbb.com/" target="_blank">phpBB</a></span><br /><br />
1075
				</td>
1076
				<td nowrap="nowrap" align="center"><div style="text-align:center;">&nbsp;</div></td>
1077
				<td nowrap="nowrap" width="45%" align="right">
1078
					<br /><span class="copyright">Design by <a href="http://www.mightygorgon.com" target="_blank">Mighty
Gorgon</a>&nbsp;</span><br /><br />
1079
				</td>
1080
			</tr>
1081
		</table>
1082
	</div>
1083
	</div>
1084
	</td>
1085
</tr>
1086
</table>
1087
</div></div></div>
1088
</div>
1089
</body>
1090
</html>
1091
');
1092
				exit_handler();
1093
				exit;
1094
				break;
1095
1096
			case 'stop':
1097
				$endtime = explode(' ', microtime());
1098
				$endtime = $endtime[0] + $endtime[1];
1099
				$this->sql_report .= '
1100
<table class="forumline" width="100%" cellspacing="0" cellpadding="0" border="0">
1101
<thead>
1102
<tr><th>Query #' . $this->num_queries['total'] . '</th></tr>
1103
</thead>
1104
<tbody>
1105
<tr>
1106
	<td class="row1"><textarea style="font-family: \'Courier New\', monospace; width: 99%;" rows="8"
cols="160">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n",
$query))) . '</textarea></td>
1107
</tr>
1108
</tbody>
1109
</table>
1110
' . $this->html_hold . '
1111
<p class="helpline" style="padding: 2px;">
1112
				';
1113
				if ($this->query_result)
1114
				{
1115
					$this->sql_report .= 'Elapsed: <b style="color:#224488;">' . sprintf('%.5f', $endtime - $this->curtime) . 's</b> &bull;
[Before: ' . sprintf('%.5f', $this->curtime - $this->sql_start_time) . 's | After: ' . sprintf('%.5f', $endtime - $this->sql_start_time) . 's]';
1116
					if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
1117
					{
1118
						$this->sql_report .= ' - [Affected rows: <b style="color:#224488;">' . $this->sql_affectedrows($this->query_result) .
'</b>]';
1119
					}
1120
				}
1121
				else
1122
				{
1123
					$error = $this->sql_error();
1124
					$this->sql_report .= '<b style="color:#cc3333;">FAILED</b> - ' . SQL_LAYER . ' Error ' . $error['code'] . ': ' .
htmlspecialchars($error['message']);
1125
				}
1126
				$this->sql_report .= '</p><br /><br />';
1127
				$this->sql_time += $endtime - $this->curtime;
1128
			break;
1129
1130
			case 'start':
1131
				$this->query_hold = $query;
1132
				$this->html_hold = '';
1133
				$this->curtime = explode(' ', microtime());
1134
				$this->curtime = $this->curtime[0] + $this->curtime[1];
1135
			break;
1136
1137
			case 'add_select_row':
1138
1139
				$html_table = func_get_arg(2);
1140
				$row = func_get_arg(3);
1141
1142
				if (!$html_table && sizeof($row))
1143
				{
1144
					$html_table = true;
1145
					$this->html_hold .= '<table class="forumline" width="100%" cellspacing="0" cellpadding="0"
border="0"><tr>';
1146
1147
					foreach (array_keys($row) as $val)
1148
					{
1149
						$this->html_hold .= '<th>' . (($val) ? ucwords(str_replace('_', ' ', $val)) : '&nbsp;') . '</th>';
1150
					}
1151
					$this->html_hold .= '</tr>';
1152
				}
1153
				$this->html_hold .= '<tr>';
1154
1155
				$class = 'row1';
1156
				foreach (array_values($row) as $val)
1157
				{
1158
					$class = ($class == 'row1') ? 'row2' : 'row1';
1159
					$this->html_hold .= '<td class="' . $class . '">' . (($val) ? $val : '&nbsp;') . '</td>';
1160
				}
1161
				$this->html_hold .= '</tr>';
1162
1163
				return $html_table;
1164
1165
			break;
1166
1167
			case 'fromcache':
1168
1169
				$this->_sql_report($mode, $query);
1170
1171
			break;
1172
1173
			case 'record_fromcache':
1174
1175
				$endtime = func_get_arg(2);
1176
				$splittime = func_get_arg(3);
1177
1178
				$time_cache = $endtime - $this->curtime;
1179
				$time_db = $splittime - $endtime;
1180
				$color = ($time_db > $time_cache) ? '#228844' : '#cc3333';
1181
1182
				$this->sql_report .= '<table class="forumline" width="100%" cellspacing="0" cellpadding="0"
border="0">';
1183
				$this->sql_report .= '<thead><tr><th>Query #' . $this->num_queries['total'] . ' [From
Cache]</th></tr></thead><tbody><tr>';
1184
				$this->sql_report .= '<td class="row3"><textarea style="font-family: \'Courier New\', monospace; width: 99%;"
rows="8" cols="160">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/',
"\n", $query))) . '</textarea></td></tr></tbody></table>';
1185
				$this->sql_report .= '<p class="helpline" style="padding: 2px;">';
1186
				$this->sql_report .= 'Before: ' . sprintf('%.5f', $this->curtime - $this->sql_start_time) . 's | After: ' . sprintf('%.5f', $endtime -
$this->sql_start_time) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed
[db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p><br /><br />';
1187
1188
				// Pad the start time to not interfere with page timing
1189
				$this->sql_start_time += $time_db;
1190
1191
			break;
1192
1193
			default:
1194
				$this->_sql_report($mode, $query);
1195
			break;
1196
		}
1197
1198
		return true;
1199
	}
1200
1201
	/**
1202
	* Build LIMIT query
1203
	*/
1204
	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
1205
	{
1206
		$this->query_result = false;
1207
1208
		// if $total is set to 0 we do not want to limit the number of rows
1209
		if ($total == 0)
1210
		{
1211
			// Having a value of -1 was always a bug
1212
			$total = '18446744073709551615';
1213
		}
1214
1215
		$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
1216
1217
		return $this->sql_query($query, $cache_ttl);
1218
	}
1219
1220
	/**
1221
	* Build LIKE expression
1222
	* @access private
1223
	*/
1224
	function _sql_like_expression($expression)
1225
	{
1226
		return $expression;
1227
	}
1228
1229
	/**
1230
	* Build db-specific query data
1231
	* @access private
1232
	*/
1233
	function _sql_custom_build($stage, $data)
1234
	{
1235
		switch ($stage)
1236
		{
1237
			case 'FROM':
1238
				$data = '(' . $data . ')';
1239
			break;
1240
		}
1241
1242
		return $data;
1243
	}
1244
1245
	/**
1246
	* SQL Transaction
1247
	* @access private
1248
	*/
1249
	function _sql_transaction($status = 'begin')
1250
	{
1251
		switch ($status)
1252
		{
1253
			case 'begin':
1254
				return @mysql_query('BEGIN', $this->db_connect_id);
1255
			break;
1256
1257
			case 'commit':
1258
				return @mysql_query('COMMIT', $this->db_connect_id);
1259
			break;
1260
1261
			case 'rollback':
1262
				return @mysql_query('ROLLBACK', $this->db_connect_id);
1263
			break;
1264
		}
1265
1266
		return true;
1267
	}
1268
1269
	/**
1270
	* return sql error array
1271
	* @access private
1272
	*/
1273
	function _sql_error()
1274
	{
1275
		if (!$this->db_connect_id)
1276
		{
1277
			return array(
1278
				'message' => @mysql_error(),
1279
				'code' => @mysql_errno()
1280
			);
1281
		}
1282
1283
		return array(
1284
			'message' => @mysql_error($this->db_connect_id),
1285
			'code' => @mysql_errno($this->db_connect_id)
1286
		);
1287
	}
1288
1289
	/**
1290
	* Build db-specific report
1291
	* @access private
1292
	*/
1293
	function _sql_report($mode, $query = '')
1294
	{
1295
		static $test_prof;
1296
1297
		// current detection method, might just switch to see the existance of INFORMATION_SCHEMA.PROFILING
1298
		if ($test_prof === null)
1299
		{
1300
			$test_prof = false;
1301
			if (version_compare($this->sql_server_info(true), '5.0.37', '>=') && version_compare($this->sql_server_info(true), '5.1', '<'))
1302
			{
1303
				$test_prof = true;
1304
			}
1305
		}
1306
1307
		switch ($mode)
1308
		{
1309
			case 'start':
1310
1311
				$explain_query = $query;
1312
				if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
1313
				{
1314
					$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
1315
				}
1316
				elseif (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
1317
				{
1318
					$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
1319
				}
1320
1321
				if (preg_match('/^SELECT/', $explain_query))
1322
				{
1323
					$html_table = false;
1324
1325
					// begin profiling
1326
					if ($test_prof)
1327
					{
1328
						@mysql_query('SET profiling = 1;', $this->db_connect_id);
1329
					}
1330
1331
					if ($result = @mysql_query("EXPLAIN $explain_query", $this->db_connect_id))
1332
					{
1333
						while ($row = @mysql_fetch_assoc($result))
1334
						{
1335
							$html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
1336
						}
1337
					}
1338
					@mysql_free_result($result);
1339
1340
					if ($html_table)
1341
					{
1342
						$this->html_hold .= '</table>';
1343
					}
1344
1345
					if ($test_prof)
1346
					{
1347
						$html_table = false;
1348
1349
						// get the last profile
1350
						if ($result = @mysql_query('SHOW PROFILE ALL;', $this->db_connect_id))
1351
						{
1352
							$this->html_hold .= '<br />';
1353
							while ($row = @mysql_fetch_assoc($result))
1354
							{
1355
								// make <unknown> HTML safe
1356
								if (!empty($row['Source_function']))
1357
								{
1358
									$row['Source_function'] = str_replace(array('<', '>'), array('&lt;', '&gt;'), $row['Source_function']);
1359
								}
1360
1361
								// remove unsupported features
1362
								foreach ($row as $key => $val)
1363
								{
1364
									if ($val === null)
1365
									{
1366
										unset($row[$key]);
1367
									}
1368
								}
1369
								$html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
1370
							}
1371
						}
1372
						@mysql_free_result($result);
1373
1374
						if ($html_table)
1375
						{
1376
							$this->html_hold .= '</table>';
1377
						}
1378
1379
						@mysql_query('SET profiling = 0;', $this->db_connect_id);
1380
					}
1381
				}
1382
1383
			break;
1384
1385
			case 'fromcache':
1386
				$endtime = explode(' ', microtime());
1387
				$endtime = $endtime[0] + $endtime[1];
1388
1389
				$result = @mysql_query($query, $this->db_connect_id);
1390
				while ($void = @mysql_fetch_assoc($result))
1391
				{
1392
					// Take the time spent on parsing rows into account
1393
				}
1394
				@mysql_free_result($result);
1395
1396
				$splittime = explode(' ', microtime());
1397
				$splittime = $splittime[0] + $splittime[1];
1398
1399
				$this->sql_report('record_fromcache', $query, $endtime, $splittime);
1400
1401
			break;
1402
		}
1403
	}
1404
1405
	/**
1406
	* Close sql connection
1407
	* @access private
1408
	*/
1409
	function _sql_close()
1410
	{
1411
		return @mysql_close($this->db_connect_id);
1412
	}
1413
1414
	/**
1415
	* Cache clear function
1416
	*/
1417
	function clear_cache($cache_prefix = '', $cache_folder = SQL_CACHE_FOLDER, $files_per_step = 0)
1418
	{
1419
		$cache_folder = (empty($cache_folder) ? SQL_CACHE_FOLDER : $cache_folder);
1420
1421
		$cache_prefix = 'sql_' . $cache_prefix;
1422
		$cache_folder = (!empty($cache_folder) && @is_dir($cache_folder)) ? $cache_folder : SQL_CACHE_FOLDER;
1423
		$cache_folder = ((@is_dir($cache_folder)) ? $cache_folder : @phpbb_realpath($cache_folder));
1424
1425
		$res = opendir($cache_folder);
1426
		if($res)
1427
		{
1428
			$files_counter = 0;
1429
			while(($file = readdir($res)) !== false)
1430
			{
1431
				if(!@is_dir($file) && (substr($file, 0, strlen($cache_prefix)) === $cache_prefix) && (substr($file, -(strlen(PHP_EXT) + 1)) === '.' .
PHP_EXT))
1432
				{
1433
					@unlink($cache_folder . $file);
1434
					$files_counter++;
1435
				}
1436
				if (($files_per_step > 0) && ($files_counter >= $files_per_step))
1437
				{
1438
					closedir($res);
1439
					return $files_per_step;
1440
				}
1441
			}
1442
		}
1443
		@closedir($res);
1444
	}
1445
1446
}
1447
434
?>
1448
?>