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