mirror of
https://github.com/e107inc/e107.git
synced 2025-08-02 20:57:26 +02:00
Issue #5382 - Fix history table creation.
This commit is contained in:
@@ -15,7 +15,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('e107_INIT')) { exit; }
|
if(!defined('e107_INIT'))
|
||||||
|
{
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
e107::includeLan(e_LANGUAGEDIR . e_LANGUAGE . '/admin/lan_db_verify.php');
|
e107::includeLan(e_LANGUAGEDIR . e_LANGUAGE . '/admin/lan_db_verify.php');
|
||||||
|
|
||||||
@@ -25,6 +28,7 @@ e107::includeLan(e_LANGUAGEDIR.e_LANGUAGE.'/admin/lan_db_verify.php');
|
|||||||
*/
|
*/
|
||||||
class db_verify
|
class db_verify
|
||||||
{
|
{
|
||||||
|
|
||||||
var $backUrl = "";
|
var $backUrl = "";
|
||||||
public $sqlFileTables = array();
|
public $sqlFileTables = array();
|
||||||
const MOST_PREFERRED_STORAGE_ENGINE = "InnoDB";
|
const MOST_PREFERRED_STORAGE_ENGINE = "InnoDB";
|
||||||
@@ -40,6 +44,7 @@ class db_verify
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Aliases for preferred storage engines when provided the key
|
* Aliases for preferred storage engines when provided the key
|
||||||
|
*
|
||||||
* @var string[][]
|
* @var string[][]
|
||||||
*/
|
*/
|
||||||
private $storageEnginePreferenceMap = [
|
private $storageEnginePreferenceMap = [
|
||||||
@@ -71,6 +76,7 @@ class db_verify
|
|||||||
var $errors = array();
|
var $errors = array();
|
||||||
|
|
||||||
const cachetag = 'Dbverify';
|
const cachetag = 'Dbverify';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup
|
* Setup
|
||||||
*/
|
*/
|
||||||
@@ -78,7 +84,6 @@ class db_verify
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$this->backUrl = e_SELF;
|
$this->backUrl = e_SELF;
|
||||||
|
|
||||||
$this->init();
|
$this->init();
|
||||||
@@ -103,6 +108,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
private function load()
|
private function load()
|
||||||
{
|
{
|
||||||
|
|
||||||
$mes = e107::getMessage();
|
$mes = e107::getMessage();
|
||||||
$pref = e107::getPref();
|
$pref = e107::getPref();
|
||||||
|
|
||||||
@@ -143,6 +149,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
private function diffStructurePermissive($expected, $actual)
|
private function diffStructurePermissive($expected, $actual)
|
||||||
{
|
{
|
||||||
|
|
||||||
$expected['default'] = isset($expected['default']) ? $expected['default'] : '';
|
$expected['default'] = isset($expected['default']) ? $expected['default'] : '';
|
||||||
$actual['default'] = isset($actual['default']) ? $actual['default'] : '';
|
$actual['default'] = isset($actual['default']) ? $actual['default'] : '';
|
||||||
|
|
||||||
@@ -153,9 +160,11 @@ class db_verify
|
|||||||
|
|
||||||
// Permit actual text types that default to null even when
|
// Permit actual text types that default to null even when
|
||||||
// expected does not explicitly default to null
|
// expected does not explicitly default to null
|
||||||
if(0 === strcasecmp($expected['type'], $actual['type']) &&
|
if(
|
||||||
|
0 === strcasecmp($expected['type'], $actual['type']) &&
|
||||||
1 === preg_match('/[A-Z]*TEXT/i', $expected['type']) &&
|
1 === preg_match('/[A-Z]*TEXT/i', $expected['type']) &&
|
||||||
0 === strcasecmp($actual['default'], "DEFAULT NULL"))
|
0 === strcasecmp($actual['default'], "DEFAULT NULL")
|
||||||
|
)
|
||||||
{
|
{
|
||||||
$expected['default'] = $actual['default'];
|
$expected['default'] = $actual['default'];
|
||||||
}
|
}
|
||||||
@@ -169,6 +178,7 @@ class db_verify
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Display width specification for integer data types was deprecated in MySQL 8.0.17
|
* Display width specification for integer data types was deprecated in MySQL 8.0.17
|
||||||
|
*
|
||||||
* @see https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html
|
* @see https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html
|
||||||
*/
|
*/
|
||||||
if(1 === preg_match('/([A-Z]*INT)/i', $expected['type']))
|
if(1 === preg_match('/([A-Z]*INT)/i', $expected['type']))
|
||||||
@@ -192,6 +202,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function verify()
|
function verify()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!empty($_POST['runfix']))
|
if(!empty($_POST['runfix']))
|
||||||
{
|
{
|
||||||
$this->runFix($_POST['fix']);
|
$this->runFix($_POST['fix']);
|
||||||
@@ -215,6 +226,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function runComparison($fileArray)
|
function runComparison($fileArray)
|
||||||
{
|
{
|
||||||
|
|
||||||
$mes = e107::getMessage();
|
$mes = e107::getMessage();
|
||||||
|
|
||||||
foreach($fileArray as $tab)
|
foreach($fileArray as $tab)
|
||||||
@@ -261,6 +273,7 @@ class db_verify
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check core tables and installed plugin tables
|
* Check core tables and installed plugin tables
|
||||||
|
*
|
||||||
* @param $exclude - array of plugins to exclude.
|
* @param $exclude - array of plugins to exclude.
|
||||||
*/
|
*/
|
||||||
function compareAll($exclude = null)
|
function compareAll($exclude = null)
|
||||||
@@ -318,6 +331,7 @@ class db_verify
|
|||||||
{
|
{
|
||||||
//$this->internalError = true;
|
//$this->internalError = true;
|
||||||
e107::getMessage()->addDebug("Couldn't read table data for " . $selection);
|
e107::getMessage()->addDebug("Couldn't read table data for " . $selection);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,11 +340,12 @@ class db_verify
|
|||||||
$rawSqlData = $this->getSqlData($tbl, $language);
|
$rawSqlData = $this->getSqlData($tbl, $language);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if($rawSqlData === false)
|
if($rawSqlData === false)
|
||||||
{
|
{
|
||||||
if($language) continue;
|
if($language)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$this->errors[$tbl]['_status'] = self::STATUS_TABLE_MISSING;
|
$this->errors[$tbl]['_status'] = self::STATUS_TABLE_MISSING;
|
||||||
@@ -416,6 +431,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
public function getResults($type = 'fields')
|
public function getResults($type = 'fields')
|
||||||
{
|
{
|
||||||
|
|
||||||
if($type === 'indices')
|
if($type === 'indices')
|
||||||
{
|
{
|
||||||
return $this->indices;
|
return $this->indices;
|
||||||
@@ -427,6 +443,7 @@ class db_verify
|
|||||||
|
|
||||||
public function hasSyntaxIssue($sqlFileData): bool
|
public function hasSyntaxIssue($sqlFileData): bool
|
||||||
{
|
{
|
||||||
|
|
||||||
return false; // TODO check syntax for errrors.
|
return false; // TODO check syntax for errrors.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,6 +457,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
public function prepareResults($tbl, $selection, $sqlData, $fileData)
|
public function prepareResults($tbl, $selection, $sqlData, $fileData)
|
||||||
{
|
{
|
||||||
|
|
||||||
if($this->hasSyntaxIssue($fileData))
|
if($this->hasSyntaxIssue($fileData))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -455,8 +473,14 @@ class db_verify
|
|||||||
$results = 'indices';
|
$results = 'indices';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($this->errors[$tbl])) $this->errors[$tbl] = [];
|
if(!isset($this->errors[$tbl]))
|
||||||
if (!isset($this->errors[$tbl]['_status'])) $this->errors[$tbl]['_status'] = self::STATUS_TABLE_OK;
|
{
|
||||||
|
$this->errors[$tbl] = [];
|
||||||
|
}
|
||||||
|
if(!isset($this->errors[$tbl]['_status']))
|
||||||
|
{
|
||||||
|
$this->errors[$tbl]['_status'] = self::STATUS_TABLE_OK;
|
||||||
|
}
|
||||||
$this->errors[$tbl]['_file'] = $selection;
|
$this->errors[$tbl]['_file'] = $selection;
|
||||||
|
|
||||||
foreach($fileData[$type] as $key => $value)
|
foreach($fileData[$type] as $key => $value)
|
||||||
@@ -501,15 +525,12 @@ class db_verify
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile Results into a complete list of Fixes that could be run without the need of a form selection.
|
* Compile Results into a complete list of Fixes that could be run without the need of a form selection.
|
||||||
*/
|
*/
|
||||||
function compileResults()
|
function compileResults()
|
||||||
{
|
{
|
||||||
|
|
||||||
foreach($this->results as $tabs => $field)
|
foreach($this->results as $tabs => $field)
|
||||||
{
|
{
|
||||||
$file = varset($this->results[$tabs]['_file'], $tabs);
|
$file = varset($this->results[$tabs]['_file'], $tabs);
|
||||||
@@ -529,7 +550,10 @@ class db_verify
|
|||||||
}
|
}
|
||||||
foreach($field as $k => $f)
|
foreach($field as $k => $f)
|
||||||
{
|
{
|
||||||
if($f['_status']=='ok') continue;
|
if($f['_status'] == 'ok')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$status = $f['_status'];
|
$status = $f['_status'];
|
||||||
if(!empty($this->modes[$status]))
|
if(!empty($this->modes[$status]))
|
||||||
{
|
{
|
||||||
@@ -547,7 +571,10 @@ class db_verify
|
|||||||
{
|
{
|
||||||
foreach($field as $k => $f)
|
foreach($field as $k => $f)
|
||||||
{
|
{
|
||||||
if($f['_status']=='ok') continue;
|
if($f['_status'] == 'ok')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$this->fixList[$f['_file']][$tabs][$k][] = $this->modes[$f['_status']];
|
$this->fixList[$f['_file']][$tabs][$k][] = $this->modes[$f['_status']];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,6 +589,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
public function errors()
|
public function errors()
|
||||||
{
|
{
|
||||||
|
|
||||||
$badTableCount = 0;
|
$badTableCount = 0;
|
||||||
foreach($this->errors as $tableName => $tableMetadata)
|
foreach($this->errors as $tableName => $tableMetadata)
|
||||||
{
|
{
|
||||||
@@ -593,6 +621,7 @@ class db_verify
|
|||||||
|
|
||||||
public function getErrors()
|
public function getErrors()
|
||||||
{
|
{
|
||||||
|
|
||||||
return $this->errors;
|
return $this->errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,6 +686,7 @@ class db_verify
|
|||||||
] as $statusFlag)
|
] as $statusFlag)
|
||||||
{
|
{
|
||||||
if($tableStatus & $statusFlag)
|
if($tableStatus & $statusFlag)
|
||||||
|
{
|
||||||
$errors[] = $parser->lanVars(
|
$errors[] = $parser->lanVars(
|
||||||
$info[$statusFlag],
|
$info[$statusFlag],
|
||||||
[
|
[
|
||||||
@@ -665,6 +695,7 @@ class db_verify
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$fixMode = $tableStatus & self::STATUS_TABLE_MISSING ? 'create' : 'convert';
|
$fixMode = $tableStatus & self::STATUS_TABLE_MISSING ? 'create' : 'convert';
|
||||||
|
|
||||||
@@ -680,7 +711,10 @@ class db_verify
|
|||||||
}
|
}
|
||||||
foreach($field as $k => $f)
|
foreach($field as $k => $f)
|
||||||
{
|
{
|
||||||
if($f['_status']=='ok') continue;
|
if($f['_status'] == 'ok')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$fstat = $info[$f['_status']];
|
$fstat = $info[$f['_status']];
|
||||||
|
|
||||||
@@ -709,7 +743,10 @@ class db_verify
|
|||||||
{
|
{
|
||||||
foreach($field as $k => $f)
|
foreach($field as $k => $f)
|
||||||
{
|
{
|
||||||
if($f['_status']=='ok') continue;
|
if($f['_status'] == 'ok')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$fstat = $info[$f['_status']];
|
$fstat = $info[$f['_status']];
|
||||||
|
|
||||||
@@ -767,8 +804,10 @@ class db_verify
|
|||||||
if(strpos($tabs, "lan_") === 0)
|
if(strpos($tabs, "lan_") === 0)
|
||||||
{
|
{
|
||||||
list($tmp, $lang, $table) = explode("_", $tabs, 3);
|
list($tmp, $lang, $table) = explode("_", $tabs, 3);
|
||||||
|
|
||||||
return $table . " (" . ucfirst($lang) . ")";
|
return $table . " (" . ucfirst($lang) . ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tabs;
|
return $tabs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,6 +823,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function fixForm($file, $table, $field, $newvalue, $mode, $after = '')
|
function fixForm($file, $table, $field, $newvalue, $mode, $after = '')
|
||||||
{
|
{
|
||||||
|
|
||||||
$frm = e107::getForm();
|
$frm = e107::getForm();
|
||||||
$text = $frm->checkbox("fix[$file][$table][$field][]", $mode, false, array('id' => false));
|
$text = $frm->checkbox("fix[$file][$table][$field][]", $mode, false, array('id' => false));
|
||||||
|
|
||||||
@@ -798,6 +838,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function renderNotes($data, $mode = 'field')
|
function renderNotes($data, $mode = 'field')
|
||||||
{
|
{
|
||||||
|
|
||||||
// return "<pre>".print_r($data,TRUE)."</pre>";
|
// return "<pre>".print_r($data,TRUE)."</pre>";
|
||||||
|
|
||||||
$v = $data['_valid'];
|
$v = $data['_valid'];
|
||||||
@@ -828,7 +869,10 @@ class db_verify
|
|||||||
public function toMysql($data, $mode = 'field')
|
public function toMysql($data, $mode = 'field')
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!$data) return;
|
if(!$data)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if($mode === 'index')
|
if($mode === 'index')
|
||||||
{
|
{
|
||||||
@@ -838,6 +882,7 @@ class db_verify
|
|||||||
//return $data['type']." (".$data['field'].");";
|
//return $data['type']." (".$data['field'].");";
|
||||||
// Check if index keyname exists and add backticks
|
// Check if index keyname exists and add backticks
|
||||||
$keyname = (!empty($data['keyname']) ? " `" . $data['keyname'] . "`" : "");
|
$keyname = (!empty($data['keyname']) ? " `" . $data['keyname'] . "`" : "");
|
||||||
|
|
||||||
return $data['type'] . $keyname . " (" . $data['field'] . ");";
|
return $data['type'] . $keyname . " (" . $data['field'] . ");";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -850,6 +895,7 @@ class db_verify
|
|||||||
if(!in_array(strtolower($data['type']), $this->fieldTypes))
|
if(!in_array(strtolower($data['type']), $this->fieldTypes))
|
||||||
{
|
{
|
||||||
$ret = $data['type'] . "(" . $data['value'] . ") " . $data['attributes'] . " " . $data['null'] . " " . $data['default'];
|
$ret = $data['type'] . "(" . $data['value'] . ") " . $data['attributes'] . " " . $data['null'] . " " . $data['default'];
|
||||||
|
|
||||||
return trim($ret);
|
return trim($ret);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -873,8 +919,10 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function getPrevious($array, $cur)
|
function getPrevious($array, $cur)
|
||||||
{
|
{
|
||||||
|
|
||||||
$fkeys = array_keys($array);
|
$fkeys = array_keys($array);
|
||||||
$cur_key = array_search($cur, $fkeys);
|
$cur_key = array_search($cur, $fkeys);
|
||||||
|
|
||||||
return @$fkeys[$cur_key - 1];
|
return @$fkeys[$cur_key - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,6 +931,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function getId($tabl, $cur)
|
function getId($tabl, $cur)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(empty($tabl))
|
if(empty($tabl))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -983,13 +1032,13 @@ class db_verify
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fix tables
|
* Fix tables
|
||||||
* FixArray eg. [core][table][field] = alter|create|index| etc.
|
* FixArray eg. [core][table][field] = alter|create|index| etc.
|
||||||
*/
|
*/
|
||||||
function runFix($fixArray = '')
|
function runFix($fixArray = '')
|
||||||
{
|
{
|
||||||
|
|
||||||
$mes = e107::getMessage();
|
$mes = e107::getMessage();
|
||||||
$log = e107::getLog();
|
$log = e107::getLog();
|
||||||
|
|
||||||
@@ -1064,9 +1113,11 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function getSqlFileTables($sql_data)
|
function getSqlFileTables($sql_data)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!$sql_data)
|
if(!$sql_data)
|
||||||
{
|
{
|
||||||
e107::getMessage()->addError("No SQL Data found in file");
|
e107::getMessage()->addError("No SQL Data found in file");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1113,7 +1164,10 @@ class db_verify
|
|||||||
|
|
||||||
foreach($match[3] as $rawTableOptions)
|
foreach($match[3] as $rawTableOptions)
|
||||||
{
|
{
|
||||||
if (empty($rawTableOptions)) continue;
|
if(empty($rawTableOptions))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$engine = null;
|
$engine = null;
|
||||||
$charset = null;
|
$charset = null;
|
||||||
@@ -1193,7 +1247,10 @@ class db_verify
|
|||||||
|
|
||||||
$ret = array();
|
$ret = array();
|
||||||
|
|
||||||
if($print) var_dump($regex, $m);
|
if($print)
|
||||||
|
{
|
||||||
|
var_dump($regex, $m);
|
||||||
|
}
|
||||||
|
|
||||||
foreach($m[1] as $k => $val)
|
foreach($m[1] as $k => $val)
|
||||||
{
|
{
|
||||||
@@ -1211,108 +1268,70 @@ class db_verify
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $data
|
* Helper method to clean column names
|
||||||
* @param $print
|
*
|
||||||
* @return array
|
* @param string $col The raw column name to clean
|
||||||
|
* @return string The cleaned column name
|
||||||
*/
|
*/
|
||||||
function getIndex($data, $print = false)
|
private function cleanColumn($col)
|
||||||
{
|
{
|
||||||
// $regex = "/(PRIMARY|UNIQUE|FULLTEXT|FOREIGN)?[\s]*?(INDEX|KEY)[\s]*(?:`?([\w]*)`?)?[\s]*?\(`?([\w]+)`?(?:\s*\(\d+\))?(?:\s*(ASC|DESC))?\)[\s]*,?/i";
|
|
||||||
// $regex = "/(?P<type>PRIMARY|PRIMARY|UNIQUE|FULLTEXT|FOREIGN|KEY)[\s]*?(?P<key_type>INDEX|KEY)?[\s]*(?:`?(?P<field>[\w]*)`?)?[\s]*?\(`?(?P<keyname>[\w]+)`?(?:\s*\(\d+\))?(?:\s*(?P<order>ASC|DESC))?\)[\s]*,?/i";
|
|
||||||
|
|
||||||
$regex = "/(?P<type>PRIMARY|UNIQUE|FULLTEXT|FOREIGN|KEY|INDEX)[\s]*?(?P<key_type>INDEX|KEY)?[\s]*(?:`?(?P<field>[\w]*)`?)?[\s]*?\(`?(?P<keyname>[\w]+)`?(?:\s*\((?P<length>\d+)\))?(?:\s*(?P<order>ASC|DESC))?\)[\s]*,?/i";
|
$col = trim($col);
|
||||||
|
$col = str_replace('(', ' (', $col);
|
||||||
|
$tmp = explode(' ', $col);
|
||||||
|
|
||||||
|
return str_replace('`', '', $tmp[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse index definitions from a string
|
||||||
|
*
|
||||||
|
* @param string $data The raw index definition string
|
||||||
|
* @param bool $print Optional flag to print results (not used here)
|
||||||
|
* @return array Parsed index information
|
||||||
|
*/
|
||||||
|
public function getIndex($data, $print = false)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Regular expression to match index definitions
|
||||||
|
$regex = "/(?P<type>PRIMARY|UNIQUE|FULLTEXT|FOREIGN|KEY|INDEX)[\s]*?(?P<key_type>INDEX|KEY)?[\s]*(?:`?(?P<field>[\w]*)`?)?[\s]*?\((?P<columns>[^)]+)\)[\s]*,?/i";
|
||||||
preg_match_all($regex, $data, $m);
|
preg_match_all($regex, $data, $m);
|
||||||
|
|
||||||
$ret = [];
|
$ret = [];
|
||||||
|
|
||||||
|
// Process each matched index
|
||||||
foreach($m['type'] as $k => $val)
|
foreach($m['type'] as $k => $val)
|
||||||
{
|
{
|
||||||
$i = $m['field'][$k];
|
$type = trim(strtoupper($m['type'][$k])); // Index type (e.g., PRIMARY, UNIQUE)
|
||||||
$type = trim(strtoupper($m['type'][$k]));
|
$field = trim($m['field'][$k]); // Index name before parentheses
|
||||||
$keyname = trim($m['keyname'][$k]);
|
$columnsRaw = trim($m['columns'][$k]); // Content inside parentheses
|
||||||
$field = trim($m['field'][$k]);
|
|
||||||
|
|
||||||
if(empty($field) || $field === 'KEY')
|
// Split columns and clean each one using the helper method
|
||||||
|
$columnsArray = array_map(array($this, 'cleanColumn'), explode(',', $columnsRaw));
|
||||||
|
$keyname = implode(',', $columnsArray); // Comma-separated column names
|
||||||
|
|
||||||
|
// Determine the index name: use 'field' if provided, otherwise first column
|
||||||
|
$i = $field ?: $columnsArray[0];
|
||||||
|
if($type === 'PRIMARY')
|
||||||
{
|
{
|
||||||
$field = $keyname;
|
$i = $columnsArray[0]; // Primary key uses the column name
|
||||||
$i = $keyname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Normalize KEY/INDEX to empty type for regular indexes
|
||||||
if($type === 'KEY' || $type === 'INDEX')
|
if($type === 'KEY' || $type === 'INDEX')
|
||||||
{
|
{
|
||||||
$type = '';
|
$type = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty($keyname) || $keyname === 'KEY')
|
// Build the result array for this index
|
||||||
{
|
|
||||||
$keyname = $field;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ret[$i] = array(
|
$ret[$i] = array(
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'keyname' => $keyname,
|
'keyname' => $keyname,
|
||||||
'field' => $field,
|
'field' => $i,
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
/*
|
|
||||||
if (count($m) > 0)
|
|
||||||
{
|
|
||||||
unset($m[2]);
|
|
||||||
$m = array_combine(range(0, count($m)-1), array_values($m));
|
|
||||||
}
|
|
||||||
$ret = array();
|
|
||||||
|
|
||||||
if($print)
|
|
||||||
{
|
|
||||||
e107::getDebug()->log($m);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Standard Detection Method.
|
|
||||||
|
|
||||||
$fieldReplace = array("`"," ");
|
|
||||||
|
|
||||||
|
|
||||||
foreach($m[3] as $k=>$val)
|
|
||||||
{
|
|
||||||
if(!$val) continue;
|
|
||||||
$val = str_replace("`","",$val);
|
|
||||||
|
|
||||||
$key = !empty($m[2][$k]) ? $m[2][$k] : $val;
|
|
||||||
|
|
||||||
$ret[$key] = array(
|
|
||||||
'type' => strtoupper($m[1][$k]),
|
|
||||||
'keyname' => (!empty($m[2][$k])) ? str_replace("`","",$m[2][$k]) : str_replace("`","",$m[3][$k]),
|
|
||||||
'field' => str_replace($fieldReplace,"",$m[3][$k])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Alternate Index detection method.
|
|
||||||
// eg. `table_id` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
|
|
||||||
|
|
||||||
$regex = "/`?([\w]*)`? .*((?:AUTO_INCREMENT))\s?(PRIMARY|UNIQUE|FULLTEXT|FOREIGN)\s?KEY\s?,/i";
|
|
||||||
preg_match_all($regex,$data,$m);
|
|
||||||
|
|
||||||
foreach($m[1] as $k=>$val)
|
|
||||||
{
|
|
||||||
if(!$val) continue;
|
|
||||||
|
|
||||||
$ret[$val] = array(
|
|
||||||
'type' => strtoupper($m[3][$k]),
|
|
||||||
'keyname' => $m[1][$k],
|
|
||||||
'field' => str_replace($fieldReplace,"",$m[1][$k])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($print)
|
|
||||||
{
|
|
||||||
e107::getDebug()->log($ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1331,7 +1350,7 @@ class db_verify
|
|||||||
{
|
{
|
||||||
if(!in_array($tbl, $this->sqlLanguageTables[$language]))
|
if(!in_array($tbl, $this->sqlLanguageTables[$language]))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$prefix .= "lan_" . $language . "_";
|
$prefix .= "lan_" . $language . "_";
|
||||||
@@ -1339,13 +1358,12 @@ class db_verify
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$sql = e107::getDb();
|
$sql = e107::getDb();
|
||||||
|
|
||||||
if(!$sql->isTable($tbl))
|
if(!$sql->isTable($tbl))
|
||||||
{
|
{
|
||||||
$mes->addDebug('Missing table on db-verify: ' . $tbl);
|
$mes->addDebug('Missing table on db-verify: ' . $tbl);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1360,6 +1378,7 @@ class db_verify
|
|||||||
{
|
{
|
||||||
// $row = mysql_fetch_row($z);
|
// $row = mysql_fetch_row($z);
|
||||||
$row = $sql->fetch('num');
|
$row = $sql->fetch('num');
|
||||||
|
|
||||||
//return $row[1];
|
//return $row[1];
|
||||||
|
|
||||||
return stripslashes($row[1]) . ';'; // backticks needed.
|
return stripslashes($row[1]) . ';'; // backticks needed.
|
||||||
@@ -1369,7 +1388,8 @@ class db_verify
|
|||||||
{
|
{
|
||||||
$mes->addDebug('Failed: ' . $qry);
|
$mes->addDebug('Failed: ' . $qry);
|
||||||
$this->internalError = true;
|
$this->internalError = true;
|
||||||
return FALSE;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1379,6 +1399,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function getSqlLanguages()
|
function getSqlLanguages()
|
||||||
{
|
{
|
||||||
|
|
||||||
$sql = e107::getDb();
|
$sql = e107::getDb();
|
||||||
$list = $sql->tables('lan');
|
$list = $sql->tables('lan');
|
||||||
|
|
||||||
@@ -1400,6 +1421,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
function renderTableSelect()
|
function renderTableSelect()
|
||||||
{
|
{
|
||||||
|
|
||||||
$frm = e107::getForm();
|
$frm = e107::getForm();
|
||||||
$ns = e107::getRender();
|
$ns = e107::getRender();
|
||||||
$mes = e107::getMessage();
|
$mes = e107::getMessage();
|
||||||
@@ -1497,6 +1519,7 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
private function getAvailableStorageEngines()
|
private function getAvailableStorageEngines()
|
||||||
{
|
{
|
||||||
|
|
||||||
$db = e107::getDb();
|
$db = e107::getDb();
|
||||||
$db->gen("SHOW ENGINES;");
|
$db->gen("SHOW ENGINES;");
|
||||||
$output = [];
|
$output = [];
|
||||||
@@ -1504,6 +1527,7 @@ class db_verify
|
|||||||
{
|
{
|
||||||
$output[] = $row['Engine'];
|
$output[] = $row['Engine'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1533,11 +1557,15 @@ class db_verify
|
|||||||
if(!array_key_exists($maybeStorageEngine, $this->storageEnginePreferenceMap))
|
if(!array_key_exists($maybeStorageEngine, $this->storageEnginePreferenceMap))
|
||||||
{
|
{
|
||||||
if(in_array($maybeStorageEngine, $this->availableStorageEngines))
|
if(in_array($maybeStorageEngine, $this->availableStorageEngines))
|
||||||
|
{
|
||||||
return $maybeStorageEngine;
|
return $maybeStorageEngine;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fit = array_intersect($this->storageEnginePreferenceMap[$maybeStorageEngine], $this->availableStorageEngines);
|
$fit = array_intersect($this->storageEnginePreferenceMap[$maybeStorageEngine], $this->availableStorageEngines);
|
||||||
|
|
||||||
return current($fit);
|
return current($fit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1550,8 +1578,11 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
public function getCanonicalStorageEngine($maybeStorageEngine)
|
public function getCanonicalStorageEngine($maybeStorageEngine)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(in_array($maybeStorageEngine, $this->availableStorageEngines))
|
if(in_array($maybeStorageEngine, $this->availableStorageEngines))
|
||||||
|
{
|
||||||
return $maybeStorageEngine;
|
return $maybeStorageEngine;
|
||||||
|
}
|
||||||
|
|
||||||
throw new UnexpectedValueException(
|
throw new UnexpectedValueException(
|
||||||
"Unknown storage engine: " . var_export($maybeStorageEngine, true)
|
"Unknown storage engine: " . var_export($maybeStorageEngine, true)
|
||||||
@@ -1566,7 +1597,11 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
public function getIntendedCharset($maybeCharset = null)
|
public function getIntendedCharset($maybeCharset = null)
|
||||||
{
|
{
|
||||||
if (empty($maybeCharset)) return self::MOST_PREFERRED_CHARSET;
|
|
||||||
|
if(empty($maybeCharset))
|
||||||
|
{
|
||||||
|
return self::MOST_PREFERRED_CHARSET;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->getCanonicalCharset($maybeCharset);
|
return $this->getCanonicalCharset($maybeCharset);
|
||||||
}
|
}
|
||||||
@@ -1579,17 +1614,23 @@ class db_verify
|
|||||||
*/
|
*/
|
||||||
public function getCanonicalCharset($maybeCharset)
|
public function getCanonicalCharset($maybeCharset)
|
||||||
{
|
{
|
||||||
if ($maybeCharset == "utf8") return "utf8mb4";
|
|
||||||
|
if($maybeCharset == "utf8")
|
||||||
|
{
|
||||||
|
return "utf8mb4";
|
||||||
|
}
|
||||||
|
|
||||||
return $maybeCharset;
|
return $maybeCharset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inititalize the class parameters.
|
* Inititalize the class parameters.
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function init($clearCache = false): void
|
public function init($clearCache = false): void
|
||||||
{
|
{
|
||||||
|
|
||||||
$sql = e107::getDb();
|
$sql = e107::getDb();
|
||||||
$sql->gen('SET SQL_QUOTE_SHOW_CREATE = 1');
|
$sql->gen('SET SQL_QUOTE_SHOW_CREATE = 1');
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@ class db_verifyTest extends \Codeception\Test\Unit
|
|||||||
|
|
||||||
protected function _before()
|
protected function _before()
|
||||||
{
|
{
|
||||||
|
|
||||||
require_once(e_HANDLER . "db_verify_class.php");
|
require_once(e_HANDLER . "db_verify_class.php");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -32,6 +33,7 @@ class db_verifyTest extends \Codeception\Test\Unit
|
|||||||
|
|
||||||
public function testGetFields()
|
public function testGetFields()
|
||||||
{
|
{
|
||||||
|
|
||||||
$data = "table_id int(10) unsigned NOT NULL auto_increment,
|
$data = "table_id int(10) unsigned NOT NULL auto_increment,
|
||||||
table_name varchar(100) NOT NULL default '',
|
table_name varchar(100) NOT NULL default '',
|
||||||
table_email varchar(100) NOT NULL default '',
|
table_email varchar(100) NOT NULL default '',
|
||||||
@@ -216,6 +218,7 @@ class db_verifyTest extends \Codeception\Test\Unit
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public function testClearCache()
|
public function testClearCache()
|
||||||
{
|
{
|
||||||
@@ -296,6 +299,7 @@ class db_verifyTest extends \Codeception\Test\Unit
|
|||||||
*/
|
*/
|
||||||
public function testGetIndexOptionalLengthAndSortOrder()
|
public function testGetIndexOptionalLengthAndSortOrder()
|
||||||
{
|
{
|
||||||
|
|
||||||
$data = <<<EOF
|
$data = <<<EOF
|
||||||
`field1` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`field1` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`field2` varchar(100) NOT NULL DEFAULT '',
|
`field2` varchar(100) NOT NULL DEFAULT '',
|
||||||
@@ -338,6 +342,51 @@ EOF;
|
|||||||
self::assertEquals($expected, $result);
|
self::assertEquals($expected, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testGetIndexCompositeKeys()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = <<<DATA
|
||||||
|
history_id int(10) unsigned NOT NULL auto_increment,
|
||||||
|
history_table varchar(64) NOT NULL default '',
|
||||||
|
history_pid varchar(64) NOT NULL default '',
|
||||||
|
history_record_id int(10) unsigned NOT NULL default '0',
|
||||||
|
history_action enum('delete','restore','update') NOT NULL,
|
||||||
|
history_data LONGTEXT DEFAULT NULL,
|
||||||
|
history_user_id int(10) unsigned NOT NULL default '0',
|
||||||
|
history_datestamp int(10) unsigned NOT NULL default '0',
|
||||||
|
history_restored int(10) unsigned NOT NULL default '0',
|
||||||
|
PRIMARY KEY (history_id),
|
||||||
|
KEY history_table_record (history_table, history_record_id),
|
||||||
|
KEY history_datestamp (history_datestamp)
|
||||||
|
DATA;
|
||||||
|
|
||||||
|
$expected = array(
|
||||||
|
'history_id' =>
|
||||||
|
array(
|
||||||
|
'type' => 'PRIMARY',
|
||||||
|
'keyname' => 'history_id',
|
||||||
|
'field' => 'history_id',
|
||||||
|
),
|
||||||
|
'history_table_record' =>
|
||||||
|
array(
|
||||||
|
'type' => '',
|
||||||
|
'keyname' => 'history_table,history_record_id',
|
||||||
|
'field' => 'history_table_record',
|
||||||
|
),
|
||||||
|
'history_datestamp' =>
|
||||||
|
array(
|
||||||
|
'type' => '',
|
||||||
|
'keyname' => 'history_datestamp',
|
||||||
|
'field' => 'history_datestamp',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$actual = $this->dbv->getIndex($data);
|
||||||
|
self::assertEquals($expected, $actual);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME: This test has no assertions!
|
* FIXME: This test has no assertions!
|
||||||
*/
|
*/
|
||||||
@@ -445,6 +494,7 @@ EOF;
|
|||||||
|
|
||||||
public function testToMysql()
|
public function testToMysql()
|
||||||
{
|
{
|
||||||
|
|
||||||
$tests = array(
|
$tests = array(
|
||||||
0 =>
|
0 =>
|
||||||
array(
|
array(
|
||||||
@@ -510,6 +560,7 @@ EOF;
|
|||||||
*/
|
*/
|
||||||
public function testGetSqlFileTables()
|
public function testGetSqlFileTables()
|
||||||
{
|
{
|
||||||
|
|
||||||
$tests = array(
|
$tests = array(
|
||||||
|
|
||||||
|
|
||||||
@@ -850,7 +901,6 @@ EOF;
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$sql = "`schedule_id` int(10) unsigned NOT NULL auto_increment,
|
$sql = "`schedule_id` int(10) unsigned NOT NULL auto_increment,
|
||||||
`schedule_user_id` int(11) NOT NULL,
|
`schedule_user_id` int(11) NOT NULL,
|
||||||
`schedule_invoice_id` int(11) NOT NULL,
|
`schedule_invoice_id` int(11) NOT NULL,
|
||||||
@@ -1018,6 +1068,7 @@ EOF;
|
|||||||
|
|
||||||
public function testSyntaxCheck()
|
public function testSyntaxCheck()
|
||||||
{
|
{
|
||||||
|
|
||||||
$file = "`affiliate_id` int(10) unsigned NOT NULL auto_increment,
|
$file = "`affiliate_id` int(10) unsigned NOT NULL auto_increment,
|
||||||
`affiliate_code` varchar(10) NOT NULL DEFAULT '',
|
`affiliate_code` varchar(10) NOT NULL DEFAULT '',
|
||||||
`affiliate_name` varchar(30) NOT NULL DEFAULT '',
|
`affiliate_name` varchar(30) NOT NULL DEFAULT '',
|
||||||
@@ -1042,7 +1093,6 @@ EOF;
|
|||||||
$result = $this->dbv->hasSyntaxIssue($file);
|
$result = $this->dbv->hasSyntaxIssue($file);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var_export($result);
|
var_export($result);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1071,6 +1121,7 @@ EOF;
|
|||||||
|
|
||||||
public function testGetCanonicalStorageEngine()
|
public function testGetCanonicalStorageEngine()
|
||||||
{
|
{
|
||||||
|
|
||||||
$input = "InnoDB";
|
$input = "InnoDB";
|
||||||
|
|
||||||
$output = $this->dbv->getCanonicalStorageEngine($input);
|
$output = $this->dbv->getCanonicalStorageEngine($input);
|
||||||
@@ -1080,6 +1131,7 @@ EOF;
|
|||||||
|
|
||||||
public function testGetCanonicalStorageEngineUnknownStorageEngine()
|
public function testGetCanonicalStorageEngineUnknownStorageEngine()
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->expectException(UnexpectedValueException::class);
|
$this->expectException(UnexpectedValueException::class);
|
||||||
|
|
||||||
$this->dbv->getCanonicalStorageEngine("FakeEngine");
|
$this->dbv->getCanonicalStorageEngine("FakeEngine");
|
||||||
@@ -1087,6 +1139,7 @@ EOF;
|
|||||||
|
|
||||||
public function testGetCanonicalCharsetUtf8Alias()
|
public function testGetCanonicalCharsetUtf8Alias()
|
||||||
{
|
{
|
||||||
|
|
||||||
$input = "utf8";
|
$input = "utf8";
|
||||||
$expected = "utf8mb4";
|
$expected = "utf8mb4";
|
||||||
|
|
||||||
@@ -1097,6 +1150,7 @@ EOF;
|
|||||||
|
|
||||||
public function testGetCanonicalCharsetOther()
|
public function testGetCanonicalCharsetOther()
|
||||||
{
|
{
|
||||||
|
|
||||||
$inputs = ["latin1", "utf8mb3", "utf8mb4"];
|
$inputs = ["latin1", "utf8mb3", "utf8mb4"];
|
||||||
|
|
||||||
foreach($inputs as $input)
|
foreach($inputs as $input)
|
||||||
@@ -1109,6 +1163,7 @@ EOF;
|
|||||||
|
|
||||||
public function testGetIntendedStorageEngine()
|
public function testGetIntendedStorageEngine()
|
||||||
{
|
{
|
||||||
|
|
||||||
$output = $this->dbv->getIntendedStorageEngine("MyISAM");
|
$output = $this->dbv->getIntendedStorageEngine("MyISAM");
|
||||||
self::assertEquals("InnoDB", $output);
|
self::assertEquals("InnoDB", $output);
|
||||||
|
|
||||||
@@ -1130,6 +1185,7 @@ EOF;
|
|||||||
|
|
||||||
public function testGetIntendedCharset()
|
public function testGetIntendedCharset()
|
||||||
{
|
{
|
||||||
|
|
||||||
$output = $this->dbv->getIntendedCharset("");
|
$output = $this->dbv->getIntendedCharset("");
|
||||||
self::assertEquals("utf8mb4", $output);
|
self::assertEquals("utf8mb4", $output);
|
||||||
|
|
||||||
@@ -1154,6 +1210,7 @@ EOF;
|
|||||||
|
|
||||||
public function testRunFix()
|
public function testRunFix()
|
||||||
{
|
{
|
||||||
|
|
||||||
self::markTestSkipped('Inconsistent behavior');
|
self::markTestSkipped('Inconsistent behavior');
|
||||||
|
|
||||||
$sql = e107::getDb();
|
$sql = e107::getDb();
|
||||||
@@ -1190,7 +1247,6 @@ EOF;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user