Project

General

Profile

1
<?php
2
/**
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
 * @requirements    PHP 5.2.2 and higher
13
 * @version         $Id: Database.php 1682 2012-05-02 23:40:35Z darkviper $
14
 * @filesource      $HeadURL: svn://isteam.dynxs.de/wb-archiv/branches/2.8.x/wb/framework/Database.php $
15
 * @lastmodified    $Date: 2012-05-03 01:40:35 +0200 (Thu, 03 May 2012) $
16
 *
17
 */
18
/*
19
Database class
20
This class will be used to interface between the database
21
and the Website Baker code
22
*/
23
/* -------------------------------------------------------- */
24
// Must include code to stop this file being accessed directly
25
if(!defined('WB_PATH')) {
26
	require_once(dirname(__FILE__).'/globalExceptionHandler.php');
27
	throw new IllegalFileException();
28
}
29
/* -------------------------------------------------------- */
30
define('DATABASE_CLASS_LOADED', true);
31

    
32
class Database {
33

    
34
//	$sdb = 'mysql://user:password@demo.de:3306/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  = '3306';
42
	private $_db_name   = '';
43

    
44
	private $connected  = false;
45

    
46
	private $error      = '';
47
	private $error_type = '';
48
	private $message    = array();
49
	private $iQueryCount= 0;
50

    
51

    
52
	// Set DB_URL
53
	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
			throw new RuntimeException('Missing parameter: unable to connect database');
65
		}
66
		// Connect to database
67
		$this->connect();
68
	}
69
	
70
	// Connect to the database
71
	function connect() {
72
		$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
		} else {
79
			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
			} else {
84
				$this->connected = true;
85
			}
86
		}
87
		return $this->connected;
88
	}
89
	
90
	// Disconnect from the database
91
	function disconnect() {
92
		if($this->connected==true) {
93
			mysql_close($this->_db_handle);
94
			return true;
95
		} else {
96
			return false;
97
		}
98
	}
99
	
100
	// Run a query
101
	function query($statement) {
102
		$this->iQueryCount++;
103
		$mysql = new mysql();
104
		$mysql->query($statement, $this->_db_handle);
105
		$this->set_error($mysql->error($this->_db_handle));
106
		if($mysql->error($this->_db_handle)) {
107
			return null;
108
		} else {
109
			return $mysql;
110
		}
111
	}
112

    
113
	// Gets the first column of the first row
114
	function get_one( $statement )
115
	{
116
		$this->iQueryCount++;
117
		$fetch_row = mysql_fetch_array(mysql_query($statement, $this->_db_handle));
118
		$result = $fetch_row[0];
119
		$this->set_error(mysql_error($this->_db_handle));
120
		if(mysql_error($this->_db_handle)) {
121
			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
/**
149
 * default Getter for some properties
150
 * @param string $sPropertyName
151
 * @return mixed NULL on error or missing property
152
 */
153
	public function __get($sPropertyName)
154
	{
155
		switch ($sPropertyName):
156
			case 'db_handle':
157
			case 'DbHandle':
158
			case 'getDbHandle':
159
				$retval = $this->_db_handle;
160
				break;
161
			case 'db_name':
162
			case 'DbName':
163
			case 'getDbName':
164
				$retval = $this->_db_name;
165
				break;
166
			case 'getQueryCount':
167
				$retval = $this->iQueryCount;
168
				break;
169
			default:
170
				$retval = null;
171
				break;
172
		endswitch;
173
		return $retval;
174
	} // __get()
175

    
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
		$query = $this->query($sql, $this->_db_handle);
185
		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
		if( ($res_keys = $this->query($sql, $this->_db_handle)) )
199
		{
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
		if( !$this->field_exists($table_name, $field_name) )
226
		{ // add new field into a table
227
			$sql = 'ALTER TABLE `'.$table_name.'` ADD '.$field_name.' '.$description.' ';
228
			$query = $this->query($sql, $this->_db_handle);
229
			$this->set_error(mysql_error($this->_db_handle));
230
			if( !$this->is_error() )
231
			{
232
				return ( $this->field_exists($table_name, $field_name) ) ? true : false;
233
			}
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
		if( $this->field_exists($table_name, $field_name) )
251
		{ // modify a existing field in a table
252
			$sql  = 'ALTER TABLE `'.$table_name.'` MODIFY `'.$field_name.'` '.$description;
253
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false);
254
			$this->set_error(mysql_error());
255
		}
256
		return $retval;
257
	}
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
		if( $this->field_exists($table_name, $field_name) )
268
		{ // modify a existing field in a table
269
			$sql  = 'ALTER TABLE `'.$table_name.'` DROP `'.$field_name.'`';
270
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false );
271
		}
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
			if( $this->query($sql, $this->_db_handle))
295
			{
296
				$sql  = 'ALTER TABLE `'.$table_name.'` ';
297
				$sql .= 'ADD '.$index_type.' `'.$index_name.'` ( '.$field_list.' ); ';
298
				if( $this->query($sql, $this->_db_handle)) { $retval = true; }
299
			}
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
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false );
316
		}
317
		return $retval;
318
	}
319
/**
320
 * Import a standard *.sql dump file
321
 * @param string $sSqlDump link to the sql-dumpfile
322
 * @param string $sTablePrefix
323
 * @param bool $bPreserve set to true will ignore all DROP TABLE statements
324
 * @param string $sTblEngine
325
 * @param string $sTblCollation
326
 * @return boolean true if import successful
327
 */
328
	public function SqlImport($sSqlDump,
329
	                          $sTablePrefix = '',
330
	                          $bPreserve = true,
331
	                          $sTblEngine = 'ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
332
	                          $sTblCollation = ' collate utf8_unicode_ci')
333
	{
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
			if (!preg_match('/^[-\/]+.*/', $sSqlLine)) {
343
				$sql = $sql.' '.$sSqlLine;
344
				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
						if(!mysql_query($sql, $this->_db_handle)) {
348
							$retval = false;
349
							$this->error = mysql_error($this->_db_handle);
350
							unset($aSql);
351
							break;
352
						}
353
					}
354
					$sql = '';
355
				}
356
			}
357
		}
358
		return $retval;
359
	}
360

    
361
/**
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
	public function getTableEngine($table)
367
	{
368
		$retVal = false;
369
		$mysqlVersion = mysql_get_server_info($this->_db_handle);
370
		$engineValue = (version_compare($mysqlVersion, '5.0') < 0) ? 'Type' : 'Engine';
371
		$sql = "SHOW TABLE STATUS FROM " . $this->_db_name . " LIKE '" . $table . "'";
372
		if(($result = $this->query($sql, $this->_db_handle))) {
373
			if(($row = $result->fetchRow(MYSQL_ASSOC))) {
374
				$retVal = $row[$engineValue];
375
			}
376
		}
377
		return $retVal;
378
	}
379

    
380

    
381
} /// end of class database
382

    
383
define('MYSQL_SEEK_FIRST', 0);
384
define('MYSQL_SEEK_LAST', -1);
385

    
386
class mysql {
387

    
388
	private $result = null;
389
	private $_db_handle = null;
390
	// Run a query
391
	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
		return $this->result;
396
	}
397
	
398
	// Fetch num rows
399
	function numRows() {
400
		return mysql_num_rows($this->result);
401
	}
402

    
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
	}
407

    
408
	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
	// Get error
421
	function error() {
422
		if(isset($this->error)) {
423
			return $this->error;
424
		} else {
425
			return null;
426
		}
427
	}
428

    
429
}
430
/* 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
			$sql = 'SELECT COUNT(`setting_id`) '
456
			     . 'FROM `'.TABLE_PREFIX.$table.'` '
457
			     . 'WHERE `name` = \''.$index.'\' ';
458
			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
	}
(1-1/23)