Project

General

Profile

1 4 ryan
<?php
2 1362 Luisehahne
/**
3
 *
4
 * @category        framework
5
 * @package         database
6
 * @author          WebsiteBaker Project
7
 * @copyright       2004-2009, Ryan Djurovich
8
 * @copyright       2009-2011, Website Baker Org. e.V.
9
 * @link            http://www.websitebaker2.org/
10
 * @license         http://www.gnu.org/licenses/gpl.html
11
 * @platform        WebsiteBaker 2.8.x
12 1374 Luisehahne
 * @requirements    PHP 5.2.2 and higher
13 1362 Luisehahne
 * @version         $Id$
14 1457 Luisehahne
 * @filesource      $HeadURL$
15
 * @lastmodified    $Date$
16 1362 Luisehahne
 *
17
 */
18 4 ryan
/*
19
Database class
20
This class will be used to interface between the database
21
and the Website Baker code
22
*/
23 1496 DarkViper
/* -------------------------------------------------------- */
24
// Must include code to stop this file being accessed directly
25 1499 DarkViper
if(!defined('WB_PATH')) {
26
	require_once(dirname(__FILE__).'/globalExceptionHandler.php');
27
	throw new IllegalFileException();
28
}
29 1496 DarkViper
/* -------------------------------------------------------- */
30 4 ryan
define('DATABASE_CLASS_LOADED', true);
31
32 1680 darkviper
class Database {
33 1362 Luisehahne
34 1680 darkviper
//	$sdb = 'mysql://user:password@demo.de:3604/datenbank';
35
36
	private $_db_handle = null; // readonly from outside
37
	private $_scheme    = 'mysql';
38
	private $_hostname  = 'localhost';
39
	private $_username  = '';
40
	private $_password  = '';
41
	private $_hostport  = '3406';
42
	private $_db_name   = '';
43
44 1362 Luisehahne
	private $connected  = false;
45
46
	private $error      = '';
47
	private $error_type = '';
48
	private $message    = array();
49 1662 darkviper
	private $iQueryCount= 0;
50 1362 Luisehahne
51
52 4 ryan
	// Set DB_URL
53 1680 darkviper
	function __construct($url = '') {
54
		if($url != '') {
55
			$aIni = parse_url($url);
56
			$this->_scheme   = isset($aIni['scheme']) ? $aIni['scheme'] : 'mysql';
57
			$this->_hostname = isset($aIni['host']) ? $aIni['host'] : '';
58
			$this->_username = isset($aIni['user']) ? $aIni['user'] : '';
59
			$this->_password = isset($aIni['pass']) ? $aIni['pass'] : '';
60
			$this->_hostport = isset($aIni['port']) ? $aIni['port'] : '3306';
61
			$this->_hostport = $this->_hostport == '3306' ? '' : ':'.$this->_hostport;
62
			$this->_db_name  = ltrim(isset($aIni['path']) ? $aIni['path'] : '', '/\\');
63
		}else {
64
			$this->_hostname = DB_HOST;
65
			$this->_username = DB_USERNAME;
66
			$this->_password = DB_PASSWORD;
67
			$this->_hostport = '';
68
			$this->_db_name  = DB_NAME;
69
		}
70 4 ryan
		// Connect to database
71
		$this->connect();
72
	}
73
74
	// Connect to the database
75
	function connect() {
76 1680 darkviper
		$this->_db_handle = mysql_connect($this->_hostname.$this->_hostport,
77
		                                  $this->_username,
78
		                                  $this->_password);
79
		if(!$this->_db_handle) {
80
			throw new RuntimeException('unable to connect \''.$this->_scheme.'://'.
81
			                           $this->_hostname.$this->_hostport.'\'');
82 4 ryan
		} else {
83 1680 darkviper
			if(!mysql_select_db($this->_db_name)) {
84
				throw new RuntimeException('unable to select database \''.$this->_db_name.
85
				                           '\' on \''.$this->_scheme.'://'.
86
				                           $this->_hostname.$this->_hostport.'\'');
87 4 ryan
			} else {
88
				$this->connected = true;
89
			}
90
		}
91
		return $this->connected;
92
	}
93
94
	// Disconnect from the database
95
	function disconnect() {
96 95 stefan
		if($this->connected==true) {
97 1680 darkviper
			mysql_close($this->_db_handle);
98 4 ryan
			return true;
99
		} else {
100
			return false;
101
		}
102
	}
103
104
	// Run a query
105
	function query($statement) {
106 1662 darkviper
		$this->iQueryCount++;
107 4 ryan
		$mysql = new mysql();
108 1680 darkviper
		$mysql->query($statement, $this->_db_handle);
109
		$this->set_error($mysql->error($this->_db_handle));
110
		if($mysql->error($this->_db_handle)) {
111 4 ryan
			return null;
112
		} else {
113
			return $mysql;
114
		}
115
	}
116 1362 Luisehahne
117 4 ryan
	// Gets the first column of the first row
118 1362 Luisehahne
	function get_one( $statement )
119
	{
120 1662 darkviper
		$this->iQueryCount++;
121 1680 darkviper
		$fetch_row = mysql_fetch_array(mysql_query($statement, $this->_db_handle));
122 4 ryan
		$result = $fetch_row[0];
123 1680 darkviper
		$this->set_error(mysql_error($this->_db_handle));
124
		if(mysql_error($this->_db_handle)) {
125 4 ryan
			return null;
126
		} else {
127
			return $result;
128
		}
129
	}
130
131
	// Set the DB error
132
	function set_error($message = null) {
133
		global $TABLE_DOES_NOT_EXIST, $TABLE_UNKNOWN;
134
		$this->error = $message;
135
		if(strpos($message, 'no such table')) {
136
			$this->error_type = $TABLE_DOES_NOT_EXIST;
137
		} else {
138
			$this->error_type = $TABLE_UNKNOWN;
139
		}
140
	}
141
142
	// Return true if there was an error
143
	function is_error() {
144
		return (!empty($this->error)) ? true : false;
145
	}
146
147
	// Return the error
148
	function get_error() {
149
		return $this->error;
150
	}
151
152 1613 darkviper
/**
153
 * default Getter for some properties
154
 * @param string $sPropertyName
155
 * @return mixed NULL on error or missing property
156 1362 Luisehahne
 */
157 1613 darkviper
	public function __get($sPropertyName)
158 1362 Luisehahne
	{
159 1613 darkviper
		switch ($sPropertyName):
160
			case 'db_handle':
161
			case 'DbHandle':
162 1662 darkviper
			case 'getDbHandle':
163 1680 darkviper
				$retval = $this->_db_handle;
164 1613 darkviper
				break;
165
			case 'db_name':
166
			case 'DbName':
167 1662 darkviper
			case 'getDbName':
168 1680 darkviper
				$retval = $this->_db_name;
169 1613 darkviper
				break;
170 1662 darkviper
			case 'getQueryCount':
171
				$retval = $this->iQueryCount;
172
				break;
173 1613 darkviper
			default:
174
				$retval = null;
175
				break;
176
		endswitch;
177
		return $retval;
178
	} // __get()
179 1362 Luisehahne
180
/*
181
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
182
 * @param string $field_name: name of the field to seek for
183
 * @return bool: true if field exists
184
 */
185
	public function field_exists($table_name, $field_name)
186
	{
187
		$sql = 'DESCRIBE `'.$table_name.'` `'.$field_name.'` ';
188 1680 darkviper
		$query = $this->query($sql, $this->_db_handle);
189 1362 Luisehahne
		return ($query->numRows() != 0);
190
	}
191
192
/*
193
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
194
 * @param string $index_name: name of the index to seek for
195
 * @return bool: true if field exists
196
 */
197
	public function index_exists($table_name, $index_name, $number_fields = 0)
198
	{
199
		$number_fields = intval($number_fields);
200
		$keys = 0;
201
		$sql = 'SHOW INDEX FROM `'.$table_name.'`';
202 1680 darkviper
		if( ($res_keys = $this->query($sql, $this->_db_handle)) )
203 1362 Luisehahne
		{
204
			while(($rec_key = $res_keys->fetchRow()))
205
			{
206
				if( $rec_key['Key_name'] == $index_name )
207
				{
208
					$keys++;
209
				}
210
			}
211
212
		}
213
		if( $number_fields == 0 )
214
		{
215
			return ($keys != $number_fields);
216
		}else
217
		{
218
			return ($keys == $number_fields);
219
		}
220
	}
221
/*
222
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
223
 * @param string $field_name: name of the field to add
224
 * @param string $description: describes the new field like ( INT NOT NULL DEFAULT '0')
225
 * @return bool: true if successful, otherwise false and error will be set
226
 */
227
	public function field_add($table_name, $field_name, $description)
228
	{
229 1442 Luisehahne
		if( !$this->field_exists($table_name, $field_name) )
230 1362 Luisehahne
		{ // add new field into a table
231
			$sql = 'ALTER TABLE `'.$table_name.'` ADD '.$field_name.' '.$description.' ';
232 1680 darkviper
			$query = $this->query($sql, $this->_db_handle);
233
			$this->set_error(mysql_error($this->_db_handle));
234 1362 Luisehahne
			if( !$this->is_error() )
235
			{
236 1442 Luisehahne
				return ( $this->field_exists($table_name, $field_name) ) ? true : false;
237 1362 Luisehahne
			}
238
		}else
239
		{
240
			$this->set_error('field \''.$field_name.'\' already exists');
241
		}
242
		return false;
243
	}
244
245
/*
246
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
247
 * @param string $field_name: name of the field to add
248
 * @param string $description: describes the new field like ( INT NOT NULL DEFAULT '0')
249
 * @return bool: true if successful, otherwise false and error will be set
250
 */
251
	public function field_modify($table_name, $field_name, $description)
252
	{
253
		$retval = false;
254 1486 DarkViper
		if( $this->field_exists($table_name, $field_name) )
255 1362 Luisehahne
		{ // modify a existing field in a table
256 1486 DarkViper
			$sql  = 'ALTER TABLE `'.$table_name.'` MODIFY `'.$field_name.'` '.$description;
257 1680 darkviper
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false);
258 1486 DarkViper
			$this->set_error(mysql_error());
259 1362 Luisehahne
		}
260 1486 DarkViper
		return $retval;
261 1362 Luisehahne
	}
262
263
/*
264
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
265
 * @param string $field_name: name of the field to remove
266
 * @return bool: true if successful, otherwise false and error will be set
267
 */
268
	public function field_remove($table_name, $field_name)
269
	{
270
		$retval = false;
271 1507 Luisehahne
		if( $this->field_exists($table_name, $field_name) )
272 1362 Luisehahne
		{ // modify a existing field in a table
273
			$sql  = 'ALTER TABLE `'.$table_name.'` DROP `'.$field_name.'`';
274 1680 darkviper
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false );
275 1362 Luisehahne
		}
276
		return $retval;
277
	}
278
279
/*
280
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
281
 * @param string $index_name: name of the new index
282
 * @param string $field_list: comma seperated list of fields for this index
283
 * @param string $index_type: kind of index (UNIQUE, PRIMARY, '')
284
 * @return bool: true if successful, otherwise false and error will be set
285
 */
286
	public function index_add($table_name, $index_name, $field_list, $index_type = '')
287
	{
288
		$retval = false;
289
		$field_list = str_replace(' ', '', $field_list);
290
		$field_list = explode(',', $field_list);
291
		$number_fields = sizeof($field_list);
292
		$field_list = '`'.implode('`,`', $field_list).'`';
293
		if( $this->index_exists($table_name, $index_name, $number_fields) ||
294
		    $this->index_exists($table_name, $index_name))
295
		{
296
			$sql  = 'ALTER TABLE `'.$table_name.'` ';
297
			$sql .= 'DROP INDEX `'.$index_name.'`';
298 1680 darkviper
			if( $this->query($sql, $this->_db_handle))
299 1362 Luisehahne
			{
300
				$sql  = 'ALTER TABLE `'.$table_name.'` ';
301
				$sql .= 'ADD '.$index_type.' `'.$index_name.'` ( '.$field_list.' ); ';
302 1680 darkviper
				if( $this->query($sql, $this->_db_handle)) { $retval = true; }
303 1362 Luisehahne
			}
304
		}
305
		return $retval;
306
	}
307
308
/*
309
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
310
 * @param string $field_name: name of the field to remove
311
 * @return bool: true if successful, otherwise false and error will be set
312
 */
313
	public function index_remove($table_name, $index_name)
314
	{
315
		$retval = false;
316
		if( $this->index_exists($table_name, $index_name) )
317
		{ // modify a existing field in a table
318
			$sql  = 'ALTER TABLE `'.$table_name.'` DROP INDEX `'.$index_name.'`';
319 1680 darkviper
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false );
320 1362 Luisehahne
		}
321
		return $retval;
322
	}
323 1586 darkviper
/**
324
 * Import a standard *.sql dump file
325
 * @param string $sSqlDump link to the sql-dumpfile
326
 * @param string $sTablePrefix
327 1591 darkviper
 * @param bool $bPreserve set to true will ignore all DROP TABLE statements
328 1586 darkviper
 * @param string $sTblEngine
329
 * @param string $sTblCollation
330
 * @return boolean true if import successful
331
 */
332
	public function SqlImport($sSqlDump,
333
	                          $sTablePrefix = '',
334 1591 darkviper
	                          $bPreserve = true,
335 1586 darkviper
	                          $sTblEngine = 'ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
336 1591 darkviper
	                          $sTblCollation = ' collate utf8_unicode_ci')
337 1586 darkviper
	{
338
		$retval = true;
339
		$this->error = '';
340
		$aSearch  = array('{TABLE_PREFIX}','{TABLE_ENGINE}', '{TABLE_COLLATION}');
341
		$aReplace = array($sTablePrefix, $sTblEngine, $sTblCollation);
342
		$sql = '';
343
		$aSql = file($sSqlDump);
344
		while ( sizeof($aSql) > 0 ) {
345
			$sSqlLine = trim(array_shift($aSql));
346 1591 darkviper
			if (!preg_match('/^[-\/]+.*/', $sSqlLine)) {
347 1592 darkviper
				$sql = $sql.' '.$sSqlLine;
348 1586 darkviper
				if ((substr($sql,-1,1) == ';')) {
349
					$sql = trim(str_replace( $aSearch, $aReplace, $sql));
350
					if (!($bPreserve && preg_match('/^\s*DROP TABLE IF EXISTS/siU', $sql))) {
351 1680 darkviper
						if(!mysql_query($sql, $this->_db_handle)) {
352 1586 darkviper
							$retval = false;
353 1680 darkviper
							$this->error = mysql_error($this->_db_handle);
354 1586 darkviper
							unset($aSql);
355
							break;
356
						}
357
					}
358
					$sql = '';
359
				}
360
			}
361
		}
362
		return $retval;
363
	}
364 1362 Luisehahne
365 1586 darkviper
/**
366
 * retuns the type of the engine used for requested table
367
 * @param string $table name of the table, including prefix
368
 * @return boolean/string false on error, or name of the engine (myIsam/InnoDb)
369
 */
370 1535 Luisehahne
	public function getTableEngine($table)
371
	{
372
		$retVal = false;
373 1680 darkviper
		$mysqlVersion = mysql_get_server_info($this->_db_handle);
374 1535 Luisehahne
		$engineValue = (version_compare($mysqlVersion, '5.0') < 0) ? 'Type' : 'Engine';
375 1680 darkviper
		$sql = "SHOW TABLE STATUS FROM " . $this->_db_name . " LIKE '" . $table . "'";
376
		if(($result = $this->query($sql, $this->_db_handle))) {
377 1535 Luisehahne
			if(($row = $result->fetchRow(MYSQL_ASSOC))) {
378
				$retVal = $row[$engineValue];
379
			}
380
		}
381
		return $retVal;
382
	}
383
384
385 1362 Luisehahne
} /// end of class database
386
387 1549 Luisehahne
define('MYSQL_SEEK_FIRST', 0);
388
define('MYSQL_SEEK_LAST', -1);
389
390 4 ryan
class mysql {
391
392 1680 darkviper
	private $result = null;
393
	private $_db_handle = null;
394 4 ryan
	// Run a query
395 1680 darkviper
	function query($statement, $dbHandle) {
396
		$this->_db_handle = $dbHandle;
397
		$this->result = mysql_query($statement, $this->_db_handle);
398
		$this->error = mysql_error($this->_db_handle);
399 4 ryan
		return $this->result;
400
	}
401
402
	// Fetch num rows
403
	function numRows() {
404
		return mysql_num_rows($this->result);
405
	}
406 1011 Ruebenwurz
407
	// Fetch row  $typ = MYSQL_ASSOC, MYSQL_NUM, MYSQL_BOTH
408
	function fetchRow($typ = MYSQL_BOTH) {
409
		return mysql_fetch_array($this->result, $typ);
410 4 ryan
	}
411 1011 Ruebenwurz
412 1549 Luisehahne
	function rewind()
413
	{
414
		return $this->seekRow();
415
	}
416
417
	function seekRow( $position = MYSQL_SEEK_FIRST )
418
	{
419
		$pmax = $this->numRows() - 1;
420
		$p = (($position < 0 || $position > $pmax) ? $pmax : $position);
421
		return mysql_data_seek($this->result, $p);
422
	}
423
424 4 ryan
	// Get error
425
	function error() {
426
		if(isset($this->error)) {
427
			return $this->error;
428
		} else {
429
			return null;
430
		}
431
	}
432
433
}
434 1364 Luisehahne
/* this function is placed inside this file temporarely until a better place is found */
435
/*  function to update a var/value-pair(s) in table ****************************
436
 *  nonexisting keys are inserted
437
 *  @param string $table: name of table to use (without prefix)
438
 *  @param mixed $key:    a array of key->value pairs to update
439
 *                        or a string with name of the key to update
440
 *  @param string $value: a sting with needed value, if $key is a string too
441
 *  @return bool:  true if any keys are updated, otherwise false
442
 */
443
	function db_update_key_value($table, $key, $value = '')
444
	{
445
		global $database;
446
		if( !is_array($key))
447
		{
448
			if( trim($key) != '' )
449
			{
450
				$key = array( trim($key) => trim($value) );
451
			} else {
452
				$key = array();
453
			}
454
		}
455
		$retval = true;
456
		foreach( $key as $index=>$val)
457
		{
458
			$index = strtolower($index);
459 1680 darkviper
			$sql = 'SELECT COUNT(`setting_id`) '
460
			     . 'FROM `'.TABLE_PREFIX.$table.'` '
461
			     . 'WHERE `name` = \''.$index.'\' ';
462 1364 Luisehahne
			if($database->get_one($sql))
463
			{
464
				$sql = 'UPDATE ';
465
				$sql_where = 'WHERE `name` = \''.$index.'\'';
466
			}else {
467
				$sql = 'INSERT INTO ';
468
				$sql_where = '';
469
			}
470
			$sql .= '`'.TABLE_PREFIX.$table.'` ';
471
			$sql .= 'SET `name` = \''.$index.'\', ';
472
			$sql .= '`value` = \''.$val.'\' '.$sql_where;
473
			if( !$database->query($sql) )
474
			{
475
				$retval = false;
476
			}
477
		}
478
		return $retval;
479
	}