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 1680 2012-05-02 22:17:37Z darkviper $
14
 * @filesource      $HeadURL: svn://isteam.dynxs.de/wb-archiv/branches/2.8.x/wb/framework/Database.php $
15
 * @lastmodified    $Date: 2012-05-03 00:17:37 +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: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
	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
			$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
		// Connect to database
71
		$this->connect();
72
	}
73
	
74
	// Connect to the database
75
	function connect() {
76
		$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
		} else {
83
			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
			} else {
88
				$this->connected = true;
89
			}
90
		}
91
		return $this->connected;
92
	}
93
	
94
	// Disconnect from the database
95
	function disconnect() {
96
		if($this->connected==true) {
97
			mysql_close($this->_db_handle);
98
			return true;
99
		} else {
100
			return false;
101
		}
102
	}
103
	
104
	// Run a query
105
	function query($statement) {
106
		$this->iQueryCount++;
107
		$mysql = new mysql();
108
		$mysql->query($statement, $this->_db_handle);
109
		$this->set_error($mysql->error($this->_db_handle));
110
		if($mysql->error($this->_db_handle)) {
111
			return null;
112
		} else {
113
			return $mysql;
114
		}
115
	}
116

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

    
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
		$query = $this->query($sql, $this->_db_handle);
189
		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
		if( ($res_keys = $this->query($sql, $this->_db_handle)) )
203
		{
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
		if( !$this->field_exists($table_name, $field_name) )
230
		{ // add new field into a table
231
			$sql = 'ALTER TABLE `'.$table_name.'` ADD '.$field_name.' '.$description.' ';
232
			$query = $this->query($sql, $this->_db_handle);
233
			$this->set_error(mysql_error($this->_db_handle));
234
			if( !$this->is_error() )
235
			{
236
				return ( $this->field_exists($table_name, $field_name) ) ? true : false;
237
			}
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
		if( $this->field_exists($table_name, $field_name) )
255
		{ // modify a existing field in a table
256
			$sql  = 'ALTER TABLE `'.$table_name.'` MODIFY `'.$field_name.'` '.$description;
257
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false);
258
			$this->set_error(mysql_error());
259
		}
260
		return $retval;
261
	}
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
		if( $this->field_exists($table_name, $field_name) )
272
		{ // modify a existing field in a table
273
			$sql  = 'ALTER TABLE `'.$table_name.'` DROP `'.$field_name.'`';
274
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false );
275
		}
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
			if( $this->query($sql, $this->_db_handle))
299
			{
300
				$sql  = 'ALTER TABLE `'.$table_name.'` ';
301
				$sql .= 'ADD '.$index_type.' `'.$index_name.'` ( '.$field_list.' ); ';
302
				if( $this->query($sql, $this->_db_handle)) { $retval = true; }
303
			}
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
			$retval = ( $this->query($sql, $this->_db_handle) ? true : false );
320
		}
321
		return $retval;
322
	}
323
/**
324
 * Import a standard *.sql dump file
325
 * @param string $sSqlDump link to the sql-dumpfile
326
 * @param string $sTablePrefix
327
 * @param bool $bPreserve set to true will ignore all DROP TABLE statements
328
 * @param string $sTblEngine
329
 * @param string $sTblCollation
330
 * @return boolean true if import successful
331
 */
332
	public function SqlImport($sSqlDump,
333
	                          $sTablePrefix = '',
334
	                          $bPreserve = true,
335
	                          $sTblEngine = 'ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
336
	                          $sTblCollation = ' collate utf8_unicode_ci')
337
	{
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
			if (!preg_match('/^[-\/]+.*/', $sSqlLine)) {
347
				$sql = $sql.' '.$sSqlLine;
348
				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
						if(!mysql_query($sql, $this->_db_handle)) {
352
							$retval = false;
353
							$this->error = mysql_error($this->_db_handle);
354
							unset($aSql);
355
							break;
356
						}
357
					}
358
					$sql = '';
359
				}
360
			}
361
		}
362
		return $retval;
363
	}
364

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

    
384

    
385
} /// end of class database
386

    
387
define('MYSQL_SEEK_FIRST', 0);
388
define('MYSQL_SEEK_LAST', -1);
389

    
390
class mysql {
391

    
392
	private $result = null;
393
	private $_db_handle = null;
394
	// Run a query
395
	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
		return $this->result;
400
	}
401
	
402
	// Fetch num rows
403
	function numRows() {
404
		return mysql_num_rows($this->result);
405
	}
406

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

    
412
	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
	// Get error
425
	function error() {
426
		if(isset($this->error)) {
427
			return $this->error;
428
		} else {
429
			return null;
430
		}
431
	}
432

    
433
}
434
/* 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
			$sql = 'SELECT COUNT(`setting_id`) '
460
			     . 'FROM `'.TABLE_PREFIX.$table.'` '
461
			     . 'WHERE `name` = \''.$index.'\' ';
462
			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
	}
(1-1/23)