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