PageRenderTime 25ms CodeModel.GetById 2ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 1ms

/halogy/database/drivers/mysql/mysql_driver.php

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