Subversion-Projekte lars-tiefland.codeigniter

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP 4.3.2 or newer
6
 *
7
 * @package		CodeIgniter
8
 * @author		ExpressionEngine Dev Team
9
 * @copyright	Copyright (c) 2008, 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
	/**
39
	 * The syntax to count rows is slightly different across different
40
	 * database engines, so this string appears in each driver and is
41
	 * used for the count_all() and count_all_results() functions.
42
	 */
43
	var $_count_string = "SELECT COUNT(*) AS ";
44
	var $_random_keyword = ' RAND()'; // database specific random keyword
45
 
46
	/**
47
	 * Whether to use the MySQL "delete hack" which allows the number
48
	 * of affected rows to be shown. Uses a preg_replace when enabled,
49
	 * adding a bit more processing to all queries.
50
	 */
51
	var $delete_hack = TRUE;
52
 
53
	// --------------------------------------------------------------------
54
 
55
	/**
56
	 * Non-persistent database connection
57
	 *
58
	 * @access	private called by the base class
59
	 * @return	resource
60
	 */
61
	function db_connect()
62
	{
63
		if ($this->port != '')
64
		{
65
			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);
66
		}
67
		else
68
		{
69
			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
70
		}
71
 
72
	}
73
 
74
	// --------------------------------------------------------------------
75
 
76
	/**
77
	 * Persistent database connection
78
	 *
79
	 * @access	private called by the base class
80
	 * @return	resource
81
	 */
82
	function db_pconnect()
83
	{
84
		return $this->db_connect();
85
	}
86
 
87
	// --------------------------------------------------------------------
88
 
89
	/**
90
	 * Select the database
91
	 *
92
	 * @access	private called by the base class
93
	 * @return	resource
94
	 */
95
	function db_select()
96
	{
97
		return @mysqli_select_db($this->conn_id, $this->database);
98
	}
99
 
100
	// --------------------------------------------------------------------
101
 
102
	/**
103
	 * Set client character set
104
	 *
105
	 * @access	private
106
	 * @param	string
107
	 * @param	string
108
	 * @return	resource
109
	 */
110
	function _db_set_charset($charset, $collation)
111
	{
112
		return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
113
	}
114
 
115
	// --------------------------------------------------------------------
116
 
117
	/**
118
	 * Version number query string
119
	 *
120
	 * @access	public
121
	 * @return	string
122
	 */
123
	function _version()
124
	{
125
		return "SELECT version() AS ver";
126
	}
127
 
128
	// --------------------------------------------------------------------
129
 
130
	/**
131
	 * Execute the query
132
	 *
133
	 * @access	private called by the base class
134
	 * @param	string	an SQL query
135
	 * @return	resource
136
	 */
137
	function _execute($sql)
138
	{
139
		$sql = $this->_prep_query($sql);
140
		$result = @mysqli_query($this->conn_id, $sql);
141
		return $result;
142
	}
143
 
144
	// --------------------------------------------------------------------
145
 
146
	/**
147
	 * Prep the query
148
	 *
149
	 * If needed, each database adapter can prep the query string
150
	 *
151
	 * @access	private called by execute()
152
	 * @param	string	an SQL query
153
	 * @return	string
154
	 */
155
	function _prep_query($sql)
156
	{
157
		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies
158
		// the query so that it returns the number of affected rows
159
		if ($this->delete_hack === TRUE)
160
		{
161
			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
162
			{
163
				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
164
			}
165
		}
166
 
167
		return $sql;
168
	}
169
 
170
	// --------------------------------------------------------------------
171
 
172
	/**
173
	 * Begin Transaction
174
	 *
175
	 * @access	public
176
	 * @return	bool
177
	 */
178
	function trans_begin($test_mode = FALSE)
179
	{
180
		if ( ! $this->trans_enabled)
181
		{
182
			return TRUE;
183
		}
184
 
185
		// When transactions are nested we only begin/commit/rollback the outermost ones
186
		if ($this->_trans_depth > 0)
187
		{
188
			return TRUE;
189
		}
190
 
191
		// Reset the transaction failure flag.
192
		// If the $test_mode flag is set to TRUE transactions will be rolled back
193
		// even if the queries produce a successful result.
194
		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
195
 
196
		$this->simple_query('SET AUTOCOMMIT=0');
197
		$this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
198
		return TRUE;
199
	}
200
 
201
	// --------------------------------------------------------------------
202
 
203
	/**
204
	 * Commit Transaction
205
	 *
206
	 * @access	public
207
	 * @return	bool
208
	 */
209
	function trans_commit()
210
	{
211
		if ( ! $this->trans_enabled)
212
		{
213
			return TRUE;
214
		}
215
 
216
		// When transactions are nested we only begin/commit/rollback the outermost ones
217
		if ($this->_trans_depth > 0)
218
		{
219
			return TRUE;
220
		}
221
 
222
		$this->simple_query('COMMIT');
223
		$this->simple_query('SET AUTOCOMMIT=1');
224
		return TRUE;
225
	}
226
 
227
	// --------------------------------------------------------------------
228
 
229
	/**
230
	 * Rollback Transaction
231
	 *
232
	 * @access	public
233
	 * @return	bool
234
	 */
235
	function trans_rollback()
236
	{
237
		if ( ! $this->trans_enabled)
238
		{
239
			return TRUE;
240
		}
241
 
242
		// When transactions are nested we only begin/commit/rollback the outermost ones
243
		if ($this->_trans_depth > 0)
244
		{
245
			return TRUE;
246
		}
247
 
248
		$this->simple_query('ROLLBACK');
249
		$this->simple_query('SET AUTOCOMMIT=1');
250
		return TRUE;
251
	}
252
 
253
	// --------------------------------------------------------------------
254
 
255
	/**
256
	 * Escape String
257
	 *
258
	 * @access	public
259
	 * @param	string
260
	 * @return	string
261
	 */
262
	function escape_str($str)
263
	{
264
		if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))
265
		{
266
			return mysqli_real_escape_string($this->conn_id, $str);
267
		}
268
		elseif (function_exists('mysql_escape_string'))
269
		{
270
			return mysql_escape_string($str);
271
		}
272
		else
273
		{
274
			return addslashes($str);
275
		}
276
	}
277
 
278
	// --------------------------------------------------------------------
279
 
280
	/**
281
	 * Affected Rows
282
	 *
283
	 * @access	public
284
	 * @return	integer
285
	 */
286
	function affected_rows()
287
	{
288
		return @mysqli_affected_rows($this->conn_id);
289
	}
290
 
291
	// --------------------------------------------------------------------
292
 
293
	/**
294
	 * Insert ID
295
	 *
296
	 * @access	public
297
	 * @return	integer
298
	 */
299
	function insert_id()
300
	{
301
		return @mysqli_insert_id($this->conn_id);
302
	}
303
 
304
	// --------------------------------------------------------------------
305
 
306
	/**
307
	 * "Count All" query
308
	 *
309
	 * Generates a platform-specific query string that counts all records in
310
	 * the specified database
311
	 *
312
	 * @access	public
313
	 * @param	string
314
	 * @return	string
315
	 */
316
	function count_all($table = '')
317
	{
318
		if ($table == '')
319
		{
320
			return 0;
321
		}
322
 
323
		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
324
 
325
		if ($query->num_rows() == 0)
326
		{
327
			return 0;
328
		}
329
 
330
		$row = $query->row();
331
		return (int) $row->numrows;
332
	}
333
 
334
	// --------------------------------------------------------------------
335
 
336
	/**
337
	 * List table query
338
	 *
339
	 * Generates a platform-specific query string so that the table names can be fetched
340
	 *
341
	 * @access	private
342
	 * @param	boolean
343
	 * @return	string
344
	 */
345
	function _list_tables($prefix_limit = FALSE)
346
	{
347
		$sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;
348
 
349
		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
350
		{
351
			$sql .= " LIKE '".$this->dbprefix."%'";
352
		}
353
 
354
		return $sql;
355
	}
356
 
357
	// --------------------------------------------------------------------
358
 
359
	/**
360
	 * Show column query
361
	 *
362
	 * Generates a platform-specific query string so that the column names can be fetched
363
	 *
364
	 * @access	public
365
	 * @param	string	the table name
366
	 * @return	string
367
	 */
368
	function _list_columns($table = '')
369
	{
370
		return "SHOW COLUMNS FROM ".$table;
371
	}
372
 
373
	// --------------------------------------------------------------------
374
 
375
	/**
376
	 * Field data query
377
	 *
378
	 * Generates a platform-specific query so that the column data can be retrieved
379
	 *
380
	 * @access	public
381
	 * @param	string	the table name
382
	 * @return	object
383
	 */
384
	function _field_data($table)
385
	{
386
		return "SELECT * FROM ".$table." LIMIT 1";
387
	}
388
 
389
	// --------------------------------------------------------------------
390
 
391
	/**
392
	 * The error message string
393
	 *
394
	 * @access	private
395
	 * @return	string
396
	 */
397
	function _error_message()
398
	{
399
		return mysqli_error($this->conn_id);
400
	}
401
 
402
	// --------------------------------------------------------------------
403
 
404
	/**
405
	 * The error message number
406
	 *
407
	 * @access	private
408
	 * @return	integer
409
	 */
410
	function _error_number()
411
	{
412
		return mysqli_errno($this->conn_id);
413
	}
414
 
415
	// --------------------------------------------------------------------
416
 
417
	/**
418
	 * Escape the SQL Identifiers
419
	 *
420
	 * This function escapes column and table names
421
	 *
422
	 * @access	private
423
	 * @param	string
424
	 * @return	string
425
	 */
426
	function _escape_identifiers($item)
427
	{
428
		if ($this->_escape_char == '')
429
		{
430
			return $item;
431
		}
432
 
433
		foreach ($this->_reserved_identifiers as $id)
434
		{
435
			if (strpos($item, '.'.$id) !== FALSE)
436
			{
437
				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
438
 
439
				// remove duplicates if the user already included the escape
440
				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
441
			}
442
		}
443
 
444
		if (strpos($item, '.') !== FALSE)
445
		{
446
			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
447
		}
448
		else
449
		{
450
			$str = $this->_escape_char.$item.$this->_escape_char;
451
		}
452
 
453
		// remove duplicates if the user already included the escape
454
		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
455
	}
456
 
457
	// --------------------------------------------------------------------
458
 
459
	/**
460
	 * From Tables
461
	 *
462
	 * This function implicitly groups FROM tables so there is no confusion
463
	 * about operator precedence in harmony with SQL standards
464
	 *
465
	 * @access	public
466
	 * @param	type
467
	 * @return	type
468
	 */
469
	function _from_tables($tables)
470
	{
471
		if ( ! is_array($tables))
472
		{
473
			$tables = array($tables);
474
		}
475
 
476
		return '('.implode(', ', $tables).')';
477
	}
478
 
479
	// --------------------------------------------------------------------
480
 
481
	/**
482
	 * Insert statement
483
	 *
484
	 * Generates a platform-specific insert string from the supplied data
485
	 *
486
	 * @access	public
487
	 * @param	string	the table name
488
	 * @param	array	the insert keys
489
	 * @param	array	the insert values
490
	 * @return	string
491
	 */
492
	function _insert($table, $keys, $values)
493
	{
494
		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
495
	}
496
 
497
	// --------------------------------------------------------------------
498
 
499
	/**
500
	 * Update statement
501
	 *
502
	 * Generates a platform-specific update string from the supplied data
503
	 *
504
	 * @access	public
505
	 * @param	string	the table name
506
	 * @param	array	the update data
507
	 * @param	array	the where clause
508
	 * @param	array	the orderby clause
509
	 * @param	array	the limit clause
510
	 * @return	string
511
	 */
512
	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
513
	{
514
		foreach($values as $key => $val)
515
		{
516
			$valstr[] = $key." = ".$val;
517
		}
518
 
519
		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
520
 
521
		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
522
 
523
		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
524
 
525
		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
526
 
527
		$sql .= $orderby.$limit;
528
 
529
		return $sql;
530
	}
531
 
532
 
533
	// --------------------------------------------------------------------
534
 
535
	/**
536
	 * Truncate statement
537
	 *
538
	 * Generates a platform-specific truncate string from the supplied data
539
	 * If the database does not support the truncate() command
540
	 * This function maps to "DELETE FROM table"
541
	 *
542
	 * @access	public
543
	 * @param	string	the table name
544
	 * @return	string
545
	 */
546
	function _truncate($table)
547
	{
548
		return "TRUNCATE ".$table;
549
	}
550
 
551
	// --------------------------------------------------------------------
552
 
553
	/**
554
	 * Delete statement
555
	 *
556
	 * Generates a platform-specific delete string from the supplied data
557
	 *
558
	 * @access	public
559
	 * @param	string	the table name
560
	 * @param	array	the where clause
561
	 * @param	string	the limit clause
562
	 * @return	string
563
	 */
564
	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
565
	{
566
		$conditions = '';
567
 
568
		if (count($where) > 0 OR count($like) > 0)
569
		{
570
			$conditions = "\nWHERE ";
571
			$conditions .= implode("\n", $this->ar_where);
572
 
573
			if (count($where) > 0 && count($like) > 0)
574
			{
575
				$conditions .= " AND ";
576
			}
577
			$conditions .= implode("\n", $like);
578
		}
579
 
580
		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
581
 
582
		return "DELETE FROM ".$table.$conditions.$limit;
583
	}
584
 
585
	// --------------------------------------------------------------------
586
 
587
	/**
588
	 * Limit string
589
	 *
590
	 * Generates a platform-specific LIMIT clause
591
	 *
592
	 * @access	public
593
	 * @param	string	the sql query string
594
	 * @param	integer	the number of rows to limit the query to
595
	 * @param	integer	the offset value
596
	 * @return	string
597
	 */
598
	function _limit($sql, $limit, $offset)
599
	{
600
		$sql .= "LIMIT ".$limit;
601
 
602
		if ($offset > 0)
603
		{
604
			$sql .= " OFFSET ".$offset;
605
		}
606
 
607
		return $sql;
608
	}
609
 
610
	// --------------------------------------------------------------------
611
 
612
	/**
613
	 * Close DB Connection
614
	 *
615
	 * @access	public
616
	 * @param	resource
617
	 * @return	void
618
	 */
619
	function _close($conn_id)
620
	{
621
		@mysqli_close($conn_id);
622
	}
623
 
624
 
625
}
626
 
627
 
628
/* End of file mysqli_driver.php */
629
/* Location: ./system/database/drivers/mysqli/mysqli_driver.php */