Version 3.0.5
This commit is contained in:
1 parent
19b38c7c74
commit
1d4720f3e2
3755 files changed
+508378
-664541
No files matched your search
@@ -1,116 +1,185 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [DB Tools]
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2007-10-18 15:47:19 -0400 (Thu, 18 Oct 2007) $
|
||||
| > $Revision: 1137 $
|
||||
| > $Author: bfarber $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > MySQL DB Tools
|
||||
| > Module written by Remco Wilting
|
||||
| > Date started: Tuesday 1st March 2005 15:40
|
||||
|
|
||||
| > Module Version Number: 2.1.001
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* MySQL Database Diagnostic Methods
|
||||
* Last Updated: $Date: 2009-10-09 09:24:39 -0400 (Fri, 09 Oct 2009) $
|
||||
*
|
||||
* @author $Author: josh $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Tuesday 1st March 2005 15:40
|
||||
* @version $Revision: 337 $
|
||||
*/
|
||||
|
||||
class db_tools
|
||||
{
|
||||
var $ipsclass;
|
||||
/**
|
||||
* Missing column/table/index flag
|
||||
*
|
||||
* @var boolean Table/index has issues
|
||||
* @access public
|
||||
*/
|
||||
public $has_issues = false;
|
||||
|
||||
var $has_issues = 0;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Constructor
|
||||
/*-------------------------------------------------------------------------*/
|
||||
function db_tools( & $ipsclass )
|
||||
{
|
||||
$this->ipsclass = & $ipsclass;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Diagnose the table indexes
|
||||
// @input sql_statements array of create table/index statements to check
|
||||
// @output array array of results ( table, index, status, message, fixsql )
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* Internal mapping - ignore me
|
||||
*
|
||||
* @var array Table/column mappings
|
||||
* @access private
|
||||
*/
|
||||
private $_mapping = array();
|
||||
|
||||
function db_index_diag( & $sql_statements )
|
||||
/**
|
||||
* Diagnose table indexes
|
||||
*
|
||||
* @access public
|
||||
* @param array Array of create table/index statements to check
|
||||
* @param array Array of issues to fix
|
||||
* @return array Array of results
|
||||
*/
|
||||
public function dbIndexDiag( $sql_statements, $issues_to_fix='' )
|
||||
{
|
||||
$indexes = array();
|
||||
$error_count = 0;
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$indexes = array();
|
||||
$error_count = 0;
|
||||
$output = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Do we have SQL statements?
|
||||
//-----------------------------------------
|
||||
|
||||
if( is_array($sql_statements) && count($sql_statements) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Loop over our statements
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $sql_statements as $definition )
|
||||
{
|
||||
$table_name = "";
|
||||
$fields_str = "";
|
||||
$primary_key = "";
|
||||
$tablename = array();
|
||||
$fields = array();
|
||||
$final_keys = array();
|
||||
$col_definition = "";
|
||||
$colmatch = array();
|
||||
$final_primary = array();
|
||||
//-----------------------------------------
|
||||
// Some more per-statement init
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#CREATE TABLE\s+?(.+?)\s+?\(#ie", $definition, $tablename ) )
|
||||
$table_name = "";
|
||||
$fields_str = "";
|
||||
$primary_key = "";
|
||||
$tablename = array();
|
||||
$fields = array();
|
||||
$final_keys = array();
|
||||
$col_definition = "";
|
||||
$colmatch = array();
|
||||
$final_primary = array();
|
||||
|
||||
/* Remove backticks */
|
||||
$definition = str_replace( '`', '', $definition );
|
||||
|
||||
//-----------------------------------------
|
||||
// Is this a create table statement?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#CREATE\s+TABLE\s+?(.+?)\s+?\(#ie", $definition, $tablename ) )
|
||||
{
|
||||
$table_name = $tablename[1];
|
||||
if ( preg_match( "#\s+?PRIMARY\s+?KEY\s+?\((.*?)\)(?:(?:[,\s+?$])?\((.+?)\))?#is", $definition, $fields ) )
|
||||
{
|
||||
$final_primary = array();
|
||||
$tableName = $tablename[1];
|
||||
|
||||
//-----------------------------------------
|
||||
// Does the table have a primary key?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#\s+?PRIMARY\s+?KEY\s+?(?:(\w+?)\s+?)?\((.*?)\)(?:(?:[,\s+?$])?\((.+?)\))?#is", $definition, $fields ) )
|
||||
{
|
||||
$final_primary = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Did we find anything with our regex?
|
||||
//-----------------------------------------
|
||||
|
||||
if( count( $fields ) )
|
||||
{
|
||||
$primary_key = trim($fields[1]);
|
||||
//-----------------------------------------
|
||||
// Get the actual key name
|
||||
//-----------------------------------------
|
||||
|
||||
$primary_key = trim($fields[1]);
|
||||
$primary_fields = implode( ",", array_map( 'trim', explode( ",", $fields[2] ) ) );
|
||||
|
||||
//-----------------------------------------
|
||||
// Get the table definition
|
||||
//-----------------------------------------
|
||||
|
||||
$col_definition = $this->sql_strip_ticks( $definition );
|
||||
|
||||
if ( preg_match( "#^\s+?{$primary_key}\s+?(.+?)(?:[,$])#im", $col_definition, $colmatch ) )
|
||||
{
|
||||
$col_definition = trim($colmatch[1]);
|
||||
}
|
||||
$final_primary = array( $primary_key, $col_definition );
|
||||
$col_definition = $this->_sqlStripTicks( $definition );
|
||||
|
||||
//-----------------------------------------
|
||||
// This is the primary key for this table
|
||||
//-----------------------------------------
|
||||
|
||||
$final_primary = array( $primary_key ? $primary_key : $primary_fields, $primary_fields );
|
||||
}
|
||||
}
|
||||
$table_array[$i] = $table_name;
|
||||
|
||||
$table_array[$i] = $tableName;
|
||||
|
||||
//-----------------------------------------
|
||||
// We found a primary key, store it
|
||||
//-----------------------------------------
|
||||
|
||||
if ( count( $final_primary ) )
|
||||
{
|
||||
$primary_array[$i] = $final_primary;
|
||||
}
|
||||
}
|
||||
|
||||
if ( preg_match_all( "#(?<!PRIMARY)\s+?KEY\s+?(?:(\w+?)\s+?)?\((.*?)\)(?:(?:[,\s+?$])?\((.+?)\))?#is", $definition, $fields, PREG_PATTERN_ORDER ) )
|
||||
|
||||
//-----------------------------------------
|
||||
// Now find all non-primary keys
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match_all( "#(?<!PRIMARY)\s*?KEY\s+?(?:(\w+?)\s+?)?\((.+?)\)(\n|,\n)#is", $definition, $fields ) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// We got some fields!
|
||||
//-----------------------------------------
|
||||
|
||||
if( count( $fields[2] ) )
|
||||
{
|
||||
$i = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Loop over the data from the preg statement
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $fields[2] as $index_cols )
|
||||
{
|
||||
$index_cols = trim( $this->sql_strip_ticks( $index_cols ) );
|
||||
|
||||
$index_name = $fields[1][$i] ? $fields[1][$i] : $index_cols;
|
||||
|
||||
$final_keys[] = array( $index_name, implode( ",", array_map( 'trim', explode( ",", $index_cols ) ) ) );
|
||||
//-----------------------------------------
|
||||
// Get index name, column name, and store
|
||||
//-----------------------------------------
|
||||
|
||||
//$index_cols = implode( ",", array_map( 'trim', explode( ",", $this->_sqlStripTicks( preg_replace( "#\(([^\(]+?)\)#", "", $index_cols ) ) ) ) );
|
||||
$index_cols = implode( ",", array_map( 'trim', explode( ",", $this->_sqlStripTicks( $index_cols ) ) ) );
|
||||
$index_name = $fields[1][$i] ? $fields[1][$i] : $index_cols;
|
||||
|
||||
if( $index_cols != $final_primary[1] )
|
||||
{
|
||||
$final_keys[] = array( $index_name, $index_cols );
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( $table_name AND ( $primary_key OR count($final_keys) ) )
|
||||
//-----------------------------------------
|
||||
// We have some indexes for this table
|
||||
//-----------------------------------------
|
||||
|
||||
if( $tableName AND ( $primary_key OR count($final_keys) ) )
|
||||
{
|
||||
$indexes[] = array( 'table' => $table_name,
|
||||
$indexes[] = array( 'table' => $tableName,
|
||||
'primary' => $final_primary,
|
||||
'index' => $final_keys
|
||||
);
|
||||
@@ -118,106 +187,251 @@ class db_tools
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// No indexes on this table
|
||||
//-----------------------------------------
|
||||
|
||||
if( !count($indexes) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$output = array();
|
||||
//-----------------------------------------
|
||||
// Loop over the indexes
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $indexes as $data )
|
||||
{
|
||||
$table_name = str_replace( "ibf_", "", $data['table']);
|
||||
//-----------------------------------------
|
||||
// Get table schematics and clean it
|
||||
//-----------------------------------------
|
||||
|
||||
$row = $this->ipsclass->DB->sql_get_table_schematic( $table_name );
|
||||
|
||||
$tbl = $this->sql_strip_ticks( $row['Create Table'] );
|
||||
$row = ipsRegistry::DB()->getTableSchematic( $data['table'] );
|
||||
$tbl = $this->_sqlStripTicks( $row['Create Table'] );
|
||||
|
||||
//-----------------------------------------
|
||||
// Start output (one per index)
|
||||
//-----------------------------------------
|
||||
|
||||
$output[ $data['table'] ] = array( 'table' => ipsRegistry::$settings['sql_tbl_prefix'].$data['table'],
|
||||
'status' => 'ok',
|
||||
'missing' => array(),
|
||||
);
|
||||
|
||||
//-----------------------------------------
|
||||
// We had a primary key, so let's look for it
|
||||
//-----------------------------------------
|
||||
|
||||
if( isset( $data['primary'] ) && is_array($data['primary']) AND count($data['primary']) )
|
||||
{
|
||||
$index_name = $data['primary'][0];
|
||||
$column_definition = $data['primary'][1];
|
||||
$index_name = $data['primary'][0];
|
||||
$index_cols = $data['primary'][1];
|
||||
$ok = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Can we find it...?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#\s+?PRIMARY\s+?KEY\s+?\({$index_name}\)?[,\s+?$]?#is", $tbl, $match ) )
|
||||
if ( preg_match( "#\s*PRIMARY\s+?KEY\s*(\((.+?)\))?#is", $tbl, $matches ) )
|
||||
{
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'ok',
|
||||
'message' => '',
|
||||
'fixsql' => '' );
|
||||
$ok = 1;
|
||||
|
||||
//-----------------------------------------
|
||||
// It is...now is the index right (mulicolumn)?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $index_cols != $matches[2] )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Break out the real indexes and loop
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( explode( ',', $index_cols ) as $mc )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// And make sure it's in the definition
|
||||
//-----------------------------------------
|
||||
|
||||
if ( strpos( $match[2], $mc ) === false )
|
||||
{
|
||||
$query_needed = 'ALTER TABLE ' . ipsRegistry::$settings['sql_tbl_prefix'] . $data['table'] . ' DROP INDEX ' . $index_name . ', ADD INDEX ' . $index_name . ' (' . $index_cols . ')';
|
||||
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $data['table'] OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// We got issues gomer!
|
||||
//-----------------------------------------
|
||||
|
||||
$this->has_issues = 1;
|
||||
|
||||
$output[ $data['table'] ]['status'] = 'error';
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
$output[ $data['table'] ]['missing'][] = $index_name;
|
||||
$output[ $data['table'] ]['fixsql'][] = $query_needed;
|
||||
|
||||
$ok = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query_needed = "ALTER TABLE ".SQL_PREFIX."$table_name CHANGE {$index_name} {$index_name} {$column_definition}, ADD PRIMARY KEY ({$index_name})";
|
||||
//-----------------------------------------
|
||||
// Generate query and set the output array
|
||||
//-----------------------------------------
|
||||
|
||||
if( !$this->ipsclass->DB->field_exists( $index_name, $table_name ) )
|
||||
{
|
||||
$query_needed = str_replace( "CHANGE {$index_name}", "ADD", $query_needed );
|
||||
}
|
||||
$query_needed = "ALTER TABLE " . ipsRegistry::$settings['sql_tbl_prefix'] . "{$data['table']} ADD PRIMARY KEY ({$index_name})";
|
||||
|
||||
$this->has_issues = 1;
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'error',
|
||||
'message' => 'Missing primary key',
|
||||
'fixsql' => $query_needed );
|
||||
$error_count++;
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $data['table'] OR $issues_to_fix == 'all' )
|
||||
{
|
||||
$ok = 1;
|
||||
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->has_issues = 1;
|
||||
|
||||
$output[ $data['table'] ]['status'] = 'error';
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
$output[ $data['table'] ]['missing'][] = $index_name;
|
||||
$output[ $data['table'] ]['fixsql'][] = $query_needed;
|
||||
|
||||
$error_count++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Primary key is fine
|
||||
//-----------------------------------------
|
||||
|
||||
if( $ok )
|
||||
{
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Got other indexes?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( isset( $data['index'] ) && is_array( $data['index'] ) and count( $data['index'] ) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Loop over the other indexes
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $data['index'] as $indexes )
|
||||
{
|
||||
$index_name = $indexes[0];
|
||||
$index_cols = $indexes[1] ? $indexes[1] : $index_name;
|
||||
$ok = 0;
|
||||
$index_name = $indexes[0];
|
||||
$index_cols = $indexes[1] ? $indexes[1] : $index_name;
|
||||
|
||||
$ok = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Is the key there?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#(?<!PRIMARY)\s+?KEY\s+?{$index_name}\s+?(\((.+?)\))?#is", $tbl, $match ) )
|
||||
if ( preg_match( "#(?<!PRIMARY)\s+?KEY\s+?{$index_name}\s+?(\((.+?)\))(\n|,\n)#is", $tbl, $match ) )
|
||||
{
|
||||
$ok = 1;
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Multi index column?
|
||||
// It is...now is the index right (mulicolumn)?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $index_cols != $table_cols )
|
||||
if ( $index_cols != $match[2] )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Break out the real indexes and loop
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( explode( ',', $indexes[1] ) as $mc )
|
||||
{
|
||||
if ( ! strstr( $match[2], $mc ) )
|
||||
//-----------------------------------------
|
||||
// And make sure it's in the definition
|
||||
//-----------------------------------------
|
||||
|
||||
if ( strpos( $match[2], str_replace(' ', '', $mc) ) === false )
|
||||
{
|
||||
$this->has_issues = 1;
|
||||
$query_needed = 'ALTER TABLE ' . ipsRegistry::$settings['sql_tbl_prefix'] . $data['table'] . ' DROP INDEX ' . $index_name . ', ADD INDEX ' . $index_name . ' (' . $index_cols . ')';
|
||||
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'error',
|
||||
'message' => 'Missing field \''.$mc.'\'',
|
||||
'fixsql' => 'ALTER TABLE '.SQL_PREFIX.$table_name.' DROP INDEX '.$index_name.', ADD INDEX '.$index_name.' ('.$index_cols.')' );
|
||||
$error_count++;
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $data['table'] OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$this->has_issues = 1;
|
||||
|
||||
$output[ $data['table'] ]['status'] = 'error';
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
$output[ $data['table'] ]['missing'][] = $index_name;
|
||||
$output[ $data['table'] ]['fixsql'][] = $query_needed;
|
||||
|
||||
$ok = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'error',
|
||||
'message' => 'Missing index \''.$index_name.'\'',
|
||||
'fixsql' => 'ALTER TABLE '.SQL_PREFIX.$table_name.' ADD INDEX '.$index_name.'('.$index_cols.')' );
|
||||
$error_count++;
|
||||
//-----------------------------------------
|
||||
// Generate query and set the output array
|
||||
//-----------------------------------------
|
||||
|
||||
$query_needed = 'ALTER TABLE ' . ipsRegistry::$settings['sql_tbl_prefix'] . $data['table'] . ' ADD INDEX ' . $index_name . ' (' . $index_cols . ')';
|
||||
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $data['table'] OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
|
||||
$ok = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$output[ $data['table'] ]['status'] = 'error';
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
$output[ $data['table'] ]['missing'][] = $index_name;
|
||||
$output[ $data['table'] ]['fixsql'][] = $query_needed;
|
||||
|
||||
$error_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// The index is ok
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $ok )
|
||||
{
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'ok',
|
||||
'message' => '',
|
||||
'fixsql' => '' );
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,127 +441,271 @@ class db_tools
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Diagnose the DB tables
|
||||
// @input sql_statements array of create table statements to check
|
||||
// @output array array of results ( key, table, status, message, fixsql )
|
||||
//-------------------------------------------------------------
|
||||
|
||||
function db_table_diag( & $sql_statements )
|
||||
/**
|
||||
* Diagnose table structure
|
||||
*
|
||||
* @access public
|
||||
* @param array Array of create table/index statements to check
|
||||
* @param array Array of issues to fix
|
||||
* @return array Array of results
|
||||
*/
|
||||
public function dbTableDiag( $sql_statements, $issues_to_fix='' )
|
||||
{
|
||||
$queries_needed = array();
|
||||
$tables_needed = array();
|
||||
$error_count = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Init
|
||||
//-----------------------------------------
|
||||
|
||||
$queries_needed = array();
|
||||
$tables_needed = array();
|
||||
$table_definitions = array();
|
||||
$error_count = 0;
|
||||
$_tablesFull = array();
|
||||
$_tablesAlter = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Do we have any statements?
|
||||
//-----------------------------------------
|
||||
|
||||
if( is_array( $sql_statements ) && count( $sql_statements ) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Loop over those statements
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $sql_statements as $the_table )
|
||||
{
|
||||
$expected_columns = array();
|
||||
|
||||
if( preg_match("#CREATE TABLE\s+?(.+?)\s+?\(#ie", $the_table, $bits))
|
||||
$expected_columns = array();
|
||||
$missing_columns = array();
|
||||
|
||||
/* Remove backticks */
|
||||
$the_table = str_replace( '`', '', $the_table );
|
||||
|
||||
//-----------------------------------------
|
||||
// Is this a create table statement?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_match( "#CREATE\s+TABLE\s+?(.+?)\s+?\(#ie", $the_table, $definition ) )
|
||||
{
|
||||
$tbl_name = $bits[1];
|
||||
$tbl_name = str_replace( "ibf_", "", $tbl_name );
|
||||
$tableName = ipsRegistry::$settings['sql_tbl_prefix'] . $definition[1];
|
||||
|
||||
$table_defs[$tbl_name] = str_replace( "ibf_", SQL_PREFIX, $the_table );
|
||||
//-----------------------------------------
|
||||
// Store the entire table definition
|
||||
//-----------------------------------------
|
||||
|
||||
$table_definitions[ $tableName ] = str_replace( $definition[1], $tableName, $the_table );
|
||||
$_tablesFull[] = $tableName;
|
||||
|
||||
//-----------------------------------------
|
||||
// Get the columns
|
||||
//-----------------------------------------
|
||||
|
||||
// Get the columns and lose the first line (it's the table name)
|
||||
$columns_array = explode( "\n", $the_table );
|
||||
|
||||
//-----------------------------------------
|
||||
// Get rid of first row ("CREATE TABLE ...")
|
||||
//-----------------------------------------
|
||||
|
||||
array_shift($columns_array);
|
||||
|
||||
// Get rid of the end junk
|
||||
if ( (strpos(end($columns_array), ");") == 0) ||
|
||||
(strpos(end($columns_array), ")") == 0) ||
|
||||
(strpos(end($columns_array), ";") == 0) )
|
||||
//-----------------------------------------
|
||||
// Get rid of the junk at the end of each line
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ( strpos(end($columns_array), ");") === 0 ) OR
|
||||
( strpos(end($columns_array), ")") === 0 ) OR
|
||||
( strpos(end($columns_array), ";") === 0 ) )
|
||||
{
|
||||
array_pop($columns_array);
|
||||
}
|
||||
|
||||
|
||||
reset($columns_array);
|
||||
|
||||
//-----------------------------------------
|
||||
// Loop over each supposed "column"
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $columns_array as $col )
|
||||
{
|
||||
$temp = preg_split( "/[\s]+/" , $col );
|
||||
$col_name = trim( next( $temp ) );
|
||||
//-----------------------------------------
|
||||
// Find the column name
|
||||
//-----------------------------------------
|
||||
|
||||
if( $col_name != "PRIMARY" &&
|
||||
$col_name != "KEY" &&
|
||||
$col_name != "UNIQUE" &&
|
||||
$col_name != "" &&
|
||||
$col_name != "(" &&
|
||||
$col_name != ";" &&
|
||||
$col_name != ");" )
|
||||
$temp = preg_split( "/[\s]+/" , trim($col) );
|
||||
$columnName = $temp[0];
|
||||
|
||||
//-----------------------------------------
|
||||
// If this is a real column, map it
|
||||
//-----------------------------------------
|
||||
|
||||
if( !in_array( $columnName, array( "PRIMARY", "KEY", "UNIQUE", "", "(", ";", ");" ) ) )
|
||||
{
|
||||
$expected_columns[] = $col_name;
|
||||
$this->columns_to_defs[$tbl_name][$col_name] = trim( str_replace( ',', ';', $col ) );
|
||||
$expected_columns[] = $columnName;
|
||||
$this->_mapping[ $tableName ][ $columnName ] = trim( str_replace( ',', ';', $col ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( preg_match("#ALTER TABLE ([a-z_]*) ADD ([a-z_]*) #is", $the_table, $bits) )
|
||||
|
||||
//-----------------------------------------
|
||||
// This an alter table statement?
|
||||
//-----------------------------------------
|
||||
|
||||
elseif ( preg_match( "#ALTER\s+TABLE\s+([a-z_]*)\s+ADD\s+([a-z_]*)\s+#is", $the_table, $definition ) )
|
||||
{
|
||||
if( $bits[1] != "" &&
|
||||
$bits[2] != "" &&
|
||||
$bits[2] != 'INDEX' &&
|
||||
strpos($bits[2], 'TYPE') === false )
|
||||
//-----------------------------------------
|
||||
// If this is truly adding a new column, map it
|
||||
//-----------------------------------------
|
||||
|
||||
if( $definition[1] AND $definition[2] AND $definition[2] != 'INDEX' AND strpos($definition[2], 'TYPE') === false AND strpos($definition[2], 'ENGINE') === false )
|
||||
{
|
||||
$tbl_name = trim($bits[1]);
|
||||
$tbl_name = str_replace( "ibf_", "", $tbl_name );
|
||||
$col_name = trim($bits[2]);
|
||||
|
||||
$expected_columns[] = $col_name;
|
||||
$this->columns_to_defs[$tbl_name][$col_name] = str_replace( $bits[1], SQL_PREFIX . $tbl_name, $the_table ) . ";";
|
||||
$tableName = ipsRegistry::$settings['sql_tbl_prefix'] . trim( $definition[1] );
|
||||
$columnName = trim($definition[2]);
|
||||
$_tablesAlter[] = $tableName;
|
||||
|
||||
$expected_columns[] = $columnName;
|
||||
$this->_mapping[ $tableName ][ $columnName ] = $definition[2] . ' ' . str_replace( $definition[0], '', $the_table ) . ";";
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// We don't care about any other queries
|
||||
//-----------------------------------------
|
||||
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the current schema....
|
||||
$this->ipsclass->DB->return_die = 1;
|
||||
|
||||
if ( ! $this->ipsclass->DB->table_exists( $tbl_name ) )
|
||||
|
||||
//-----------------------------------------
|
||||
// Don't die on me sarge!
|
||||
//-----------------------------------------
|
||||
|
||||
ipsRegistry::DB()->return_die = 1;
|
||||
|
||||
$tableNoPrefix = preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $tableName );
|
||||
|
||||
//-----------------------------------------
|
||||
// If table is missing entirely, we need to build it
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! ipsRegistry::DB()->checkForTable( $tableNoPrefix ) )
|
||||
{
|
||||
$output[] = array( 'key' => $tbl_name,
|
||||
'table' => SQL_PREFIX.$tbl_name,
|
||||
'status' => 'error',
|
||||
'message' => 'missing table',
|
||||
'fixsql' => $table_defs[$tbl_name] );
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $tableNoPrefix OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $table_definitions[ $tableName ] );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$output[ $tableName ] = array( 'key' => $tableNoPrefix,
|
||||
'table' => $tableName,
|
||||
'status' => 'error_table',
|
||||
'fixsql' => array( $table_definitions[ $tableName ] )
|
||||
);
|
||||
|
||||
//-----------------------------------------
|
||||
// Increment error counter
|
||||
//-----------------------------------------
|
||||
|
||||
$error_count++;
|
||||
$this->ipsclass->DB->failed = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Reset failed status
|
||||
//-----------------------------------------
|
||||
|
||||
ipsRegistry::DB()->failed = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Table exists...
|
||||
//-----------------------------------------
|
||||
|
||||
else
|
||||
{
|
||||
// Here we go...
|
||||
$missing = array();
|
||||
//-----------------------------------------
|
||||
// Loop over all the columns
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $expected_columns as $trymeout )
|
||||
{
|
||||
if( ! $this->ipsclass->DB->field_exists( $trymeout, $tbl_name ) )
|
||||
//-----------------------------------------
|
||||
// Does column exist?
|
||||
//-----------------------------------------
|
||||
|
||||
if( ! ipsRegistry::DB()->checkForField( $trymeout, $tableNoPrefix ) )
|
||||
{
|
||||
$missing[] = $trymeout;
|
||||
$query_needed = "ALTER TABLE " . SQL_PREFIX . $tbl_name . " ADD " . $this->columns_to_defs[$tbl_name][$trymeout];
|
||||
//-----------------------------------------
|
||||
// Missing - create "ALTER TABLE" query
|
||||
//-----------------------------------------
|
||||
|
||||
$query_needed = "ALTER TABLE " . $tableName . " ADD " . $this->_mapping[ $tableName ][ $trymeout ];
|
||||
|
||||
if( preg_match( "/auto_increment;/", $query_needed ) )
|
||||
//-----------------------------------------
|
||||
// If this is an autoincrement column, we need
|
||||
// to add the primary key, since it won't exist
|
||||
//-----------------------------------------
|
||||
|
||||
if( strpos( $query_needed, "auto_increment;" ) !== false )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Cut off the ";", add primary key bit
|
||||
//-----------------------------------------
|
||||
|
||||
$query_needed = substr( $query_needed, 0, -1 ).", ADD PRIMARY KEY( ". $trymeout . ");";
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $tableNoPrefix OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$missing_columns[] = $trymeout;
|
||||
|
||||
//-----------------------------------------
|
||||
// We only do this once
|
||||
//-----------------------------------------
|
||||
|
||||
if( !isset($output[ $tableName ]) OR !count($output[ $tableName ]) )
|
||||
{
|
||||
$output[ $tableName ] = array( 'key' => $tableNoPrefix,
|
||||
'table' => $tableName,
|
||||
'status' => 'error_column',
|
||||
);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// But with each error, add the query
|
||||
//-----------------------------------------
|
||||
|
||||
$output[ $tableName ]['fixsql'][] = $query_needed;
|
||||
|
||||
//-----------------------------------------
|
||||
// Increment error count
|
||||
//-----------------------------------------
|
||||
|
||||
$output[] = array( 'key' => $tbl_name.$trymeout,
|
||||
'table' => SQL_PREFIX.$tbl_name,
|
||||
'status' => 'error',
|
||||
'message' => 'Missing column \''.$trymeout.'\'',
|
||||
'fixsql' => $query_needed );
|
||||
$error_count++;
|
||||
}
|
||||
}
|
||||
if( !count( $missing ) )
|
||||
|
||||
//-----------------------------------------
|
||||
// If nothing was wrong, show ok message
|
||||
//-----------------------------------------
|
||||
|
||||
if( !count( $missing_columns ) )
|
||||
{
|
||||
$output[] = array( 'key' => $tbl_name,
|
||||
'table' => SQL_PREFIX.$tbl_name,
|
||||
$output[] = array( 'key' => $tableNoPrefix,
|
||||
'table' => $tableName,
|
||||
'column' => in_array( $tableName, $_tablesFull ) ? '' : $trymeout,
|
||||
'status' => 'ok',
|
||||
'message' => '',
|
||||
'fixsql' => '' );
|
||||
}
|
||||
}
|
||||
@@ -358,11 +716,14 @@ class db_tools
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// sql_strip_ticks from field names
|
||||
//-----------------------------------------
|
||||
|
||||
function sql_strip_ticks($data)
|
||||
/**
|
||||
* Remove ticks from statement
|
||||
*
|
||||
* @access private
|
||||
* @param string String
|
||||
* @return string String with ticks removed
|
||||
*/
|
||||
private function _sqlStripTicks( $data )
|
||||
{
|
||||
return str_replace( "`", "", $data );
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user