/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk
20.1.1 by galaxyAbstractor
* Added an simple admin panel to the codeviewer-cmssy stuff
1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP 5.1.6 or newer
6
 *
7
 * @package		CodeIgniter
8
 * @author		ExpressionEngine Dev Team
9
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
10
 * @license		http://codeigniter.com/user_guide/license.html
11
 * @link		http://codeigniter.com
12
 * @since		Version 1.0
13
 * @filesource
14
 */
15
16
// ------------------------------------------------------------------------
17
18
/**
19
 * MySQLi Database Adapter Class - MySQLi only works with PHP 5
20
 *
21
 * Note: _DB is an extender class that the app controller
22
 * creates dynamically based on whether the active record
23
 * class is being used or not.
24
 *
25
 * @package		CodeIgniter
26
 * @subpackage	Drivers
27
 * @category	Database
28
 * @author		ExpressionEngine Dev Team
29
 * @link		http://codeigniter.com/user_guide/database/
30
 */
31
class CI_DB_mysqli_driver extends CI_DB {
32
33
	var $dbdriver = 'mysqli';
34
35
	// The character used for escaping
36
	var $_escape_char = '`';
37
38
	// clause and character used for LIKE escape sequences - not used in MySQL
39
	var $_like_escape_str = '';
40
	var $_like_escape_chr = '';
41
42
	/**
43
	 * The syntax to count rows is slightly different across different
44
	 * database engines, so this string appears in each driver and is
45
	 * used for the count_all() and count_all_results() functions.
46
	 */
47
	var $_count_string = "SELECT COUNT(*) AS ";
48
	var $_random_keyword = ' RAND()'; // database specific random keyword
49
50
	/**
51
	 * Whether to use the MySQL "delete hack" which allows the number
52
	 * of affected rows to be shown. Uses a preg_replace when enabled,
53
	 * adding a bit more processing to all queries.
54
	 */
55
	var $delete_hack = TRUE;
56
57
	// whether SET NAMES must be used to set the character set
58
	var $use_set_names;
59
	
60
	// --------------------------------------------------------------------
61
62
	/**
63
	 * Non-persistent database connection
64
	 *
65
	 * @access	private called by the base class
66
	 * @return	resource
67
	 */
68
	function db_connect()
69
	{
70
		if ($this->port != '')
71
		{
72
			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);
73
		}
74
		else
75
		{
76
			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
77
		}
78
79
	}
80
81
	// --------------------------------------------------------------------
82
83
	/**
84
	 * Persistent database connection
85
	 *
86
	 * @access	private called by the base class
87
	 * @return	resource
88
	 */
89
	function db_pconnect()
90
	{
91
		return $this->db_connect();
92
	}
93
94
	// --------------------------------------------------------------------
95
96
	/**
97
	 * Reconnect
98
	 *
99
	 * Keep / reestablish the db connection if no queries have been
100
	 * sent for a length of time exceeding the server's idle timeout
101
	 *
102
	 * @access	public
103
	 * @return	void
104
	 */
105
	function reconnect()
106
	{
107
		if (mysqli_ping($this->conn_id) === FALSE)
108
		{
109
			$this->conn_id = FALSE;
110
		}
111
	}
112
113
	// --------------------------------------------------------------------
114
115
	/**
116
	 * Select the database
117
	 *
118
	 * @access	private called by the base class
119
	 * @return	resource
120
	 */
121
	function db_select()
122
	{
123
		return @mysqli_select_db($this->conn_id, $this->database);
124
	}
125
126
	// --------------------------------------------------------------------
127
128
	/**
129
	 * Set client character set
130
	 *
131
	 * @access	private
132
	 * @param	string
133
	 * @param	string
134
	 * @return	resource
135
	 */
136
	function _db_set_charset($charset, $collation)
137
	{
138
		if ( ! isset($this->use_set_names))
139
		{
140
			// mysqli_set_charset() requires MySQL >= 5.0.7, use SET NAMES as fallback
141
			$this->use_set_names = (version_compare(mysqli_get_server_info($this->conn_id), '5.0.7', '>=')) ? FALSE : TRUE;
142
		}
143
144
		if ($this->use_set_names === TRUE)
145
		{
146
			return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
147
		}
148
		else
149
		{
150
			return @mysqli_set_charset($this->conn_id, $charset);
151
		}
152
	}
153
154
	// --------------------------------------------------------------------
155
156
	/**
157
	 * Version number query string
158
	 *
159
	 * @access	public
160
	 * @return	string
161
	 */
162
	function _version()
163
	{
164
		return "SELECT version() AS ver";
165
	}
166
167
	// --------------------------------------------------------------------
168
169
	/**
170
	 * Execute the query
171
	 *
172
	 * @access	private called by the base class
173
	 * @param	string	an SQL query
174
	 * @return	resource
175
	 */
176
	function _execute($sql)
177
	{
178
		$sql = $this->_prep_query($sql);
179
		$result = @mysqli_query($this->conn_id, $sql);
180
		return $result;
181
	}
182
183
	// --------------------------------------------------------------------
184
185
	/**
186
	 * Prep the query
187
	 *
188
	 * If needed, each database adapter can prep the query string
189
	 *
190
	 * @access	private called by execute()
191
	 * @param	string	an SQL query
192
	 * @return	string
193
	 */
194
	function _prep_query($sql)
195
	{
196
		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies
197
		// the query so that it returns the number of affected rows
198
		if ($this->delete_hack === TRUE)
199
		{
200
			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
201
			{
202
				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
203
			}
204
		}
205
206
		return $sql;
207
	}
208
209
	// --------------------------------------------------------------------
210
211
	/**
212
	 * Begin Transaction
213
	 *
214
	 * @access	public
215
	 * @return	bool
216
	 */
217
	function trans_begin($test_mode = FALSE)
218
	{
219
		if ( ! $this->trans_enabled)
220
		{
221
			return TRUE;
222
		}
223
224
		// When transactions are nested we only begin/commit/rollback the outermost ones
225
		if ($this->_trans_depth > 0)
226
		{
227
			return TRUE;
228
		}
229
230
		// Reset the transaction failure flag.
231
		// If the $test_mode flag is set to TRUE transactions will be rolled back
232
		// even if the queries produce a successful result.
233
		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
234
235
		$this->simple_query('SET AUTOCOMMIT=0');
236
		$this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
237
		return TRUE;
238
	}
239
240
	// --------------------------------------------------------------------
241
242
	/**
243
	 * Commit Transaction
244
	 *
245
	 * @access	public
246
	 * @return	bool
247
	 */
248
	function trans_commit()
249
	{
250
		if ( ! $this->trans_enabled)
251
		{
252
			return TRUE;
253
		}
254
255
		// When transactions are nested we only begin/commit/rollback the outermost ones
256
		if ($this->_trans_depth > 0)
257
		{
258
			return TRUE;
259
		}
260
261
		$this->simple_query('COMMIT');
262
		$this->simple_query('SET AUTOCOMMIT=1');
263
		return TRUE;
264
	}
265
266
	// --------------------------------------------------------------------
267
268
	/**
269
	 * Rollback Transaction
270
	 *
271
	 * @access	public
272
	 * @return	bool
273
	 */
274
	function trans_rollback()
275
	{
276
		if ( ! $this->trans_enabled)
277
		{
278
			return TRUE;
279
		}
280
281
		// When transactions are nested we only begin/commit/rollback the outermost ones
282
		if ($this->_trans_depth > 0)
283
		{
284
			return TRUE;
285
		}
286
287
		$this->simple_query('ROLLBACK');
288
		$this->simple_query('SET AUTOCOMMIT=1');
289
		return TRUE;
290
	}
291
292
	// --------------------------------------------------------------------
293
294
	/**
295
	 * Escape String
296
	 *
297
	 * @access	public
298
	 * @param	string
299
	 * @param	bool	whether or not the string will be used in a LIKE condition
300
	 * @return	string
301
	 */
302
	function escape_str($str, $like = FALSE)
303
	{
304
		if (is_array($str))
305
		{
306
			foreach ($str as $key => $val)
307
			{
308
				$str[$key] = $this->escape_str($val, $like);
309
			}
310
311
			return $str;
312
		}
313
314
		if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))
315
		{
316
			$str = mysqli_real_escape_string($this->conn_id, $str);
317
		}
318
		elseif (function_exists('mysql_escape_string'))
319
		{
320
			$str = mysql_escape_string($str);
321
		}
322
		else
323
		{
324
			$str = addslashes($str);
325
		}
326
327
		// escape LIKE condition wildcards
328
		if ($like === TRUE)
329
		{
330
			$str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
331
		}
332
333
		return $str;
334
	}
335
336
	// --------------------------------------------------------------------
337
338
	/**
339
	 * Affected Rows
340
	 *
341
	 * @access	public
342
	 * @return	integer
343
	 */
344
	function affected_rows()
345
	{
346
		return @mysqli_affected_rows($this->conn_id);
347
	}
348
349
	// --------------------------------------------------------------------
350
351
	/**
352
	 * Insert ID
353
	 *
354
	 * @access	public
355
	 * @return	integer
356
	 */
357
	function insert_id()
358
	{
359
		return @mysqli_insert_id($this->conn_id);
360
	}
361
362
	// --------------------------------------------------------------------
363
364
	/**
365
	 * "Count All" query
366
	 *
367
	 * Generates a platform-specific query string that counts all records in
368
	 * the specified database
369
	 *
370
	 * @access	public
371
	 * @param	string
372
	 * @return	string
373
	 */
374
	function count_all($table = '')
375
	{
376
		if ($table == '')
377
		{
378
			return 0;
379
		}
380
381
		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
382
383
		if ($query->num_rows() == 0)
384
		{
385
			return 0;
386
		}
387
388
		$row = $query->row();
389
		$this->_reset_select();
390
		return (int) $row->numrows;
391
	}
392
393
	// --------------------------------------------------------------------
394
395
	/**
396
	 * List table query
397
	 *
398
	 * Generates a platform-specific query string so that the table names can be fetched
399
	 *
400
	 * @access	private
401
	 * @param	boolean
402
	 * @return	string
403
	 */
404
	function _list_tables($prefix_limit = FALSE)
405
	{
406
		$sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;
407
408
		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
409
		{
410
			$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
411
		}
412
413
		return $sql;
414
	}
415
416
	// --------------------------------------------------------------------
417
418
	/**
419
	 * Show column query
420
	 *
421
	 * Generates a platform-specific query string so that the column names can be fetched
422
	 *
423
	 * @access	public
424
	 * @param	string	the table name
425
	 * @return	string
426
	 */
427
	function _list_columns($table = '')
428
	{
429
		return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
430
	}
431
432
	// --------------------------------------------------------------------
433
434
	/**
435
	 * Field data query
436
	 *
437
	 * Generates a platform-specific query so that the column data can be retrieved
438
	 *
439
	 * @access	public
440
	 * @param	string	the table name
441
	 * @return	object
442
	 */
443
	function _field_data($table)
444
	{
445
		return "DESCRIBE ".$table;
446
	}
447
448
	// --------------------------------------------------------------------
449
450
	/**
451
	 * The error message string
452
	 *
453
	 * @access	private
454
	 * @return	string
455
	 */
456
	function _error_message()
457
	{
458
		return mysqli_error($this->conn_id);
459
	}
460
461
	// --------------------------------------------------------------------
462
463
	/**
464
	 * The error message number
465
	 *
466
	 * @access	private
467
	 * @return	integer
468
	 */
469
	function _error_number()
470
	{
471
		return mysqli_errno($this->conn_id);
472
	}
473
474
	// --------------------------------------------------------------------
475
476
	/**
477
	 * Escape the SQL Identifiers
478
	 *
479
	 * This function escapes column and table names
480
	 *
481
	 * @access	private
482
	 * @param	string
483
	 * @return	string
484
	 */
485
	function _escape_identifiers($item)
486
	{
487
		if ($this->_escape_char == '')
488
		{
489
			return $item;
490
		}
491
492
		foreach ($this->_reserved_identifiers as $id)
493
		{
494
			if (strpos($item, '.'.$id) !== FALSE)
495
			{
496
				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
497
498
				// remove duplicates if the user already included the escape
499
				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
500
			}
501
		}
502
503
		if (strpos($item, '.') !== FALSE)
504
		{
505
			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
506
		}
507
		else
508
		{
509
			$str = $this->_escape_char.$item.$this->_escape_char;
510
		}
511
512
		// remove duplicates if the user already included the escape
513
		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
514
	}
515
516
	// --------------------------------------------------------------------
517
518
	/**
519
	 * From Tables
520
	 *
521
	 * This function implicitly groups FROM tables so there is no confusion
522
	 * about operator precedence in harmony with SQL standards
523
	 *
524
	 * @access	public
525
	 * @param	type
526
	 * @return	type
527
	 */
528
	function _from_tables($tables)
529
	{
530
		if ( ! is_array($tables))
531
		{
532
			$tables = array($tables);
533
		}
534
535
		return '('.implode(', ', $tables).')';
536
	}
537
538
	// --------------------------------------------------------------------
539
540
	/**
541
	 * Insert statement
542
	 *
543
	 * Generates a platform-specific insert string from the supplied data
544
	 *
545
	 * @access	public
546
	 * @param	string	the table name
547
	 * @param	array	the insert keys
548
	 * @param	array	the insert values
549
	 * @return	string
550
	 */
551
	function _insert($table, $keys, $values)
552
	{
553
		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
554
	}
555
556
	// --------------------------------------------------------------------
557
558
	/**
559
	 * Insert_batch statement
560
	 *
561
	 * Generates a platform-specific insert string from the supplied data
562
	 *
563
	 * @access	public
564
	 * @param	string	the table name
565
	 * @param	array	the insert keys
566
	 * @param	array	the insert values
567
	 * @return	string
568
	 */
569
	function _insert_batch($table, $keys, $values)
570
	{
571
		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
572
	}
573
574
	// --------------------------------------------------------------------
575
576
577
	/**
578
	 * Replace statement
579
	 *
580
	 * Generates a platform-specific replace string from the supplied data
581
	 *
582
	 * @access	public
583
	 * @param	string	the table name
584
	 * @param	array	the insert keys
585
	 * @param	array	the insert values
586
	 * @return	string
587
	 */
588
	function _replace($table, $keys, $values)
589
	{
590
		return "REPLACE INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
591
	}
592
	
593
	// --------------------------------------------------------------------
594
595
	/**
596
	 * Update statement
597
	 *
598
	 * Generates a platform-specific update string from the supplied data
599
	 *
600
	 * @access	public
601
	 * @param	string	the table name
602
	 * @param	array	the update data
603
	 * @param	array	the where clause
604
	 * @param	array	the orderby clause
605
	 * @param	array	the limit clause
606
	 * @return	string
607
	 */
608
	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
609
	{
610
		foreach ($values as $key => $val)
611
		{
612
			$valstr[] = $key." = ".$val;
613
		}
614
615
		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
616
617
		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
618
619
		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
620
621
		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
622
623
		$sql .= $orderby.$limit;
624
625
		return $sql;
626
	}
627
628
	// --------------------------------------------------------------------
629
630
	/**
631
	 * Update_Batch statement
632
	 *
633
	 * Generates a platform-specific batch update string from the supplied data
634
	 *
635
	 * @access	public
636
	 * @param	string	the table name
637
	 * @param	array	the update data
638
	 * @param	array	the where clause
639
	 * @return	string
640
	 */
641
	function _update_batch($table, $values, $index, $where = NULL)
642
	{
643
		$ids = array();
644
		$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
645
646
		foreach ($values as $key => $val)
647
		{
648
			$ids[] = $val[$index];
649
650
			foreach (array_keys($val) as $field)
651
			{
652
				if ($field != $index)
653
				{
654
					$final[$field][] =  'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
655
				}
656
			}
657
		}
658
659
		$sql = "UPDATE ".$table." SET ";
660
		$cases = '';
661
662
		foreach ($final as $k => $v)
663
		{
664
			$cases .= $k.' = CASE '."\n";
665
			foreach ($v as $row)
666
			{
667
				$cases .= $row."\n";
668
			}
669
670
			$cases .= 'ELSE '.$k.' END, ';
671
		}
672
673
		$sql .= substr($cases, 0, -2);
674
675
		$sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
676
677
		return $sql;
678
	}
679
680
	// --------------------------------------------------------------------
681
682
	/**
683
	 * Truncate statement
684
	 *
685
	 * Generates a platform-specific truncate string from the supplied data
686
	 * If the database does not support the truncate() command
687
	 * This function maps to "DELETE FROM table"
688
	 *
689
	 * @access	public
690
	 * @param	string	the table name
691
	 * @return	string
692
	 */
693
	function _truncate($table)
694
	{
695
		return "TRUNCATE ".$table;
696
	}
697
698
	// --------------------------------------------------------------------
699
700
	/**
701
	 * Delete statement
702
	 *
703
	 * Generates a platform-specific delete string from the supplied data
704
	 *
705
	 * @access	public
706
	 * @param	string	the table name
707
	 * @param	array	the where clause
708
	 * @param	string	the limit clause
709
	 * @return	string
710
	 */
711
	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
712
	{
713
		$conditions = '';
714
715
		if (count($where) > 0 OR count($like) > 0)
716
		{
717
			$conditions = "\nWHERE ";
718
			$conditions .= implode("\n", $this->ar_where);
719
720
			if (count($where) > 0 && count($like) > 0)
721
			{
722
				$conditions .= " AND ";
723
			}
724
			$conditions .= implode("\n", $like);
725
		}
726
727
		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
728
729
		return "DELETE FROM ".$table.$conditions.$limit;
730
	}
731
732
	// --------------------------------------------------------------------
733
734
	/**
735
	 * Limit string
736
	 *
737
	 * Generates a platform-specific LIMIT clause
738
	 *
739
	 * @access	public
740
	 * @param	string	the sql query string
741
	 * @param	integer	the number of rows to limit the query to
742
	 * @param	integer	the offset value
743
	 * @return	string
744
	 */
745
	function _limit($sql, $limit, $offset)
746
	{
747
		$sql .= "LIMIT ".$limit;
748
749
		if ($offset > 0)
750
		{
751
			$sql .= " OFFSET ".$offset;
752
		}
753
754
		return $sql;
755
	}
756
757
	// --------------------------------------------------------------------
758
759
	/**
760
	 * Close DB Connection
761
	 *
762
	 * @access	public
763
	 * @param	resource
764
	 * @return	void
765
	 */
766
	function _close($conn_id)
767
	{
768
		@mysqli_close($conn_id);
769
	}
770
771
772
}
773
774
775
/* End of file mysqli_driver.php */
776
/* Location: ./system/database/drivers/mysqli/mysqli_driver.php */