MySQL Driver Module | > Module written by Matt Mecham | > Date started: Monday 28th February 2005 16:46 | | > Module Version Number: 2.1.0 +-------------------------------------------------------------------------- */ /** * IPS Kernel Pages: Database Object Driver * * @package IPS_KERNEL * @subpackage DatabaseAbstraction * @author Matt Mecham * @copyright Invision Power Services, Inc. * @version 2.1 */ /** * Handle base class definitions * */ if ( ! defined('KERNEL_PATH') ) { define( 'KERNEL_PATH', dirname(__FILE__) . '/' ); } if ( ! class_exists( 'db_main' ) ) { require_once( KERNEL_PATH.'class_db.php' ); } /** * Allow < 4.3.0 PHP client access * */ if ( ! defined('IPS_MAIN_DB_CLASS_LEGACY') ) { define('IPS_MAIN_DB_CLASS_LEGACY', ( PHP_VERSION < '4.3.0' ) ? TRUE : FALSE ); } /** * DB Class: Driver Methods * * Base class for database abstraction * * @package IPS_KERNEL * @subpackage DatabaseAbstraction * @author Matt Mecham * @version 2.1 */ class db_driver extends db_main { /*-------------------------------------------------------------------------*/ // Set up required vars /*-------------------------------------------------------------------------*/ function db_driver() { //-------------------------- // Set up any required connect // vars here: // Will be populated by obj // caller //-------------------------- $this->connect_vars['mysql_tbl_type'] = ""; } /*-------------------------------------------------------------------------*/ // Connect to the database /*-------------------------------------------------------------------------*/ function connect() { //----------------------------------------- // Done SQL prefix yet? //----------------------------------------- $this->_set_prefix(); //----------------------------------------- // Load query file //----------------------------------------- $this->_load_cache_file(); //----------------------------------------- // Connect //----------------------------------------- if ( $this->obj['persistent'] AND ! IPS_MAIN_DB_CLASS_LEGACY ) { $this->connection_id = mysql_pconnect( $this->obj['sql_host'] , $this->obj['sql_user'] , $this->obj['sql_pass'] , $this->obj['force_new_connection'] ); } else { if ( IPS_MAIN_DB_CLASS_LEGACY ) { $this->connection_id = mysql_connect( $this->obj['sql_host'] , $this->obj['sql_user'] , $this->obj['sql_pass'] ); } else { $this->connection_id = mysql_connect( $this->obj['sql_host'] , $this->obj['sql_user'] , $this->obj['sql_pass'] , $this->obj['force_new_connection'] ); } } if ( ! $this->connection_id ) { $this->fatal_error(); return FALSE; } if ( ! mysql_select_db($this->obj['sql_database'], $this->connection_id) ) { $this->fatal_error(); return FALSE; } return TRUE; } /*-------------------------------------------------------------------------*/ // Quick function: DO UPDATE /*-------------------------------------------------------------------------*/ function do_update( $tbl, $arr, $where="", $shutdown=FALSE ) { //----------------------------------------- // Form query //----------------------------------------- $dba = $this->compile_db_update_string( $arr ); $query = "UPDATE ".$this->obj['sql_tbl_prefix']."$tbl SET $dba"; if ( $where ) { $query .= " WHERE ".$where; } //----------------------------------------- // Shut down query? //----------------------------------------- if ( $shutdown ) { if ( ! $this->obj['use_shutdown'] ) { $this->is_shutdown = 1; return $this->query( $query ); } else { $this->obj['shutdown_queries'][] = $query; $this->cur_query = ""; } } else { return $this->query( $query ); } } /*-------------------------------------------------------------------------*/ // Quick function: DO INSERT /*-------------------------------------------------------------------------*/ function do_insert( $tbl, $arr, $shutdown=FALSE ) { //----------------------------------------- // Form query //----------------------------------------- $dba = $this->compile_db_insert_string( $arr ); $query = "INSERT INTO ".$this->obj['sql_tbl_prefix']."$tbl ({$dba['FIELD_NAMES']}) VALUES({$dba['FIELD_VALUES']})"; //----------------------------------------- // Shut down query? //----------------------------------------- if ( $shutdown ) { if ( ! $this->obj['use_shutdown'] ) { $this->is_shutdown = 1; return $this->query( $query ); } else { $this->obj['shutdown_queries'][] = $query; $this->cur_query = ""; } } else { return $this->query( $query ); } } /*-------------------------------------------------------------------------*/ // SIMPLE: UPDATE /*-------------------------------------------------------------------------*/ function simple_update( $tbl, $set, $where, $low_pro='' ) { if ( $low_pro ) { $low_pro = ' LOW_PRIORITY '; } $this->cur_query .= "UPDATE ". $low_pro . $this->obj['sql_tbl_prefix']."$tbl SET $set"; if ( $where ) { $this->cur_query .= " WHERE $where"; } } /*-------------------------------------------------------------------------*/ // SIMPLE: DELETE /*-------------------------------------------------------------------------*/ function simple_delete( $tbl, $where ) { $this->cur_query .= "DELETE FROM ".$this->obj['sql_tbl_prefix']."$tbl"; if ( $where ) { $this->cur_query .= " WHERE $where"; } } /*-------------------------------------------------------------------------*/ // SIMPLE: ORDER /*-------------------------------------------------------------------------*/ function simple_order( $a ) { if ( $a ) { $this->cur_query .= ' ORDER BY '.$a; } } /*-------------------------------------------------------------------------*/ // SIMPLE: LIMIT WITH CHECK /*-------------------------------------------------------------------------*/ function simple_limit_with_check( $offset, $limit="" ) { if ( ! preg_match( "#LIMIT\s+?\d+,#i", $this->cur_query ) ) { $this->simple_limit( $offset, $limit ); } } /*-------------------------------------------------------------------------*/ // SIMPLE: LIMIT /*-------------------------------------------------------------------------*/ function simple_limit( $offset, $limit="" ) { if ( $limit ) { $this->cur_query .= ' LIMIT '.$offset.','.$limit; } else { $this->cur_query .= ' LIMIT '.$offset; } } /*-------------------------------------------------------------------------*/ // SIMPLE: SELECT /*-------------------------------------------------------------------------*/ function simple_select( $get, $table, $where="" ) { $this->cur_query .= "SELECT $get FROM ".$this->obj['sql_tbl_prefix']."$table"; if ( $where != "" ) { $this->cur_query .= " WHERE ".$where; } } /*-------------------------------------------------------------------------*/ // SIMPLE: SELECT WITH JOIN /*-------------------------------------------------------------------------*/ function simple_select_with_join( $get, $table, $where="", $add_join=array() ) { //----------------------------------------- // OK, here we go... //----------------------------------------- $select_array = array(); $from_array = array(); $joinleft_array = array(); $where_array = array(); $final_from = array(); $select_array[] = $get; $from_array[] = $table; if ( $where ) { $where_array[] = $where; } //----------------------------------------- // Loop through JOINs and sort info //----------------------------------------- if ( is_array( $add_join ) and count( $add_join ) ) { foreach( $add_join as $i => $join ) { # Push join's select to stack if ( $join['select'] ) { $select_array[] = $join['select']; } if ( $join['type'] == 'inner' ) { # Join is inline $from_array[] = $join['from']; if ( $join['where'] ) { $where_array[] = $join['where']; } } else if ( $join['type'] == 'left' ) { # Join is left $tmp = " LEFT JOIN "; foreach( $join['from'] as $tbl => $alias ) { $tmp .= $this->obj['sql_tbl_prefix'].$tbl.' '.$alias; } if ( $join['where'] ) { $tmp .= " ON ( ".$join['where']." ) "; } $joinleft_array[] = $tmp; unset( $tmp ); } else { # Not using any other type of join } } } //----------------------------------------- // Build it.. //----------------------------------------- foreach( $from_array as $i ) { foreach( $i as $tbl => $alias ) { $final_from[] = $this->obj['sql_tbl_prefix'].$tbl.' '.$alias; } } $get = implode( "," , $select_array ); $table = implode( "," , $final_from ); $where = implode( " AND " , $where_array ); $join = implode( "\n" , $joinleft_array ); $this->cur_query .= "SELECT $get FROM $table"; if ( $join ) { $this->cur_query .= " ".$join." "; } if ( $where != "" ) { $this->cur_query .= " WHERE ".$where; } } /*-------------------------------------------------------------------------*/ // Process a manual query /*-------------------------------------------------------------------------*/ function query($the_query, $bypass=0) { //----------------------------------------- // Change the table prefix if needed //----------------------------------------- if ( $this->no_prefix_convert ) { $bypass = 1; } if ( ! $bypass ) { if ( $this->obj['sql_tbl_prefix'] != "ibf_" and ! $this->prefix_changed ) { $the_query = preg_replace("/\sibf_(\S+?)([\s\.,]|$)/", " ".$this->obj['sql_tbl_prefix']."\\1\\2", $the_query); } } //----------------------------------------- // Debug? //----------------------------------------- if ($this->obj['debug']) { global $Debug; $Debug->startTimer(); } //----------------------------------------- // Run the query //----------------------------------------- $this->query_id = mysql_query($the_query, $this->connection_id); //----------------------------------------- // Reset array... //----------------------------------------- $this->force_data_type = array(); if (! $this->query_id ) { $this->fatal_error("mySQL query error: $the_query"); } //----------------------------------------- // Debug? //----------------------------------------- if ($this->obj['debug']) { $endtime = $Debug->endTimer(); $shutdown = $this->is_shutdown ? 'SHUTDOWN QUERY: ' : ''; if ( preg_match( "/^select/i", $the_query ) ) { $eid = mysql_query("EXPLAIN $the_query", $this->connection_id); $this->debug_html .= "\n"; while( $array = mysql_fetch_array($eid) ) { $type_col = '#FFFFFF'; if ($array['type'] == 'ref' or $array['type'] == 'eq_ref' or $array['type'] == 'const') { $type_col = '#D8FFD4'; } else if ($array['type'] == 'ALL') { $type_col = '#FFEEBA'; } $this->debug_html .= "\n"; } $this->sql_time += $endtime; if ($endtime > 0.1) { $endtime = "$endtime"; } $this->debug_html .= "
{$shutdown}Select Query
$the_query
tabletypepossible_keys keykey_lenref rowsExtra
$array[table]  $array[type]  $array[possible_keys]  $array[key]  $array[key_len]  $array[ref]  $array[rows]  $array[Extra] 
MySQL time: $endtime
\n
\n"; } else { $this->debug_html .= "
{$shutdown}Non Select Query
$the_query
MySQL time: $endtime

\n\n"; } } $this->query_count++; $this->obj['cached_queries'][] = $the_query; return $this->query_id; } /*-------------------------------------------------------------------------*/ // Fetch a row based on the last query /*-------------------------------------------------------------------------*/ function fetch_row($query_id = "") { if ($query_id == "") { $query_id = $this->query_id; } $this->record_row = mysql_fetch_array($query_id, MYSQL_ASSOC); return $this->record_row; } /*-------------------------------------------------------------------------*/ // DROP TABLE /*-------------------------------------------------------------------------*/ function sql_drop_table( $table ) { $this->query( "DROP TABLE if exists ".$this->obj['sql_tbl_prefix']."{$table}" ); } /*-------------------------------------------------------------------------*/ // DROP FIELD /*-------------------------------------------------------------------------*/ function sql_drop_field( $table, $field ) { $this->query( "ALTER TABLE ".$this->obj['sql_tbl_prefix']."{$table} DROP $field" ); } /*-------------------------------------------------------------------------*/ // ADD FIELD /*-------------------------------------------------------------------------*/ function sql_add_field( $table, $field_name, $field_type, $field_default="''" ) { $this->query( "ALTER TABLE ".$this->obj['sql_tbl_prefix']."{$table} ADD $field_name $field_type default {$field_default}" ); } /*-------------------------------------------------------------------------*/ // OPTIMIZE TABLE /*-------------------------------------------------------------------------*/ function sql_optimize_table( $table ) { $this->query( "OPTIMIZE TABLE ".$this->obj['sql_tbl_prefix']."{$table}" ); } /*-------------------------------------------------------------------------*/ // ADD FULLTEXT INDEX /*-------------------------------------------------------------------------*/ function sql_add_fulltext_index( $table, $field ) { $this->query( "alter table ".$this->obj['sql_tbl_prefix']."{$table} ADD FULLTEXT({$field})" ); } /*-------------------------------------------------------------------------*/ // GET TABLE SCHEMATIC /*-------------------------------------------------------------------------*/ function sql_get_table_schematic( $table ) { $this->query( "SHOW CREATE TABLE ".$this->obj['sql_tbl_prefix']."{$table}" ); return $this->fetch_row(); } /*-------------------------------------------------------------------------*/ // IS ALREADY TABLE FULLTEXT? /*-------------------------------------------------------------------------*/ function sql_is_currently_fulltext( $table ) { $result = $this->sql_get_table_schematic( $table ); if ( preg_match( "/FULLTEXT KEY/i", $result['Create Table'] ) ) { return TRUE; } else { return FALSE; } } /*-------------------------------------------------------------------------*/ // Return the version number of the SQL server // Should return 'true' version string (ie: 3.23.0) // And formatted string (ie: 3230 ) /*-------------------------------------------------------------------------*/ function sql_get_version() { if ( ! $this->mysql_version and ! $this->true_version ) { $this->query("SELECT VERSION() AS version"); if ( ! $row = $this->fetch_row() ) { $this->query("SHOW VARIABLES LIKE 'version'"); $row = $this->fetch_row(); } $this->true_version = $row['version']; $tmp = explode( '.', preg_replace( "#[^\d\.]#", "\\1", $row['version'] ) ); $this->mysql_version = sprintf('%d%02d%02d', $tmp[0], $tmp[1], $tmp[2] ); } } /*-------------------------------------------------------------------------*/ // sql_can_fulltext // returns whether SQL engine has fulltext abilities // returns TRUE or FALSE /*-------------------------------------------------------------------------*/ function sql_can_fulltext() { $this->sql_get_version(); if ( $this->mysql_version >= 32323 AND strtolower($this->connect_vars['mysql_tbl_type']) == 'myisam' ) { return TRUE; } else { return FALSE; } } /*-------------------------------------------------------------------------*/ // sql_can_fulltext_boolean // returns whether SQL engine has boolean fulltext abilities // (+word -word, etc) // returns TRUE or FALSE /*-------------------------------------------------------------------------*/ function sql_can_fulltext_boolean() { $this->sql_get_version(); if ( $this->mysql_version >= 40010 AND strtolower($this->connect_vars['mysql_tbl_type']) == 'myisam' ) { return TRUE; } else { return FALSE; } } /*-------------------------------------------------------------------------*/ // Fetch the number of rows affected by the last query /*-------------------------------------------------------------------------*/ function get_affected_rows() { return mysql_affected_rows($this->connection_id); } /*-------------------------------------------------------------------------*/ // Fetch the number of rows in a result set /*-------------------------------------------------------------------------*/ function get_num_rows() { return mysql_num_rows($this->query_id); } /*-------------------------------------------------------------------------*/ // Fetch the last insert id from an sql autoincrement /*-------------------------------------------------------------------------*/ function get_insert_id() { return mysql_insert_id($this->connection_id); } /*-------------------------------------------------------------------------*/ // Free the result set from mySQLs memory /*-------------------------------------------------------------------------*/ function free_result($query_id="") { if ($query_id == "") { $query_id = $this->query_id; } @mysql_free_result($query_id); } /*-------------------------------------------------------------------------*/ // Shut down the database /*-------------------------------------------------------------------------*/ function close_db() { if ( $this->connection_id ) { return @mysql_close( $this->connection_id ); } } /*-------------------------------------------------------------------------*/ // Return an array of tables /*-------------------------------------------------------------------------*/ function get_table_names() { $result = mysql_list_tables($this->obj['sql_database']); $num_tables = @mysql_numrows($result); for ($i = 0; $i < $num_tables; $i++) { $tables[] = mysql_tablename($result, $i); } mysql_free_result($result); return $tables; } /*-------------------------------------------------------------------------*/ // Return an array of fields /*-------------------------------------------------------------------------*/ function get_result_fields($query_id="") { if ($query_id == "") { $query_id = $this->query_id; } while ($field = mysql_fetch_field($query_id)) { $Fields[] = $field; } return $Fields; } /*-------------------------------------------------------------------------*/ // INTERNAL: Get error number /*-------------------------------------------------------------------------*/ function _get_error_number() { return mysql_errno(); } /*-------------------------------------------------------------------------*/ // INTERNAL: Get error number /*-------------------------------------------------------------------------*/ function _get_error_string() { return mysql_error(); } /*-------------------------------------------------------------------------*/ // Use different escape method for different SQL engines /*-------------------------------------------------------------------------*/ function add_slashes( $t ) { return ( IPS_MAIN_DB_CLASS_LEGACY ) ? mysql_escape_string($t) : mysql_real_escape_string($t, $this->connection_id ); } /*-------------------------------------------------------------------------*/ // Use different escape method for different SQL engines /*-------------------------------------------------------------------------*/ function remove_slashes( $t ) { # Not required for MySQL because we use the mysql_real_escape_string /*if ( get_magic_quotes_gpc() ) { $t = stripslashes($t); }*/ return $t; } } // end class ?>