Project

General

Profile

1 4 ryan
<?php
2 1362 Luisehahne
/**
3 1866 Luisehahne
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 1362 Luisehahne
 *
5 1866 Luisehahne
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9 1362 Luisehahne
 *
10 1866 Luisehahne
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 1362 Luisehahne
 */
18 1866 Luisehahne
/**
19
 * WbDatabase.php
20
 *
21
 * @category     Core
22
 * @package      Core_database
23 1998 darkviper
 * @author       Manuela v.d.Decken <manuela@isteam.de>
24 1866 Luisehahne
 * @author       Dietmar W. <dietmar.woellbrink@websitebaker.org>
25 1998 darkviper
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
26 1866 Luisehahne
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
27
 * @version      0.0.9
28
 * @revision     $Revision$
29
 * @lastmodified $Date$
30
 * @deprecated   from WB version number 2.9
31
 * @description  Mysql database wrapper for use with websitebaker up to version 2.8.4
32
 */
33
34 1496 DarkViper
/* -------------------------------------------------------- */
35 1885 Luisehahne
@define('DATABASE_CLASS_LOADED', true);
36 2104 darkviper
	/* define the old mysql consts for Backward compatibility */
37
	if (!defined('MYSQL_ASSOC'))
38
	{
39
		define('MYSQL_SEEK_LAST',            -1);
40
		define('MYSQL_SEEK_FIRST',            0);
41
		define('MYSQL_ASSOC',                 1);
42
		define('MYSQL_NUM',                   2);
43
		define('MYSQL_BOTH',                  3);
44
		define('MYSQL_CLIENT_COMPRESS',      32);
45
		define('MYSQL_CLIENT_IGNORE_SPACE', 256);
46
		define('MYSQL_CLIENT_INTERACTIVE', 1024);
47
		define('MYSQL_CLIENT_SSL',         2048);
48
	}
49 4 ryan
50 1686 darkviper
class WbDatabase {
51 1763 Luisehahne
52 1686 darkviper
	private static $_oInstances = array();
53 1680 darkviper
54 1998 darkviper
	protected $oDbHandle    = null; // readonly from outside
55
	protected $sDbName      = '';
56
	protected $sInstanceIdentifier = '';
57 1885 Luisehahne
	protected $sTablePrefix = '';
58 1889 Luisehahne
	protected $sCharset     = '';
59 1885 Luisehahne
	protected $connected    = false;
60
	protected $error        = '';
61
	protected $error_type   = '';
62
	protected $iQueryCount  = 0;
63 1362 Luisehahne
64 1998 darkviper
/**
65
 * __constructor
66
 *  prevent from public instancing
67
 */
68 2104 darkviper
	final private function  __construct() {}
69 1998 darkviper
/**
70
 * prevent from cloning
71
 */
72 2104 darkviper
	final private function __clone() {}
73 1683 darkviper
/**
74 1686 darkviper
 * get a valid instance of this class
75
 * @param string $sIdentifier selector for several different instances
76 1998 darkviper
 * @return WbDatabase object
77 1686 darkviper
 */
78 2104 darkviper
	final public static function getInstance($sIdentifier = 'core')
79 1998 darkviper
	{
80 1686 darkviper
		if( !isset(self::$_oInstances[$sIdentifier])) {
81
            $c = __CLASS__;
82 1974 darkviper
			$oInstance = new $c;
83 1998 darkviper
			$oInstance->sInstanceIdentifier = $sIdentifier;
84 1974 darkviper
            self::$_oInstances[$sIdentifier] = $oInstance;
85 1686 darkviper
		}
86
		return self::$_oInstances[$sIdentifier];
87
	}
88
/**
89
 * disconnect and kills an existing instance
90 1998 darkviper
 * @param string $sIdentifier selector for instance to kill
91 1686 darkviper
 */
92 2104 darkviper
	final public static function killInstance($sIdentifier)
93 1998 darkviper
	{
94 1686 darkviper
		if($sIdentifier != 'core') {
95
			if( isset(self::$_oInstances[$sIdentifier])) {
96
				self::$_oInstances[$sIdentifier]->disconnect();
97
				unset(self::$_oInstances[$sIdentifier]);
98
			}
99
		}
100
	}
101
/**
102 1998 darkviper
 * Establish connection
103 1683 darkviper
 * @param string $url
104
 * @return bool
105 1998 darkviper
 * @throws WbDatabaseException
106
 * @description opens a connection using connect URL<br />
107
 *              Example for SQL-Url:  'mysql://user:password@example.com[:3306]/database?charset=utf8&tableprefix=xx_'
108 1683 darkviper
 */
109 1998 darkviper
	public function doConnect($url = '')
110
	{
111
		if ($this->connected) { return $this->connected; } // prevent from reconnecting
112 1885 Luisehahne
		$this->connected = false;
113 1998 darkviper
		if ($url != '') {
114
		// parse URL and extract connection data
115 1680 darkviper
			$aIni = parse_url($url);
116 1866 Luisehahne
			$scheme   = isset($aIni['scheme']) ? $aIni['scheme'] : 'mysql';
117
			$hostname = isset($aIni['host']) ? $aIni['host'] : '';
118
			$username = isset($aIni['user']) ? $aIni['user'] : '';
119
			$password = isset($aIni['pass']) ? $aIni['pass'] : '';
120
			$hostport = isset($aIni['port']) ? $aIni['port'] : '3306';
121 2104 darkviper
			$hostport = $hostport == '3306' ? null : $hostport;
122 1866 Luisehahne
			$db_name  = ltrim(isset($aIni['path']) ? $aIni['path'] : '', '/\\');
123 1885 Luisehahne
			$sTmp = isset($aIni['query']) ? $aIni['query'] : '';
124
			$aQuery = explode('&', $sTmp);
125 1998 darkviper
			foreach ($aQuery as $sArgument) {
126 1885 Luisehahne
				$aArg = explode('=', $sArgument);
127 1998 darkviper
				switch (strtolower($aArg[0])) {
128 1885 Luisehahne
					case 'charset':
129
						$this->sCharset = strtolower(preg_replace('/[^a-z0-9]/i', '', $aArg[1]));
130
						break;
131
					case 'tableprefix':
132
						$this->sTablePrefix = $aArg[1];
133
						break;
134
					default:
135
						break;
136
				}
137
			}
138 1998 darkviper
			$this->sDbName = $db_name;
139
		} else {
140 1885 Luisehahne
			throw new WbDatabaseException('Missing parameter: unable to connect database');
141 1680 darkviper
		}
142 2104 darkviper
		$this->oDbHandle = @mysqli_connect($hostname, $username, $password, $db_name, $hostport);
143 1998 darkviper
		if (!$this->oDbHandle) {
144 2104 darkviper
			throw new WbDatabaseException('unable to connect \''.$scheme.'://'.$hostname.':'.$hostport.'\'');
145 4 ryan
		} else {
146 2104 darkviper
            if ($this->sCharset) {
147
                @mysqli_query($this->oDbHandle, 'SET NAMES \''.$this->sCharset.'\'');
148
            }
149
            $this->connected = true;
150 4 ryan
		}
151
		return $this->connected;
152
	}
153 1998 darkviper
/**
154
 * disconnect database
155
 * @return bool
156
 * @description Disconnect current object from the database<br />
157
 *              the 'core' connection can NOT be disconnected!
158
 */
159
	public function disconnect()
160
	{
161
		if ($this->connected == true && $oInstance->sInstanceIdentifier != 'core') {
162 2104 darkviper
			mysqli_close($this->oDbHandle);
163 1974 darkviper
			$this->connected = false;
164 4 ryan
			return true;
165
		}
166 1974 darkviper
		return false;
167 4 ryan
	}
168 1998 darkviper
/**
169
 * Alias for doQuery()
170 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
171 1998 darkviper
 */
172
	public function query($statement)
173
	{
174
		return $this->doQuery($statement);
175
	}
176
/**
177
 * execute query
178
 * @param string $statement the SQL-statement to execute
179
 * @return null|\mysql
180
 */
181
	public function doQuery($statement) {
182 1662 darkviper
		$this->iQueryCount++;
183 2104 darkviper
		$mysql = new mysql($this->oDbHandle);
184
		$mysql->query($statement);
185 1998 darkviper
		$this->set_error($mysql->error($this->oDbHandle));
186 2104 darkviper
		if ($mysql->error()) {
187 4 ryan
			return null;
188
		} else {
189
			return $mysql;
190
		}
191
	}
192 1998 darkviper
/**
193
 * Alias for getOne()
194 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
195 1998 darkviper
 */
196 1686 darkviper
	public function get_one( $statement )
197 1362 Luisehahne
	{
198 1998 darkviper
		return $this->getOne($statement);
199
	}
200
	// Gets the first column of the first row
201
/**
202
 * Gets the first column of the first row
203
 * @param string $statement  SQL-statement
204
 * @return null|mixed
205
 */
206
	public function getOne( $statement )
207
	{
208 1662 darkviper
		$this->iQueryCount++;
209 2104 darkviper
		$fetch_row = mysqli_fetch_array(mysqli_query($this->oDbHandle, $statement));
210 4 ryan
		$result = $fetch_row[0];
211 2104 darkviper
		$this->set_error(null);
212
		if (mysqli_error($this->oDbHandle)) {
213
    		$this->set_error(mysqli_error($this->oDbHandle));
214 4 ryan
			return null;
215
		} else {
216
			return $result;
217
		}
218
	}
219 1998 darkviper
/**
220
 * Alias for setError()
221 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
222 1998 darkviper
 */
223
	public function set_error($message = null)
224
	{
225
		$this->setError($message = null);
226
	}
227 4 ryan
	// Set the DB error
228 1998 darkviper
/**
229
 * setError
230
 * @param string $message
231
 */
232
	public function setError($message = null)
233
	{
234 4 ryan
		$this->error = $message;
235
	}
236 1998 darkviper
/**
237
 * Alias for isError
238 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
239 1998 darkviper
 */
240
	public function is_error()
241
	{
242
		return $this->isError();
243
	}
244
/**
245
 * isError
246
 * @return bool
247
 */
248
	public function isError()
249
	{
250 4 ryan
		return (!empty($this->error)) ? true : false;
251
	}
252 1998 darkviper
/**
253
 * Alias for getError
254 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
255 1998 darkviper
 */
256
	public function get_error()
257
	{
258
		return $this->getError();
259
	}
260
/**
261
 * get last Error
262
 * @return string
263
 */
264
	public function getError()
265
	{
266 4 ryan
		return $this->error;
267
	}
268 1613 darkviper
/**
269 1885 Luisehahne
 * Protect class from property injections
270
 * @param string name of property
271
 * @param mixed value
272
 * @throws WbDatabaseException
273 1866 Luisehahne
 */
274 1998 darkviper
	public function __set($name, $value)
275
	{
276 1885 Luisehahne
		throw new WbDatabaseException('tried to set a readonly or nonexisting property ['.$name.']!! ');
277 1866 Luisehahne
	}
278
/**
279 1613 darkviper
 * default Getter for some properties
280 1866 Luisehahne
 * @param string name of the Property
281 1998 darkviper
 * @return NULL on error | valid property
282 1362 Luisehahne
 */
283 1613 darkviper
	public function __get($sPropertyName)
284 1362 Luisehahne
	{
285 1998 darkviper
		switch ($sPropertyName) {
286 1613 darkviper
			case 'DbHandle':
287 1998 darkviper
			case 'getDbHandle': // << set deprecated
288
			case 'db_handle': // << set deprecated
289
				$retval = $this->oDbHandle;
290 1613 darkviper
				break;
291 1866 Luisehahne
			case 'LastInsertId':
292 1998 darkviper
			case 'getLastInsertId': // << set deprecated
293 2104 darkviper
				$retval = $this->getLastInsertId();
294 1866 Luisehahne
				break;
295 1613 darkviper
			case 'DbName':
296 1998 darkviper
			case 'getDbName': // << set deprecated
297
			case 'db_name': // << set deprecated
298
				$retval = $this->sDbName;
299 1613 darkviper
				break;
300 1885 Luisehahne
			case 'TablePrefix':
301 1998 darkviper
			case 'getTablePrefix': // << set deprecated
302 1885 Luisehahne
				$retval = $this->sTablePrefix;
303
				break;
304 1974 darkviper
			case 'QueryCount':
305 1998 darkviper
			case 'getQueryCount': // << set deprecated
306 1662 darkviper
				$retval = $this->iQueryCount;
307
				break;
308 1613 darkviper
			default:
309
				$retval = null;
310
				break;
311 1998 darkviper
		}
312 1613 darkviper
		return $retval;
313
	} // __get()
314 1885 Luisehahne
/**
315
 * Escapes special characters in a string for use in an SQL statement
316
 * @param string $unescaped_string
317
 * @return string
318
 */
319
	public function escapeString($unescaped_string)
320
	{
321 2104 darkviper
		return mysqli_real_escape_string($this->oDbHandle, $unescaped_string);
322 1885 Luisehahne
	}
323
/**
324
 * Last inserted Id
325
 * @return bool|int false on error, 0 if no record inserted
326
 */
327
	public function getLastInsertId()
328
	{
329 2104 darkviper
		return mysqli_insert_id($this->oDbHandle);
330 1885 Luisehahne
	}
331 1998 darkviper
/**
332
 * Alias for isField()
333 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
334 1998 darkviper
 */
335
	public function field_exists($table_name, $field_name)
336
	{
337
		return $this->isField($table_name, $field_name);
338
	}
339 1362 Luisehahne
/*
340 1866 Luisehahne
 * @param string full name of the table (incl. TABLE_PREFIX)
341
 * @param string name of the field to seek for
342
 * @return bool true if field exists
343 1362 Luisehahne
 */
344 1998 darkviper
	public function isField($table_name, $field_name)
345 1362 Luisehahne
	{
346
		$sql = 'DESCRIBE `'.$table_name.'` `'.$field_name.'` ';
347 2104 darkviper
		$query = $this->doQuery($sql);
348 1362 Luisehahne
		return ($query->numRows() != 0);
349
	}
350 1998 darkviper
/**
351
 * Alias for isIndex()
352 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
353 1998 darkviper
 */
354
	public function index_exists($table_name, $index_name, $number_fields = 0)
355
	{
356
		return $this->isIndex($table_name, $index_name, $number_fields = 0);
357
	}
358 1362 Luisehahne
/*
359 1998 darkviper
 * isIndex
360 1866 Luisehahne
 * @param string full name of the table (incl. TABLE_PREFIX)
361
 * @param string name of the index to seek for
362
 * @return bool true if field exists
363 1362 Luisehahne
 */
364 1998 darkviper
	public function isIndex($table_name, $index_name, $number_fields = 0)
365 1362 Luisehahne
	{
366
		$number_fields = intval($number_fields);
367
		$keys = 0;
368
		$sql = 'SHOW INDEX FROM `'.$table_name.'`';
369 2104 darkviper
		if (($res_keys = $this->doQuery($sql))) {
370 1998 darkviper
			while (($rec_key = $res_keys->fetchRow(MYSQL_ASSOC))) {
371
				if ( $rec_key['Key_name'] == $index_name ) {
372 1362 Luisehahne
					$keys++;
373
				}
374
			}
375
376
		}
377 1998 darkviper
		if ( $number_fields == 0 ) {
378 1362 Luisehahne
			return ($keys != $number_fields);
379 1998 darkviper
		} else {
380 1362 Luisehahne
			return ($keys == $number_fields);
381
		}
382
	}
383 1998 darkviper
/**
384
 * Alias for addField()
385 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
386 1998 darkviper
 */
387
	public function field_add($table_name, $field_name, $description)
388
	{
389
		return $this->addField($table_name, $field_name, $description);
390
	}
391 1362 Luisehahne
/*
392 1866 Luisehahne
 * @param string full name of the table (incl. TABLE_PREFIX)
393
 * @param string name of the field to add
394
 * @param string describes the new field like ( INT NOT NULL DEFAULT '0')
395
 * @return bool true if successful, otherwise false and error will be set
396 1362 Luisehahne
 */
397 1998 darkviper
	public function addField($table_name, $field_name, $description)
398 1362 Luisehahne
	{
399 1998 darkviper
		if (!$this->isField($table_name, $field_name)) {
400
		// add new field into a table
401 1362 Luisehahne
			$sql = 'ALTER TABLE `'.$table_name.'` ADD '.$field_name.' '.$description.' ';
402 2104 darkviper
			$query = $this->doQuery($sql);
403
			$this->set_error(mysqli_error($this->oDbHandle));
404 1998 darkviper
			if (!$this->isError()) {
405
				return ( $this->isField($table_name, $field_name) ) ? true : false;
406 1362 Luisehahne
			}
407 1998 darkviper
		} else {
408 1362 Luisehahne
			$this->set_error('field \''.$field_name.'\' already exists');
409
		}
410
		return false;
411
	}
412 1998 darkviper
/**
413
 * Alias for modifyField()
414 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
415 1998 darkviper
 */
416
	public function field_modify($table_name, $field_name, $description)
417
	{
418
		return $this->modifyField($table_name, $field_name, $description);
419
	}
420 1362 Luisehahne
/*
421
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
422
 * @param string $field_name: name of the field to add
423
 * @param string $description: describes the new field like ( INT NOT NULL DEFAULT '0')
424
 * @return bool: true if successful, otherwise false and error will be set
425
 */
426 1998 darkviper
	public function modifyField($table_name, $field_name, $description)
427 1362 Luisehahne
	{
428
		$retval = false;
429 1998 darkviper
		if ($this->isField($table_name, $field_name)) {
430
		// modify a existing field in a table
431 1486 DarkViper
			$sql  = 'ALTER TABLE `'.$table_name.'` MODIFY `'.$field_name.'` '.$description;
432 2104 darkviper
			$retval = ( $this->doQuery($sql) ? true : false);
433
			$this->setError(mysqli_error($this->oDbHandle));
434 1362 Luisehahne
		}
435 1486 DarkViper
		return $retval;
436 1362 Luisehahne
	}
437 1998 darkviper
/**
438
 * Alias for removeField()
439 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
440 1998 darkviper
 */
441
	public function field_remove($table_name, $field_name)
442
	{
443
		return $this->removeField($table_name, $field_name);
444
	}
445 1362 Luisehahne
/*
446
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
447
 * @param string $field_name: name of the field to remove
448
 * @return bool: true if successful, otherwise false and error will be set
449
 */
450 1998 darkviper
	public function removeField($table_name, $field_name)
451 1362 Luisehahne
	{
452
		$retval = false;
453 1998 darkviper
		if ($this->isField($table_name, $field_name)) {
454
		// modify a existing field in a table
455 1362 Luisehahne
			$sql  = 'ALTER TABLE `'.$table_name.'` DROP `'.$field_name.'`';
456 1998 darkviper
			$retval = ( $this->doQuery($sql, $this->oDbHandle) ? true : false );
457 1362 Luisehahne
		}
458
		return $retval;
459
	}
460 1998 darkviper
/**
461
 * Alias for addIndex()
462 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
463 1998 darkviper
 */
464
    public function index_add($table_name, $index_name, $field_list, $index_type = 'KEY')
465
	{
466
		return $this->addIndex($table_name, $index_name, $field_list, $index_type);
467
	}
468 1362 Luisehahne
/*
469
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
470 1763 Luisehahne
 * @param string $index_name: name of the new index (empty string for PRIMARY)
471 1362 Luisehahne
 * @param string $field_list: comma seperated list of fields for this index
472 1763 Luisehahne
 * @param string $index_type: kind of index (PRIMARY, UNIQUE, KEY, FULLTEXT)
473 1362 Luisehahne
 * @return bool: true if successful, otherwise false and error will be set
474
 */
475 1998 darkviper
     public function addIndex($table_name, $index_name, $field_list, $index_type = 'KEY')
476 1763 Luisehahne
     {
477
        $retval = false;
478 1885 Luisehahne
        $field_list = explode(',', (str_replace(' ', '', $field_list)));
479 1763 Luisehahne
        $number_fields = sizeof($field_list);
480
        $field_list = '`'.implode('`,`', $field_list).'`';
481
        $index_name = $index_type == 'PRIMARY' ? $index_type : $index_name;
482 1998 darkviper
        if ( $this->isIndex($table_name, $index_name, $number_fields) ||
483
             $this->isIndex($table_name, $index_name))
484 1763 Luisehahne
        {
485
            $sql  = 'ALTER TABLE `'.$table_name.'` ';
486
            $sql .= 'DROP INDEX `'.$index_name.'`';
487 2104 darkviper
            if (!$this->doQuery($sql)) { return false; }
488 1763 Luisehahne
        }
489
        $sql  = 'ALTER TABLE `'.$table_name.'` ';
490
        $sql .= 'ADD '.$index_type.' ';
491
        $sql .= $index_type == 'PRIMARY' ? 'KEY ' : '`'.$index_name.'` ';
492
        $sql .= '( '.$field_list.' ); ';
493 2104 darkviper
        if ($this->doQuery($sql)) { $retval = true; }
494 1763 Luisehahne
        return $retval;
495
    }
496 1998 darkviper
/**
497
 * Alias for removeIndex()
498 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
499 1998 darkviper
 */
500
	public function index_remove($table_name, $index_name)
501
	{
502
		return $this->removeIndex($table_name, $index_name);
503
	}
504 1362 Luisehahne
/*
505
 * @param string $table_name: full name of the table (incl. TABLE_PREFIX)
506
 * @param string $field_name: name of the field to remove
507
 * @return bool: true if successful, otherwise false and error will be set
508
 */
509 1998 darkviper
	public function removeIndex($table_name, $index_name)
510 1362 Luisehahne
	{
511
		$retval = false;
512 1998 darkviper
		if ($this->isIndex($table_name, $index_name)) {
513
		// modify a existing field in a table
514 1362 Luisehahne
			$sql  = 'ALTER TABLE `'.$table_name.'` DROP INDEX `'.$index_name.'`';
515 2104 darkviper
			$retval = ( $this->doQuery($sql) ? true : false );
516 1362 Luisehahne
		}
517
		return $retval;
518
	}
519 1586 darkviper
/**
520 1998 darkviper
 * Alias for importSql()
521 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
522 1998 darkviper
 */
523
	public function SqlImport($sSqlDump,
524
	                          $sTablePrefix = '',
525 2104 darkviper
	                          $sAction      = 'install',
526 1998 darkviper
	                          $sEngine      = 'MyISAM',
527
	                          $sCollation   = 'utf8_unicode_ci')
528
	{
529
		return $this->importSql($sSqlDump, $sTablePrefix, $bPreserve, $sEngine, $sCollation);
530
	}
531
/**
532 2104 darkviper
 * Import an SQl-Dumpfile witch can include unlimited placeholders for values
533
 * @param mixed  $mSqlDump      can be string with filename or array with additional vars
534
 * @param string $sTablePrefix  can be used to override settings from WbDatabase object
535
 * @param string $sAction       'install', 'uninstall', 'upgrade', 'repair
536
 * @param string $sEngine       kind of table engine: MyIsam(default)
537
 * @param string $sCollation    utf8_unicode_ci(default)
538
 * @return bool  false on error
539 1586 darkviper
 */
540 2104 darkviper
	public function importSql(
541
        $mSqlDump,
542
        $sTablePrefix = '',               // can override settings from WbDatabase object
543
        $sAction      = 'install',        // skip 'DROP TABLE' statements
544
        $sEngine      = 'MyISAM',         // the default table engine
545
        $sCollation   = 'utf8_unicode_ci' // the default collation to use
546
    )
547
    {
548 1586 darkviper
		$retval = true;
549
		$this->error = '';
550 2104 darkviper
        // sanitize arguments
551
        if (! is_string($sAction)) {
552
            $sAction = $sAction ? 'repair' : 'install';
553
        }
554
        $aAllowedActions = array('install', 'uninstall', 'upgrade', 'repair');
555
        $sAction = strtolower(preg_replace('/^.*?('.implode('|', $aAllowedActions).')(\.php)?$/iU', '$1', $sAction));
556
        $sAction = (in_array($sAction, $aAllowedActions) ? $sAction : 'install');
557
        $sTablePrefix = trim($sTablePrefix);
558
        $aEngineTypes = array(
559
            'csv'        => 'CSV',
560
            'blackhole'  => 'BLACKHOLE',
561
            'memory'     => 'MEMORY',
562
            'myisam'     => 'MyISAM',
563
            'innodb'     => 'InnoDB',
564
            'archive'    => 'ARCHIVE',
565
            'mrg_myisam' => 'MRG_MYISAM'
566
        );
567
        if (isset($aEngineTypes[strtolower($sEngine)])) {
568
            $sEngine = $aEngineTypes[strtolower($sEngine)];
569
        } else {
570
            $sEngine = 'MyISAM';
571
        }
572
        // test if selected collation is available. Otherwise select 'utf8_unicode_ci'
573
        $sql = 'SELECT COUNT(*) FROM `COLLATIONS` '
574
             . 'WHERE `COLLATION_NAME`=\''.$sCollation.'\'';
575
        $sCollation = ($this->get_one($sql) ? $sCollation : 'utf8_unicode_ci');
576
        $aTmp = preg_split('/_/', $sCollation, null, PREG_SPLIT_NO_EMPTY);
577
        $sCharset = $aTmp[0];
578
        // define array of searches
579
        $aSearch  = array(
580
            '/\{TABLE_PREFIX\}/',
581
            '/\{TABLE_COLLATION\}/', // deprecated from 2.8.4
582
            '/\{FIELD_COLLATION\}/', // deprecated from 2.8.4
583
            '/\{TABLE_ENGINE\}/',
584
            '/\{TABLE_ENGINE=([a-zA-Z_0-9]*)\}/',
585
            '/\{CHARSET\}/',
586
            '/\{COLLATION\}/'
587
        );
588
        // define array of replacements
589
        $aReplace = array(
590
            $sTablePrefix,
591
            ' COLLATE {COLLATION}', // deprecated from 2.8.4
592
            ' COLLATE {COLLATION}', // deprecated from 2.8.4
593
            ' {ENGINE='.$sEngine.'}',
594
            ' ENGINE=$1 DEFAULT CHARSET={CHARSET} COLLATION={COLLATION}',
595
            $sCharset,
596
            $sCollation
597
        );
598
599
        if (is_array($mSqlDump)) {
600
            // try to get dumpfile name
601
            if (!isset($mSqlDump['sSqlDump'])) {
602
                $this->error = 'missing index \'sSqlDump\' in $mSqlDump';
603
                return false;
604
            } else {
605
            // get dumpfile name from array and then remove entry
606
                $sDumpFile = (string)$mSqlDump['sSqlDump'];
607
                unset($mSqlDump['sSqlDump']);
608
                // import all vars and it's values from array
609
                foreach ($mSqlDump as $sIndex => $sValue) {
610
                    // transform varname into placeholder name ('sPageTitle' => 'PAGE_TITLE')
611
                    $sIndex = strtoupper(preg_replace('/([a-z0-9])([A-Z])/', '\1_\2', ltrim($sIndex, 'a..z')));
612
                    // fill search/replace arrays
613
                    $aSearch[]  = '/\{'.$sIndex.'\}/';
614
                    $aReplace[] = $sValue ;
615
                }
616
            }
617
        } elseif (is_string($mSqlDump)) {
618
            $sDumpFile = (string)$mSqlDump;
619
        } else {
620
            $this->error = 'invalid argument $mSqlDump';
621
            return false;
622
        }
623
        if (!is_readable($sDumpFile)) {
624
            $this->Error = 'unable to open \''.$sDumpFile.'\'';
625
            return false;
626
        }
627 1586 darkviper
		$sql = '';
628 2104 darkviper
		$aSql = file($sDumpFile, FILE_SKIP_EMPTY_LINES);
629
        //	remove possible ByteOrderMark
630 1897 Luisehahne
		$aSql[0] = preg_replace('/^[\xAA-\xFF]{3}/', '', $aSql[0]);
631 1998 darkviper
		while (sizeof($aSql) > 0) {
632 1586 darkviper
			$sSqlLine = trim(array_shift($aSql));
633 1591 darkviper
			if (!preg_match('/^[-\/]+.*/', $sSqlLine)) {
634 1592 darkviper
				$sql = $sql.' '.$sSqlLine;
635 1586 darkviper
				if ((substr($sql,-1,1) == ';')) {
636 2104 darkviper
					$sql = trim(preg_replace($aSearch, $aReplace, $sql));
637
                    $sAvailSqlObjects = 'TABLE|VIEW|INDEX|PROCEDURE|FUNCTION|TRIGGER|EVENT';
638
                    switch ($sAction) {
639
                        case 'uninstall': // skip CREATE; execute DROP
640
                            if (preg_match('/^\s*CREATE ('.$sAvailSqlObjects.') /siU', $sql)) {
641
                                $sql = '';
642
                                continue; // read next statement
643
                            }
644
                            break;
645
                        case 'upgrade': // skip DROP; execute CREATE
646
                        case 'repair':  // skip DROP; execute CREATE
647
                            if (preg_match('/^\s*DROP ('.$sAvailSqlObjects.') /siU', $sql)) {
648
                                $sql = '';
649
                                continue; // read next statement
650
                            }
651
                            break;
652
                        default: // install:  execute DROP; execute CREATE
653
                            break;
654
                    }
655
                    if (!$this->doQuery($sql)) {
656
                        $retval = false;
657
                        $this->error = $this->getError();
658
                        unset($aSql);
659
                        break;
660
                    }
661 1586 darkviper
					$sql = '';
662
				}
663
			}
664
		}
665
		return $retval;
666 2104 darkviper
    } // end of function importSql()
667 1586 darkviper
/**
668
 * retuns the type of the engine used for requested table
669
 * @param string $table name of the table, including prefix
670
 * @return boolean/string false on error, or name of the engine (myIsam/InnoDb)
671
 */
672 1535 Luisehahne
	public function getTableEngine($table)
673
	{
674
		$retVal = false;
675 2104 darkviper
		$mysqlVersion = mysqli_get_server_info($this->oDbHandle);
676 1535 Luisehahne
		$engineValue = (version_compare($mysqlVersion, '5.0') < 0) ? 'Type' : 'Engine';
677 1998 darkviper
		$sql = 'SHOW TABLE STATUS FROM `' . $this->sDbName . '` LIKE \'' . $table . '\'';
678 2104 darkviper
		if (($result = $this->doQuery($sql))) {
679 1998 darkviper
			if (($row = $result->fetchRow(MYSQL_ASSOC))) {
680 1535 Luisehahne
				$retVal = $row[$engineValue];
681
			}
682
		}
683
		return $retVal;
684
	}
685
686
687 1362 Luisehahne
} /// end of class database
688 1885 Luisehahne
// //////////////////////////////////////////////////////////////////////////////////// //
689
/**
690
 * WbDatabaseException
691
 *
692
 * @category     Core
693
 * @package      Core_database
694 1998 darkviper
 * @author       Manuela v.d.Decken <manuela@isteam.de>
695
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
696 1885 Luisehahne
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
697
 * @version      2.9.0
698
 * @revision     $Revision$
699
 * @lastmodified $Date$
700
 * @description  Exceptionhandler for the WbDatabase and depending classes
701
 */
702
class WbDatabaseException extends AppException {}
703 1362 Luisehahne
704 1998 darkviper
/* extend global constants of mysql */
705
if(!defined('MYSQL_SEEK_FIRST')) { define('MYSQL_SEEK_FIRST', 0); }
706
if(!defined('MYSQL_SEEK_LAST')) { define('MYSQL_SEEK_LAST', -1); }
707 1549 Luisehahne
708 1998 darkviper
/**
709
 * mysql
710
 *
711
 * @category     Core
712
 * @package      Core_database
713
 * @author       Manuela v.d.Decken <manuela@isteam.de>
714
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
715
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
716
 * @version      2.9.0
717
 * @revision     $Revision$
718
 * @lastmodified $Date$
719
 * @description  MYSQL result object for requests
720
 *
721
 */
722 4 ryan
class mysql {
723
724 2104 darkviper
	private $result    = null;
725 2011 darkviper
	private $oDbHandle = null;
726 2104 darkviper
    private $error     = '';
727 1998 darkviper
728 2104 darkviper
    public function __construct($oHandle)
729
    {
730
        $this->oDbHandle = $oHandle;
731
    }
732 1998 darkviper
/**
733
 * query sql statement
734
 * @param  string $statement
735
 * @return object
736
 * @throws WbDatabaseException
737
 */
738 2104 darkviper
	function query($sStatement)
739 1998 darkviper
	{
740 2104 darkviper
		$this->result = @mysqli_query($this->oDbHandle, $sStatement);
741 1998 darkviper
		if ($this->result === false) {
742
			if (DEBUG) {
743 2104 darkviper
				throw new WbDatabaseException(mysqli_error($this->oDbHandle));
744 1998 darkviper
			} else {
745 1889 Luisehahne
				throw new WbDatabaseException('Error in SQL-Statement');
746
			}
747
		}
748 2104 darkviper
		$this->error = mysqli_error($this->oDbHandle);
749 4 ryan
		return $this->result;
750
	}
751 1998 darkviper
/**
752
 * numRows
753
 * @return integer
754
 * @description number of returned records
755
 */
756
	function numRows()
757
	{
758 2104 darkviper
		return mysqli_num_rows($this->result);
759 4 ryan
	}
760 1998 darkviper
/**
761
 * fetchRow
762
 * @param  int $typ MYSQL_BOTH(default) | MYSQL_ASSOC | MYSQL_NUM
763
 * @return array
764
 * @description get current record and increment pointer
765
 */
766
	function fetchRow($typ = MYSQL_BOTH)
767
	{
768 2104 darkviper
		return mysqli_fetch_array($this->result, $typ);
769 4 ryan
	}
770 1998 darkviper
/**
771
 * fetchObject
772
 * @param  string $sClassname Name of the class to use. Is no given use stdClass
773
 * @param  string $aParams    optional array of arguments for the constructor
774
 * @return object
775
 * @description get current record as an object and increment pointer
776
 */
777
	function fetchObject($sClassName = null, array $aParams = null)
778
	{
779 2011 darkviper
		if ($sClassName === null || class_exists($sClassName)) {
780 2104 darkviper
			return mysqli_fetch_object($this->result, $sClassName, $aParams);
781 2011 darkviper
		} else {
782
			throw new WbDatabaseException('Class <'.$sClassName.'> not available on request of mysql_fetch_object()');
783
		}
784 1998 darkviper
	}
785
/**
786
 * rewind
787
 * @return bool
788
 * @description set the recordpointer to the first record || false on error
789
 */
790 1549 Luisehahne
	function rewind()
791
	{
792 1998 darkviper
		return $this->seekRow(MYSQL_SEEK_FIRST);
793 1549 Luisehahne
	}
794 1998 darkviper
/**
795
 * seekRow
796
 * @param int $position
797
 * @return bool
798
 * @description set the pointer to the given record || false on error
799
 */
800 1549 Luisehahne
	function seekRow( $position = MYSQL_SEEK_FIRST )
801
	{
802
		$pmax = $this->numRows() - 1;
803
		$p = (($position < 0 || $position > $pmax) ? $pmax : $position);
804 2104 darkviper
		return mysqli_data_seek($this->result, $p);
805 1549 Luisehahne
	}
806 1998 darkviper
/**
807
 * freeResult
808
 * @return bool
809
 * @description remove retult object from memeory
810
 */
811
	function freeResult()
812
	{
813 2104 darkviper
		return mysqli_free_result($this->result);
814 1998 darkviper
	}
815
/**
816
 * Get error
817
 * @return string || null if no error
818
 */
819
	function error()
820
	{
821
		if (isset($this->error)) {
822 4 ryan
			return $this->error;
823
		} else {
824
			return null;
825
		}
826
	}
827
828
}
829 1885 Luisehahne
// //////////////////////////////////////////////////////////////////////////////////// //
830 1364 Luisehahne
/* this function is placed inside this file temporarely until a better place is found */
831
/*  function to update a var/value-pair(s) in table ****************************
832
 *  nonexisting keys are inserted
833
 *  @param string $table: name of table to use (without prefix)
834
 *  @param mixed $key:    a array of key->value pairs to update
835
 *                        or a string with name of the key to update
836
 *  @param string $value: a sting with needed value, if $key is a string too
837
 *  @return bool:  true if any keys are updated, otherwise false
838
 */
839
	function db_update_key_value($table, $key, $value = '')
840
	{
841 1998 darkviper
		$oDb = WbDatabase::getInstance();
842
		if (!is_array($key)) {
843
			if (trim($key) != '') {
844 1364 Luisehahne
				$key = array( trim($key) => trim($value) );
845
			} else {
846
				$key = array();
847
			}
848
		}
849
		$retval = true;
850 2104 darkviper
        $sNameValPairs = '';
851
		foreach ($key as $index => $val) {
852
            $sNameValPairs .= ', (\''.$index.'\', \''.$val.'\')';
853
        }
854
        $sValues = ltrim($sNameValPairs, ', ');
855
        if ($sValues != '') {
856
            $sql = 'REPLACE INTO `'.$oDb->TablePrefix.$table.'` (`name`, `value`) '
857
                 . 'VALUES '.$sValues;
858 1998 darkviper
			if (!$oDb->doQuery($sql)) {
859 1364 Luisehahne
				$retval = false;
860
			}
861 2104 darkviper
        }
862 1364 Luisehahne
		return $retval;
863
	}