1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-06 06:38:00 +02:00

update routine: fixed missing FULLTEXT index case

This commit is contained in:
secretr
2009-09-13 20:22:39 +00:00
parent 70ad1fa8b1
commit a34c668941
2 changed files with 593 additions and 475 deletions

View File

@@ -3,7 +3,7 @@
+ ----------------------------------------------------------------------------+ + ----------------------------------------------------------------------------+
| e107 website system | e107 website system
| |
| <EFBFBD>Steve Dunstan 2001-2002 | Steve Dunstan 2001-2002
| http://e107.org | http://e107.org
| jalist@e107.org | jalist@e107.org
| |
@@ -11,9 +11,9 @@
| GNU General Public License (http://gnu.org). | GNU General Public License (http://gnu.org).
| |
| $Source: /cvs_backup/e107_0.8/e107_admin/update_routines.php,v $ | $Source: /cvs_backup/e107_0.8/e107_admin/update_routines.php,v $
| $Revision: 1.50 $ | $Revision: 1.51 $
| $Date: 2009-09-10 09:26:54 $ | $Date: 2009-09-13 20:22:39 $
| $Author: e107coders $ | $Author: secretr $
+----------------------------------------------------------------------------+ +----------------------------------------------------------------------------+
*/ */
@@ -264,7 +264,7 @@ function update_706_to_800($type='')
// List of changed DB tables from core plugins (defined in pluginname_sql.php file) // List of changed DB tables from core plugins (defined in pluginname_sql.php file)
// key = plugin directory nane. Data = comma-separated list of tables to check // key = plugin directory name. Data = comma-separated list of tables to check
// (primarily those which have changed significantly; for the odd field write some explicit code - it'll run faster) // (primarily those which have changed significantly; for the odd field write some explicit code - it'll run faster)
$pluginChangedTables = array('linkwords' => 'linkwords'); $pluginChangedTables = array('linkwords' => 'linkwords');

View File

@@ -1,33 +1,29 @@
<?php <?php
/* /*
+----------------------------------------------------------------------------+ * e107 website system
| e107 website system *
| * Copyright (C) 2001-2008 e107 Inc (e107.org)
| <20>Steve Dunstan 2001-2002 * Released under the terms and conditions of the
| http://e107.org * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
| jalist@e107.org *
| * Database utilities
| Released under the terms and conditions of the *
| GNU General Public License (http://gnu.org). * $Source: /cvs_backup/e107_0.8/e107_handlers/db_table_admin_class.php,v $
| * $Revision: 1.10 $
| $Source: /cvs_backup/e107_0.8/e107_handlers/db_table_admin_class.php,v $ * $Date: 2009-09-13 20:22:39 $
| $Revision: 1.9 $ * $Author: secretr $
| $Date: 2009-08-17 15:45:20 $
| $Author: e107coders $
+----------------------------------------------------------------------------+
*/ */
/* /*
Database utilities for admin tasks: Database utilities for admin tasks:
Get structure of a table from a database Get structure of a table from a database
Get structure of a table from a file Get structure of a table from a file
First level parse of table structure First level parse of table structure
Parse of field definitions part of table structure Parse of field definitions part of table structure
Comparison of two structures, including generation of MySQL to make them the same Comparison of two structures, including generation of MySQL to make them the same
Some crude printing utilities Some crude printing utilities
Note: there are some uncommented 'echo' statements which are intentional to highlight that something's gone wrong! (not that it should, of course)
Note: there are some uncommented 'echo' statements which are intentional to highlight that something's gone wrong! (not that it should, of course) */
*/
class db_table_admin class db_table_admin
{ {
@@ -40,20 +36,31 @@ class db_table_admin
{ {
global $sql; global $sql;
if (!$prefix) { $prefix = MPREFIX; } if (!$prefix)
{
$prefix = MPREFIX;
}
// echo "Get table structure for: {$table_name}, prefix: {$prefix}<br />"; // echo "Get table structure for: {$table_name}, prefix: {$prefix}<br />";
$sql->db_Select_gen('SET SQL_QUOTE_SHOW_CREATE = 1'); $sql->db_Select_gen('SET SQL_QUOTE_SHOW_CREATE = 1');
$qry = 'SHOW CREATE TABLE `'.$prefix.$table_name."`"; $qry = 'SHOW CREATE TABLE `'.$prefix.$table_name."`";
if (!($z = $sql->db_Select_gen($qry))) { return FALSE; } if (!($z = $sql->db_Select_gen($qry)))
{
return FALSE;
}
$row = $sql->db_Fetch(MYSQL_NUM); $row = $sql->db_Fetch(MYSQL_NUM);
$tmp = str_replace("`", "", stripslashes($row[1])).';'; // Add semicolon to work with our parser $tmp = str_replace("`", "", stripslashes($row[1])).';'; // Add semicolon to work with our parser
$count = preg_match_all("#CREATE\s+?TABLE\s+?`{0,1}({$prefix}{$table_name})`{0,1}\s+?\((.*?)\)\s+?(?:TYPE|ENGINE)\s*\=\s*(.*?);#is",$tmp,$matches,PREG_SET_ORDER); $count = preg_match_all("#CREATE\s+?TABLE\s+?`{0,1}({$prefix}{$table_name})`{0,1}\s+?\((.*?)\)\s+?(?:TYPE|ENGINE)\s*\=\s*(.*?);#is", $tmp, $matches, PREG_SET_ORDER);
if ($count === FALSE) { return "Error occurred";} if ($count === FALSE)
if (!$count) { return "No matches"; } {
return "Error occurred";
}
if (!$count)
{
return "No matches";
}
return $matches; return $matches;
} }
// Routine to do first-level parse of table structure // Routine to do first-level parse of table structure
//--------------------------------------------------- //---------------------------------------------------
// Given the name of a file, returns an array, with each element being a table creation definition. // Given the name of a file, returns an array, with each element being a table creation definition.
@@ -67,52 +74,68 @@ class db_table_admin
// [2] - Field definitions, with the surrounding (...) stripped // [2] - Field definitions, with the surrounding (...) stripped
// [3] - The 'TYPE' field ('TYPE=' is stripped) and any AUTO-INCREMENT definition or other text. // [3] - The 'TYPE' field ('TYPE=' is stripped) and any AUTO-INCREMENT definition or other text.
// function get_table_def($table_name='',$file_name = e_ADMIN."sql/core_sql.php") // function get_table_def($table_name='',$file_name = e_ADMIN."sql/core_sql.php")
function get_table_def($table_name='',$file_name ="") function get_table_def($table_name = '', $file_name = "")
{ {
if ($file_name != '') if ($file_name != '')
{ // Read in and buffer a new file (if we've not already got one) { // Read in and buffer a new file (if we've not already got one)
if ($this->last_file != $file_name) if ($this->last_file != $file_name)
{ {
if (!is_readable($file_name)) { return "No file"; } if (!is_readable($file_name))
{
return "No file";
}
$temp = file_get_contents($file_name); $temp = file_get_contents($file_name);
// Strip any php header // Strip any php header
$this->file_buffer = preg_replace("#\<\?php.*?\?\>#mis",'',$temp); $this->file_buffer = preg_replace("#\<\?php.*?\?\>#mis", '', $temp);
$this->last_file = $file_name; $this->last_file = $file_name;
} }
} }
if (!$table_name) { $table_name = '\w+?'; } if (!$table_name)
{
$table_name = '\w+?';
}
// Regex should be identical to that in get_current_table (apart from the source text variable name) // Regex should be identical to that in get_current_table (apart from the source text variable name)
$count = preg_match_all("#CREATE\s+?TABLE\s+?`{0,1}({$table_name})`{0,1}\s+?\((.*?)\)\s+?(?:TYPE|ENGINE)\s*\=\s*(.*?);#is",$this->file_buffer,$matches,PREG_SET_ORDER); $count = preg_match_all("#CREATE\s+?TABLE\s+?`{0,1}({$table_name})`{0,1}\s+?\((.*?)\)\s+?(?:TYPE|ENGINE)\s*\=\s*(.*?);#is", $this->file_buffer, $matches, PREG_SET_ORDER);
if ($count === false) { return "Error occurred"; } if ($count === false)
if (!$count) { return "No matches"; } {
return "Error occurred";
}
if (!$count)
{
return "No matches";
}
return $matches; return $matches;
} }
// Parses the block of lines which make up the field and index definitions // Parses the block of lines which make up the field and index definitions
// Returns an array where each entry is the definitions of a field or index // Returns an array where each entry is the definitions of a field or index
function parse_field_defs($text) function parse_field_defs($text)
{ {
$ans = array(); $ans = array(
$text = str_replace("\r","\n",$text); );
$field_lines = explode("\n",$text); $text = str_replace("\r", "\n", $text);
$field_lines = explode("\n", $text);
foreach ($field_lines as $fv) foreach ($field_lines as $fv)
{ {
unset($defs); unset($defs);
$fv = trim(str_replace(' ',' ',$fv)); $fv = trim(str_replace(' ', ' ', $fv));
if (substr($fv,-1) == ',') { $fv = trim(substr($fv,0,-1)); } if (substr($fv, -1) == ',')
{
$fv = trim(substr($fv, 0, -1));
}
// echo "Line: ".$fv."<br />"; // echo "Line: ".$fv."<br />";
if ($fv) if ($fv)
{ {
$fd = explode(' ',$fv); $fd = explode(' ', $fv);
switch (strtoupper($fd[0])) switch (strtoupper($fd[0]))
{ {
case 'PRIMARY' : case 'PRIMARY':
if (strtoupper($fd[1]) == 'KEY') if (strtoupper($fd[1]) == 'KEY')
$defs['type'] = 'pkey'; $defs['type'] = 'pkey';
$defs['name'] = $fd[2]; $defs['name'] = $fd[2];
break; break;
case 'UNIQUE' :
case 'UNIQUE':
if (count($fd) < 3) if (count($fd) < 3)
{ {
echo "Truncated definition after UNIQUE {$i}: ".$fd[1]."<br />"; echo "Truncated definition after UNIQUE {$i}: ".$fd[1]."<br />";
@@ -121,17 +144,38 @@ class db_table_admin
{ {
$defs['type'] = 'ukey'; $defs['type'] = 'ukey';
$defs['name'] = $fd[2]; $defs['name'] = $fd[2];
if (isset($fd[3])) $defs['keyfield'] = $fd[3]; else $defs['keyfield'] = '['.$fd[2].']'; if (isset($fd[3])) $defs['keyfield'] = $fd[3];
else $defs['keyfield'] = '['.$fd[2].']';
} }
else else
{ {
echo "Unrecognised word after UNIQUE in definition {$i}: ".$fd[1]."<br />"; echo "Unrecognised word after UNIQUE in definition {$i}: ".$fd[1]."<br />";
} }
break; break;
case 'KEY' :
case 'FULLTEXT':
if (count($fd) < 3)
{
echo "Truncated definition after FULLTEXT {$i}: ".$fd[1]."<br />";
}
elseif (strtoupper($fd[1]) == 'KEY')
{
$defs['type'] = 'ftkey';
$defs['name'] = $fd[2];
if (isset($fd[3])) $defs['keyfield'] = $fd[3];
else $defs['keyfield'] = '['.$fd[2].']';
}
else
{
echo "Unrecognised word after FULLTEXT in definition {$i}: ".$fd[1]."<br />";
}
break;
case 'KEY':
$defs['type'] = 'key'; $defs['type'] = 'key';
$defs['name'] = $fd[1]; $defs['name'] = $fd[1];
if (isset($fd[2])) { if (isset($fd[2]))
{
$defs['keyfield'] = $fd[2]; $defs['keyfield'] = $fd[2];
} }
else else
@@ -139,12 +183,12 @@ class db_table_admin
$defs['keyfield'] = '['.$fd[1].']'; $defs['keyfield'] = '['.$fd[1].']';
} }
break; break;
default : // Must be a DB field name default: // Must be a DB field name
$defs['type'] = 'field'; $defs['type'] = 'field';
$defs['name'] = $fd[0]; $defs['name'] = $fd[0];
$defs['fieldtype'] = $fd[1]; $defs['fieldtype'] = $fd[1];
$i = 2; // First unused field $i = 2; // First unused field
if ((strpos($fd[1],'int') === 0) || (strpos($fd[1],'tinyint') === 0) || (strpos($fd[1],'smallint') === 0) || (strpos($fd[1],'bigint') === 0)) if ((strpos($fd[1], 'int') === 0) || (strpos($fd[1], 'tinyint') === 0) || (strpos($fd[1], 'smallint') === 0) || (strpos($fd[1], 'bigint') === 0))
{ {
if (isset($fd[2]) && (strtoupper($fd[2]) == 'UNSIGNED')) if (isset($fd[2]) && (strtoupper($fd[2]) == 'UNSIGNED'))
{ {
@@ -154,33 +198,33 @@ class db_table_admin
} }
while ($i < count($fd)) while ($i < count($fd))
{ {
switch(strtoupper($fd[$i])) switch (strtoupper($fd[$i]))
{ {
case 'NOT' : case 'NOT':
if (isset($fd[$i+1]) && strtoupper($fd[$i+1]) == 'NULL') if (isset($fd[$i + 1]) && strtoupper($fd[$i + 1]) == 'NULL')
{ {
$i++; $i++;
$defs['nulltype'] = 'NOT NULL'; $defs['nulltype'] = 'NOT NULL';
} }
else else
{ // Syntax error { // Syntax error
echo "Unrecognised word in definition {$i} after 'NOT': ".$fd[$i+1]."<br />"; echo "Unrecognised word in definition {$i} after 'NOT': ".$fd[$i + 1]."<br />";
} }
break; break;
case 'DEFAULT' : case 'DEFAULT':
if (isset($fd[$i+1])) if (isset($fd[$i + 1]))
{ {
$i++; $i++;
$defs['default'] = $fd[$i]; $defs['default'] = $fd[$i];
} }
break; break;
case 'COLLATE' : case 'COLLATE':
$i++; // Just skip over - we ignore collation $i++; // Just skip over - we ignore collation
break; break;
case 'AUTO_INCREMENT' : case 'AUTO_INCREMENT':
$defs['autoinc'] = TRUE; $defs['autoinc'] = TRUE;
break; break;
default : default:
echo "Unknown definition {$i}: ".$fd[$i]."<br />"; echo "Unknown definition {$i}: ".$fd[$i]."<br />";
} }
$i++; $i++;
@@ -196,53 +240,76 @@ class db_table_admin
} }
} }
} }
if (!count($ans)) { return FALSE; } if (!count($ans))
{
return FALSE;
}
return $ans; return $ans;
} }
// Utility routine - given our array-based definition, create a string MySQL field definition // Utility routine - given our array-based definition, create a string MySQL field definition
function make_def($list) function make_def($list)
{ {
switch ($list['type']) switch ($list['type'])
{ {
case 'key' : case 'key':
return 'KEY '.$list['name'].' ('.str_replace(array('(',')'),'',$list['keyfield']).')'; return 'KEY '.$list['name'].' ('.str_replace(array( '(', ')' ), '', $list['keyfield']).')';
case 'ukey' : case 'ukey':
return 'UNIQUE KEY '.$list['name'].' ('.$list['name'].')'; return 'UNIQUE KEY '.$list['name'].' ('.str_replace(array( '(', ')' ), '', $list['keyfield']).')';
case 'pkey' : case 'ftkey':
return 'FULLTEXT KEY '.$list['name'].' ('.str_replace(array( '(', ')' ), '', $list['keyfield']).')';
case 'pkey':
return 'PRIMARY KEY ('.$list['name'].')'; return 'PRIMARY KEY ('.$list['name'].')';
case 'field' : // Require a field - got a key. so add a field at the end case 'field': // Require a field - got a key. so add a field at the end
$def = $list['name']; $def = $list['name'];
if (isset($list['fieldtype'])) { $def .= ' '.$list['fieldtype']; } if (isset($list['fieldtype']))
if (isset($list['vartype'])) { $def .= ' '.$list['vartype']; } {
if (isset($list['nulltype'])) { $def .= ' '.$list['nulltype']; } $def .= ' '.$list['fieldtype'];
if (isset($list['default'])) { $def .= ' default '.$list['default']; } }
if (varsettrue($list['autoinc'])) { $def .= ' auto_increment'; } if (isset($list['vartype']))
{
$def .= ' '.$list['vartype'];
}
if (isset($list['nulltype']))
{
$def .= ' '.$list['nulltype'];
}
if (isset($list['default']))
{
$def .= ' default '.$list['default'];
}
if (varsettrue($list['autoinc']))
{
$def .= ' auto_increment';
}
return $def; return $def;
} }
return "Cannot generate definition for: ".$list['type'].' '.$list['name']; return "Cannot generate definition for: ".$list['type'].' '.$list['name'];
} }
// Compare two field/index lists as generated by parse_field_defs // Compare two field/index lists as generated by parse_field_defs
// If $stop_on_error is TRUE, returns TRUE if the same, false if different // If $stop_on_error is TRUE, returns TRUE if the same, false if different
// Return a text list of differences, plus an array of MySQL queries to fix // Return a text list of differences, plus an array of MySQL queries to fix
// List1 is the reference, List 2 is the actual // List1 is the reference, List 2 is the actual
// This version looks ahead on a failed match, and moves a field up in the table if already defined - should retain as much as possible // This version looks ahead on a failed match, and moves a field up in the table if already defined - should retain as much as possible
function compare_field_lists($list1, $list2, $stop_on_error=FALSE) function compare_field_lists($list1, $list2, $stop_on_error = FALSE)
{ {
$i = 0; // Counts records in list1 (required format) $i = 0; // Counts records in list1 (required format)
$j = 0; // Counts records in $created_list (our 'table so far' list) $j = 0; // Counts records in $created_list (our 'table so far' list)
$error_list = array(); // Free text list of differences $error_list = array(
$change_list = array(); // MySQL statements to implement changes ); // Free text list of differences
$created_list = array(); // List of field defs that we build up (just names) $change_list = array(
); // MySQL statements to implement changes
$created_list = array(
); // List of field defs that we build up (just names)
while ($i < count($list1)) while ($i < count($list1))
{ {
if (count($list2) == 0) if (count($list2) == 0)
{ // Missing field at end { // Missing field at end
if ($stop_on_error) { return FALSE; } if ($stop_on_error)
{
return FALSE;
}
$error_list[] = 'Missing field at end: '.$list1[$i]['name']; $error_list[] = 'Missing field at end: '.$list1[$i]['name'];
$change_list[] = 'ADD '.$this->make_def($list1[$i]); $change_list[] = 'ADD '.$this->make_def($list1[$i]);
$created_list[$j] = $list1[$i]['name']; $created_list[$j] = $list1[$i]['name'];
@@ -251,15 +318,18 @@ class db_table_admin
elseif ($list1[$i]['type'] == $list2[0]['type']) elseif ($list1[$i]['type'] == $list2[0]['type'])
{ // Worth doing a compare - fields are same type { // Worth doing a compare - fields are same type
// echo $i.': compare - '.$list1[$i]['name'].', '.$list2[0]['name'].'<br />'; // echo $i.': compare - '.$list1[$i]['name'].', '.$list2[0]['name'].'<br />';
if (strcasecmp($list1[$i]['name'],$list2[0]['name']) != 0) if (strcasecmp($list1[$i]['name'], $list2[0]['name']) != 0)
{ // Names differ, so need to add or subtract a field. { // Names differ, so need to add or subtract a field.
// echo $i.': names differ - '.$list1[$i]['name'].', '.$list2[0]['name'].'<br />'; // echo $i.': names differ - '.$list1[$i]['name'].', '.$list2[0]['name'].'<br />';
if ($stop_on_error) { return FALSE; } if ($stop_on_error)
{
return FALSE;
}
$found = FALSE; $found = FALSE;
for ($k = $i+1; $k < count($list1); $k++) for ($k = $i + 1; $k < count($list1); $k++)
{ {
// echo "Compare ".$list1[$k]['name'].' with '.$list2[0]['name']; // echo "Compare ".$list1[$k]['name'].' with '.$list2[0]['name'];
if (strcasecmp($list1[$k]['name'],$list2[0]['name']) == 0) if (strcasecmp($list1[$k]['name'], $list2[0]['name']) == 0)
{ // Field in list2 found later in list1; do nothing { // Field in list2 found later in list1; do nothing
// echo " - match<br />"; // echo " - match<br />";
$found = TRUE; $found = TRUE;
@@ -280,7 +350,7 @@ class db_table_admin
for ($k = 0; $k < count($list2); $k++) for ($k = 0; $k < count($list2); $k++)
{ {
// echo "Compare ".$list1[$i]['name'].' with '.$list2[$k]['name']; // echo "Compare ".$list1[$i]['name'].' with '.$list2[$k]['name'];
if (strcasecmp($list1[$i]['name'],$list2[$k]['name']) == 0) if (strcasecmp($list1[$i]['name'], $list2[$k]['name']) == 0)
{ // Field found; we need to move it up { // Field found; we need to move it up
// echo " - match<br />"; // echo " - match<br />";
$found = TRUE; $found = TRUE;
@@ -291,8 +361,8 @@ class db_table_admin
if ($found) if ($found)
{ {
$error_list[] = 'Field out of position: '.$list2[$k]['name']; $error_list[] = 'Field out of position: '.$list2[$k]['name'];
$change_list[] = 'MODIFY '.$this->make_def($list1[$i]).(count($created_list) ? ' AFTER '.$created_list[count($created_list)-1] : ' FIRST'); $change_list[] = 'MODIFY '.$this->make_def($list1[$i]).(count($created_list) ? ' AFTER '.$created_list[count($created_list) - 1] : ' FIRST');
array_splice($list2,$k,1); // Finished with this element - delete it, and renumber the keys array_splice($list2, $k, 1); // Finished with this element - delete it, and renumber the keys
$created_list[$j] = $list1[$i]['name']; $created_list[$j] = $list1[$i]['name'];
$j++; $j++;
// The above also amends any parameters as necessary // The above also amends any parameters as necessary
@@ -302,17 +372,18 @@ class db_table_admin
$error_list[] = 'Missing field: '.$list1[$i]['name'].' (found: '.$list2[0]['type'].' '.$list2[0]['name'].')'; $error_list[] = 'Missing field: '.$list1[$i]['name'].' (found: '.$list2[0]['type'].' '.$list2[0]['name'].')';
switch ($list1[$i]['type']) switch ($list1[$i]['type'])
{ {
case 'key' : case 'key':
case 'ukey' : case 'ukey':
case 'pkey' : // Require a key case 'ftkey':
case 'pkey': // Require a key
$change_list[] = 'ADD '.$this->make_def($list1[$i]); $change_list[] = 'ADD '.$this->make_def($list1[$i]);
$error_list[] = 'Missing index: '.$list1[$i]['name']; $error_list[] = 'Missing index: '.$list1[$i]['name'];
$created_list[$j] = $list1[$i]['name']; $created_list[$j] = $list1[$i]['name'];
$j++; $j++;
break; break;
case 'field' : case 'field':
$change_list[] = 'ADD '.$this->make_def($list1[$i]).(count($created_list) ? ' AFTER '.$created_list[count($created_list)-1] : ' FIRST'); $change_list[] = 'ADD '.$this->make_def($list1[$i]).(count($created_list) ? ' AFTER '.$created_list[count($created_list) - 1] : ' FIRST');
$error_list[] = 'Missing field: '.$list1[$i]['name'].' (found: '.$list2[0]['type'].' '.$list2[0]['name'].')'; $error_list[] = 'Missing field: '.$list1[$i]['name'].' (found: '.$list2[0]['type'].' '.$list2[0]['name'].')';
$created_list[$j] = $list1[$i]['name']; $created_list[$j] = $list1[$i]['name'];
$j++; $j++;
@@ -324,14 +395,23 @@ class db_table_admin
{ // Field/index is present as required; may be changes though { // Field/index is present as required; may be changes though
// Any difference and we need to update the table // Any difference and we need to update the table
// echo $i.': name match - '.$list1[$i]['name'].'<br />'; // echo $i.': name match - '.$list1[$i]['name'].'<br />';
foreach ($list1[$i] as $fi => $v) foreach ($list1[$i] as $fi=>$v)
{ {
$t = $list2[0][$fi]; $t = $list2[0][$fi];
if (stripos($v,'varchar') !== FALSE) { $v = substr($v,3); } // Treat char, varchar the same if (stripos($v, 'varchar') !== FALSE)
if (stripos($t,'varchar') !== FALSE) { $t = substr($t,3); } // Treat char, varchar the same
if (strcasecmp($t , $v) !== 0)
{ {
if ($stop_on_error) { return FALSE; } $v = substr($v, 3);
} // Treat char, varchar the same
if (stripos($t, 'varchar') !== FALSE)
{
$t = substr($t, 3);
} // Treat char, varchar the same
if (strcasecmp($t, $v) !== 0)
{
if ($stop_on_error)
{
return FALSE;
}
$error_list[] = 'Incorrect definition: '.$fi.' = '.$v; $error_list[] = 'Incorrect definition: '.$fi.' = '.$v;
$change_list[] = 'MODIFY '.$this->make_def($list1[$i]); $change_list[] = 'MODIFY '.$this->make_def($list1[$i]);
break; break;
@@ -345,13 +425,17 @@ class db_table_admin
else else
{ // Field type has changed. We know fields come before indexes. So something's missing { // Field type has changed. We know fields come before indexes. So something's missing
// echo $i.': types differ - '.$list1[$i]['type'].' '.$list1[$i]['name'].', '.$list2[$k]['type'].' '.$list2[$k]['name'].'<br />'; // echo $i.': types differ - '.$list1[$i]['type'].' '.$list1[$i]['name'].', '.$list2[$k]['type'].' '.$list2[$k]['name'].'<br />';
if ($stop_on_error) { return FALSE; } if ($stop_on_error)
{
return FALSE;
}
switch ($list1[$i]['type']) switch ($list1[$i]['type'])
{ {
case 'key' : case 'key':
case 'ukey' : case 'ukey':
case 'pkey' : // Require a key - got a field, or a key of a different type case 'ftkey':
while ((count($list2)>0) && ($list2[0]['type'] == 'field')) case 'pkey': // Require a key - got a field, or a key of a different type
while ((count($list2) > 0) && ($list2[0]['type'] == 'field'))
{ {
$error_list[] = 'Extra field: '.$list2[0]['name']; $error_list[] = 'Extra field: '.$list2[0]['name'];
$change_list[] = 'DROP '.$list2[0]['name']; $change_list[] = 'DROP '.$list2[0]['name'];
@@ -366,12 +450,12 @@ class db_table_admin
} }
break; break;
case 'field' : // Require a field - got a key. so add a field at the end case 'field': // Require a field - got a key. so add a field at the end
$error_list[] = 'Missing field: '.$list1[$i]['name'].' (found: '.$list2[0]['type'].' '.$list2[0]['name'].')'; $error_list[] = 'Missing field: '.$list1[$i]['name'].' (found: '.$list2[0]['type'].' '.$list2[0]['name'].')';
$change_list[] = 'ADD '.$this->make_def($list1[$i]); $change_list[] = 'ADD '.$this->make_def($list1[$i]);
break; break;
default : default:
$error_list[] = 'Unknown field type: '.$list1[$i]['type']; $error_list[] = 'Unknown field type: '.$list1[$i]['type'];
$change_list[] = ''; // Null entry to keep them in step $change_list[] = ''; // Null entry to keep them in step
} }
@@ -386,26 +470,33 @@ class db_table_admin
{ {
switch ($f['type']) switch ($f['type'])
{ {
case 'key' : case 'key':
case 'ukey' : case 'ukey':
case 'pkey' : // Require a key - got a field case 'ftkey':
case 'pkey': // Require a key - got a field
$error_list[] = 'Extra index: '.$list2[0]['name']; $error_list[] = 'Extra index: '.$list2[0]['name'];
$change_list[] = 'DROP INDEX '.$list2[0]['name']; $change_list[] = 'DROP INDEX '.$list2[0]['name'];
break; break;
case 'field' : case 'field':
$error_list[] = 'Extra field: '.$list2[0]['name']; $error_list[] = 'Extra field: '.$list2[0]['name'];
$change_list[] = 'DROP '.$list2[0]['name']; $change_list[] = 'DROP '.$list2[0]['name'];
break; break;
} }
} }
} }
if ($stop_on_error) return TRUE; // If doing a simple comparison and we get to here, all matches if ($stop_on_error)
return array($error_list, $change_list); return TRUE; // If doing a simple comparison and we get to here, all matches
return array(
$error_list, $change_list
);
} }
function make_changes_list($result) function make_changes_list($result)
{ {
if (!is_array($result)) { return "Not an array<br />"; } if (!is_array($result))
{
return "Not an array<br />";
}
$text = "<table>"; $text = "<table>";
for ($i = 0; $i < count($result[0]); $i++) for ($i = 0; $i < count($result[0]); $i++)
{ {
@@ -417,11 +508,13 @@ class db_table_admin
return $text; return $text;
} }
// Return a table of info from the output of get_table_def // Return a table of info from the output of get_table_def
function make_table_list($result) function make_table_list($result)
{ {
if (!is_array($result)) { return "Not an array<br />"; } if (!is_array($result))
{
return "Not an array<br />";
}
$text = "<table>"; $text = "<table>";
for ($i = 0; $i < count($result); $i++) for ($i = 0; $i < count($result); $i++)
{ {
@@ -434,27 +527,32 @@ class db_table_admin
return $text; return $text;
} }
// Return a table of info from the output of parse_field_defs() // Return a table of info from the output of parse_field_defs()
function make_field_list($fields) function make_field_list($fields)
{ {
$text = "<table>"; $text = "<table>";
foreach ($fields as $f) foreach ($fields as $f)
{ {
switch($f['type']) switch ($f['type'])
{ {
case 'pkey' : case 'pkey':
$text .= "<tr><td>PRIMARY KEY</td><td>{$f['name']}</td><td>&nbsp;</td></tr>"; $text .= "<tr><td>PRIMARY KEY</td><td>{$f['name']}</td><td>&nbsp;</td></tr>";
break; break;
case 'ukey' : case 'ukey':
$text .= "<tr><td>UNIQUE KEY</td><td>{$f['name']}</td><td>{$f['keyfield']}</td></tr>"; $text .= "<tr><td>UNIQUE KEY</td><td>{$f['name']}</td><td>{$f['keyfield']}</td></tr>";
break; break;
case 'key' : case 'ftkey':
$text .= "<tr><td>FULLTEXT KEY</td><td>{$f['name']}</td><td>{$f['keyfield']}</td></tr>";
break;
case 'key':
$text .= "<tr><td>KEY</td><td>{$f['name']}</td><td>{$f['keyfield']}</td></tr>"; $text .= "<tr><td>KEY</td><td>{$f['name']}</td><td>{$f['keyfield']}</td></tr>";
break; break;
case 'field' : case 'field':
$text .= "<tr><td>FIELD</td><td>{$f['name']}</td><td>{$f['fieldtype']}"; $text .= "<tr><td>FIELD</td><td>{$f['name']}</td><td>{$f['fieldtype']}";
if (isset($f['vartype'])) { $text .= " ".$f['vartype']; } if (isset($f['vartype']))
{
$text .= " ".$f['vartype'];
}
$text .= "</td>"; $text .= "</td>";
if (isset($f['nulltype'])) if (isset($f['nulltype']))
{ {
@@ -478,7 +576,7 @@ class db_table_admin
} }
$text .= "</tr>"; $text .= "</tr>";
break; break;
default : default:
$text .= "<tr><td>!!Unknown!!</td><td>{$f['type']}</td><td>&nbsp;</td></tr>"; $text .= "<tr><td>!!Unknown!!</td><td>{$f['type']}</td><td>&nbsp;</td></tr>";
} }
} }
@@ -486,9 +584,6 @@ class db_table_admin
return $text; return $text;
} }
//-------------------------------------------------- //--------------------------------------------------
// Update a table to required structure // Update a table to required structure
//-------------------------------------------------- //--------------------------------------------------
@@ -499,7 +594,7 @@ class db_table_admin
// Return text string if $justCheck is TRUE and changes needed // Return text string if $justCheck is TRUE and changes needed
// Return text string on most failures // Return text string on most failures
// Return FALSE on certain failures (generally indicative of code/system problems) // Return FALSE on certain failures (generally indicative of code/system problems)
function update_table_structure($newStructure, $justCheck=FALSE, $makeNewifNotExist = TRUE, $mlUpdate = FALSE) function update_table_structure($newStructure, $justCheck = FALSE, $makeNewifNotExist = TRUE, $mlUpdate = FALSE)
{ {
global $sql; global $sql;
// Pull out table name // Pull out table name
@@ -508,12 +603,21 @@ class db_table_admin
$tableName = $newStructure[1]; $tableName = $newStructure[1];
if (!$sql->db_Table_exists($tableName)) if (!$sql->db_Table_exists($tableName))
{ {
if ($makeNewifNotExist === FALSE) { return 'Table doesn\'t exist'; } if ($makeNewifNotExist === FALSE)
if ($sql->db_Select_gen($newStructure[0])) { return TRUE; } {
return 'Table doesn\'t exist';
}
if ($sql->db_Select_gen($newStructure[0]))
{
return TRUE;
}
return 'Error creating new table: '.$tableName; return 'Error creating new table: '.$tableName;
} }
$reqFields = $this->parse_field_defs($newStructure[2]); // Required field definitions $reqFields = $this->parse_field_defs($newStructure[2]); // Required field definitions
if ($debugLevel) { echo "Required table structure: <br />".$this->make_field_list($reqFields); } if ($debugLevel)
{
echo "Required table structure: <br />".$this->make_field_list($reqFields);
}
if ((($actualDefs = $this->get_current_table($tableName)) === FALSE) || !is_array($actualDefs)) // Get actual table definition (Adds current default prefix) if ((($actualDefs = $this->get_current_table($tableName)) === FALSE) || !is_array($actualDefs)) // Get actual table definition (Adds current default prefix)
{ {
@@ -523,16 +627,28 @@ class db_table_admin
{ {
// echo $db_parser->make_table_list($actual_defs); // echo $db_parser->make_table_list($actual_defs);
$actualFields = $this->parse_field_defs($actualDefs[0][2]); // Split into field definitions $actualFields = $this->parse_field_defs($actualDefs[0][2]); // Split into field definitions
if ($debugLevel) { echo 'Actual table structure: <br />'.$this->make_field_list($actualFields); } if ($debugLevel)
{
echo 'Actual table structure: <br />'.$this->make_field_list($actualFields);
}
$diffs = $this->compare_field_lists($reqFields,$actualFields); // Work out any differences $diffs = $this->compare_field_lists($reqFields, $actualFields); // Work out any differences
if (count($diffs[0])) if (count($diffs[0]))
{ // Changes needed { // Changes needed
if ($justCheck) { return 'Field changes rqd; table: '.$tableName.'<br />'; } if ($justCheck)
{
return 'Field changes rqd; table: '.$tableName.'<br />';
}
// Do the changes here // Do the changes here
if ($debugLevel) { echo "List of changes found:<br />".$this->make_changes_list($diffs); } if ($debugLevel)
$qry = 'ALTER TABLE '.MPREFIX.$tableName.' '.implode(', ',$diffs[1]); {
if ($debugLevel) { echo 'Update Query used: '.$qry.'<br />'; } echo "List of changes found:<br />".$this->make_changes_list($diffs);
}
$qry = 'ALTER TABLE '.MPREFIX.$tableName.' '.implode(', ', $diffs[1]);
if ($debugLevel)
{
echo 'Update Query used: '.$qry.'<br />';
}
if ($mlUpdate) if ($mlUpdate)
{ {
$ret = $sql->db_Query_all($qry); // Returns TRUE = success, FALSE = fail $ret = $sql->db_Query_all($qry); // Returns TRUE = success, FALSE = fail
@@ -543,7 +659,7 @@ class db_table_admin
} }
if ($ret === FALSE) if ($ret === FALSE)
{ {
return $sql->dbError() ; return $sql->dbError();
} }
} }
return TRUE; // Success even if no changes required return TRUE; // Success even if no changes required
@@ -551,22 +667,24 @@ class db_table_admin
return FALSE; return FALSE;
} }
function createTable($pathToSqlFile = '', $tableName = '', $addPrefix = true, $renameTable = '')
function createTable($pathToSqlFile='', $tableName='', $addPrefix=true, $renameTable='')
{ {
$e107 = e107::getInstance(); $e107 = e107::getInstance();
$tmp = $this->get_table_def($tableName, $pathToSqlFile); $tmp = $this->get_table_def($tableName, $pathToSqlFile);
$createText = $tmp[0][0]; $createText = $tmp[0][0];
$newTableName = ($renameTable ? $renameTable : $tableName); $newTableName = ($renameTable ? $renameTable : $tableName);
if($addPrefix) { $newTableName = MPREFIX.$newTableName; } if ($addPrefix)
if($newTableName != $tableName) {
$newTableName = MPREFIX.$newTableName;
}
if ($newTableName != $tableName)
{ {
$createText = preg_replace('#create +table +(\w*?) +#i', 'CREATE TABLE '.$newTableName.' ', $createText); $createText = preg_replace('#create +table +(\w*?) +#i', 'CREATE TABLE '.$newTableName.' ', $createText);
} }
return $e107->sql->db_Select_gen($createText); return $e107->sql->db_Select_gen($createText);
} }
} }