mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-27 07:00:29 +01:00
727 lines
18 KiB
PHP
727 lines
18 KiB
PHP
|
<?php
|
||
|
/*
|
||
|
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
|
||
|
*
|
||
|
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
|
||
|
*
|
||
|
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
|
||
|
*
|
||
|
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
|
||
|
* to obtain the text of the corresponding license version.
|
||
|
*
|
||
|
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
|
||
|
*/
|
||
|
?>
|
||
|
<?php
|
||
|
|
||
|
final class DatabaseUpgrade
|
||
|
{
|
||
|
/** @var Application $app */
|
||
|
private $app;
|
||
|
|
||
|
/** @var array $CheckColumnTableCache */
|
||
|
private $CheckColumnTableCache;
|
||
|
|
||
|
/** @var bool $check_column_missing_run */
|
||
|
private $check_column_missing_run=false;
|
||
|
|
||
|
/** @var array $check_column_missing */
|
||
|
private $check_column_missing=array();
|
||
|
|
||
|
/** @var array $check_index_missing */
|
||
|
private $check_index_missing=array();
|
||
|
|
||
|
/** @var array */
|
||
|
private $allTables = [];
|
||
|
|
||
|
/** @var array */
|
||
|
private $indexe = [];
|
||
|
|
||
|
/**
|
||
|
* @param Application $app
|
||
|
*/
|
||
|
public function __construct($app)
|
||
|
{
|
||
|
$this->app = $app;
|
||
|
}
|
||
|
|
||
|
public function emptyTableCache(){
|
||
|
$this->CheckColumnTableCache = [];
|
||
|
$this->allTables = [];
|
||
|
$this->indexe = [];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @var bool $force
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getAllTables($force = false)
|
||
|
{
|
||
|
if($force || empty($this->allTables)) {
|
||
|
$this->allTables = $this->app->DB->SelectFirstCols('SHOW TABLES');
|
||
|
}
|
||
|
|
||
|
return $this->allTables;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
* @param string $pk
|
||
|
*/
|
||
|
public function createTable($table, $pk = 'id')
|
||
|
{
|
||
|
$sql = "CREATE TABLE `$table` (`".$pk."` INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (`".$pk."`)) ENGINE = InnoDB DEFAULT CHARSET=utf8";
|
||
|
$this->app->DB->Query($sql);
|
||
|
$this->addPrimary($table, $pk);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
* @param string $pk
|
||
|
*/
|
||
|
public function addPrimary($table, $pk = 'id')
|
||
|
{
|
||
|
$this->CheckAlterTable(
|
||
|
"ALTER TABLE `$table`
|
||
|
ADD PRIMARY KEY (`".$pk."`)",
|
||
|
true
|
||
|
);
|
||
|
$this->CheckAlterTable(
|
||
|
"ALTER TABLE `$table`
|
||
|
MODIFY `".$pk."` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1",
|
||
|
true
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
* @param bool $force
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getIndexeCached($table, $force = false)
|
||
|
{
|
||
|
if($force || !isset($this->indexe[$table])){
|
||
|
$this->indexe[$table] = $this->app->DB->SelectArr(sprintf('SHOW INDEX FROM `%s`', $table));
|
||
|
if($this->indexe[$table] === null) {
|
||
|
$this->indexe[$table] = [];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $this->indexe[$table];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
*/
|
||
|
public function clearIndexCached($table)
|
||
|
{
|
||
|
if(!isset($this->indexe[$table])) {
|
||
|
return;
|
||
|
}
|
||
|
unset($this->indexe[$table]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
* @param string $pk
|
||
|
*/
|
||
|
public function hasPrimaryKey($table, $pk = 'id')
|
||
|
{
|
||
|
$indexe = $this->getIndexeCached($table);
|
||
|
if(empty($indexe)) {
|
||
|
return false;
|
||
|
}
|
||
|
foreach($indexe as $index) {
|
||
|
if($index['Column_name'] === $pk
|
||
|
&& $index['Key_name'] === 'PRIMARY'
|
||
|
&& (int)$index['Non_unique'] === 0
|
||
|
) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
* @param string $pk
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
function CheckTable($table, $pk = 'id')
|
||
|
{
|
||
|
if($pk === 'id') {
|
||
|
$tables = $this->getAllTables();
|
||
|
if(!empty($tables)){
|
||
|
if(!in_array($table, $tables)){
|
||
|
$this->createTable($table, $pk);
|
||
|
return;
|
||
|
}
|
||
|
if(!$this->hasPrimaryKey($table, $pk)) {
|
||
|
$this->addPrimary($table, $pk);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
$found = false;
|
||
|
$tables = $this->getAllTables(true);
|
||
|
if($tables) {
|
||
|
$found = in_array($table, $tables);
|
||
|
}
|
||
|
else{
|
||
|
$check = $this->app->DB->Select("SELECT $pk FROM `$table` LIMIT 1");
|
||
|
if($check) {
|
||
|
$found = true;
|
||
|
}
|
||
|
}
|
||
|
if($found==false)
|
||
|
{
|
||
|
$sql = "CREATE TABLE `$table` (`".$pk."` INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (`".$pk."`)) ENGINE = InnoDB DEFAULT CHARSET=utf8";
|
||
|
$this->app->DB->Update($sql);
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table`
|
||
|
ADD PRIMARY KEY (`".$pk."`)");
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table`
|
||
|
MODIFY `".$pk."` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1");
|
||
|
}
|
||
|
if($pk !== 'id') {
|
||
|
$this->CheckColumn('created_at','timestamp',$table,"DEFAULT CURRENT_TIMESTAMP NOT NULL");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param string $type
|
||
|
* @param string $table
|
||
|
* @param string $default
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
function UpdateColumn($column,$type,$table,$default="NOT NULL")
|
||
|
{
|
||
|
$fields = $this->app->DB->SelectArr("show columns from `".$table."`");
|
||
|
if($fields)
|
||
|
{
|
||
|
foreach($fields as $val)
|
||
|
{
|
||
|
$field_array[] = $val['Field'];
|
||
|
}
|
||
|
}
|
||
|
if (in_array($column, $field_array))
|
||
|
{
|
||
|
$this->app->DB->Query('ALTER TABLE `'.$table.'` CHANGE `'.$column.'` `'.$column.'` '.$type.' '.$default.';');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param string $table
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function DeleteColumn($column,$table)
|
||
|
{
|
||
|
$this->app->DB->Query('ALTER TABLE `'.$table.'` DROP `'.$column.'`;');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param string $type
|
||
|
* @param string $table
|
||
|
* @param string $default
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function CheckColumn($column,$type,$table,$default="")
|
||
|
{
|
||
|
if($table === 'firmendaten')
|
||
|
{
|
||
|
if($this->app->DB->Select("SELECT `id` FROM `firmendaten_werte` WHERE `name` = '$column' LIMIT 1"))return;
|
||
|
}
|
||
|
if(!isset($this->CheckColumnTableCache[$table]))
|
||
|
{
|
||
|
$tmp=$this->app->DB->SelectArr("show columns from `".$table."`");
|
||
|
if($tmp)
|
||
|
{
|
||
|
foreach($tmp as $val)
|
||
|
{
|
||
|
$this->CheckColumnTableCache[$table][] = $val['Field'];
|
||
|
//$types[$val['Field']] = strtolower($val['Type']);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (isset($this->CheckColumnTableCache[$table]) && !in_array($column, $this->CheckColumnTableCache[$table]))
|
||
|
{
|
||
|
if($this->check_column_missing_run)
|
||
|
{
|
||
|
//$result = mysqli_query($this->app->DB->connection,'ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
|
||
|
$this->check_column_missing[$table][]=$column;
|
||
|
} else {
|
||
|
$result = $this->app->DB->Query('ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
|
||
|
if($table === 'firmendaten' && $this->app->DB->error())
|
||
|
{
|
||
|
if((method_exists($this->app->DB, 'errno2') && $this->app->DB->errno() == '1118')
|
||
|
|| strpos($this->app->DB->error(),'Row size too large') !== false
|
||
|
)
|
||
|
{
|
||
|
$this->ChangeFirmendatenToMyIsam();
|
||
|
$this->app->DB->Query('ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array $indexe
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
protected function getGroupedIndexe($indexe)
|
||
|
{
|
||
|
if(empty($indexe)) {
|
||
|
return $indexe;
|
||
|
}
|
||
|
$return = [];
|
||
|
foreach($indexe as $index) {
|
||
|
$keyName = $index['Key_name'];
|
||
|
$isUnique = $index['Non_unique'] == '0';
|
||
|
$seq = $index['Seq_in_index'];
|
||
|
$columnName = $index['Column_name'];
|
||
|
$return[$isUnique?'unique':'index'][$keyName][(int)$seq - 1] = $columnName;
|
||
|
}
|
||
|
|
||
|
return $return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array $indexe
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
protected function getDoubleIndexeFromGroupedIndexe($indexe)
|
||
|
{
|
||
|
if(empty($indexe)) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
$ret = [];
|
||
|
foreach($indexe as $type => $indexArrs) {
|
||
|
$columnStrings = [];
|
||
|
foreach($indexArrs as $indexKey => $columns) {
|
||
|
$columnString = implode('|', $columns);
|
||
|
if(in_array($columnString, $columnStrings)) {
|
||
|
$ret[$type][] = $indexKey;
|
||
|
continue;
|
||
|
}
|
||
|
$columnStrings[] = $columnString;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $ret;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
* @param array $indexe
|
||
|
* @param bool $noCache
|
||
|
*
|
||
|
* @return array|null
|
||
|
*/
|
||
|
public function CheckDoubleIndex($table, $indexe, $noCache = false)
|
||
|
{
|
||
|
$query = $noCache?null:$this->CheckAlterTable("SHOW INDEX FROM `$table`");
|
||
|
if(!$query) {
|
||
|
$indexeGrouped = $this->getGroupedIndexe($indexe);
|
||
|
$doubleIndexe = $this->getDoubleIndexeFromGroupedIndexe($indexeGrouped);
|
||
|
if(!empty($doubleIndexe)) {
|
||
|
$indexe = $this->getIndexeCached($table, true);
|
||
|
$indexeGrouped = $this->getGroupedIndexe($indexe);
|
||
|
$doubleIndexe = $this->getDoubleIndexeFromGroupedIndexe($indexeGrouped);
|
||
|
if(empty($doubleIndexe)) {
|
||
|
return $indexe;
|
||
|
}
|
||
|
|
||
|
foreach($doubleIndexe as $type => $doubleIndex) {
|
||
|
foreach($doubleIndex as $indexName) {
|
||
|
$this->app->DB->Query("ALTER TABLE `".$table."` DROP INDEX `".$indexName."`");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
elseif($noCache) {
|
||
|
return $indexe;
|
||
|
}
|
||
|
$this->CheckAlterTable("SHOW INDEX FROM `$table`", true);
|
||
|
|
||
|
return $this->getIndexeCached($table, true);
|
||
|
}
|
||
|
if(empty($indexe) || count($indexe) == 1){
|
||
|
return $indexe;
|
||
|
}
|
||
|
$uniquearr = array();
|
||
|
$indexarr = array();
|
||
|
foreach($indexe as $index)
|
||
|
{
|
||
|
if($index['Key_name'] !== 'PRIMARY' && !empty($index['Column_name']))
|
||
|
{
|
||
|
if($index['Non_unique'])
|
||
|
{
|
||
|
$indexarr[$index['Key_name']][] = $index['Column_name'];
|
||
|
}else{
|
||
|
$uniquearr[$index['Key_name']][] = $index['Column_name'];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$cindex = count($indexarr);
|
||
|
$cuniqe = count($uniquearr);
|
||
|
$changed = false;
|
||
|
if($cindex > 1)
|
||
|
{
|
||
|
$check = array();
|
||
|
foreach($indexarr as $key => $value)
|
||
|
{
|
||
|
if(empty($value))
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
if(count($value) > 1){
|
||
|
sort($value);
|
||
|
}
|
||
|
$vstr = implode(',', $value);
|
||
|
if(in_array($vstr, $check))
|
||
|
{
|
||
|
$this->app->DB->Query("DROP INDEX `".$key."` ON `".$table."`");
|
||
|
$changed = true;
|
||
|
}else{
|
||
|
$check[] = $vstr;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if($cuniqe > 1)
|
||
|
{
|
||
|
$check = array();
|
||
|
foreach($uniquearr as $key => $value)
|
||
|
{
|
||
|
if(empty($value))
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
if(count($value) > 1){
|
||
|
sort($value);
|
||
|
}
|
||
|
$vstr = implode(',', $value);
|
||
|
if(in_array($vstr, $check))
|
||
|
{
|
||
|
$this->app->DB->Query("DROP UNIQUE `".$key."` ON `".$table."`");
|
||
|
$changed = true;
|
||
|
}else{
|
||
|
$check[] = $vstr;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if($changed) {
|
||
|
return $this->getIndexeCached($table, true);
|
||
|
}
|
||
|
return $indexe;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
* @param string|array $column
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function CheckFulltextIndex($table,$column)
|
||
|
{
|
||
|
if(empty($table) || empty($column))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
if(!is_array($column))
|
||
|
{
|
||
|
$column = [$column];
|
||
|
}
|
||
|
$columnmasked = [];
|
||
|
foreach($column as $keyColumn => $valueColumn)
|
||
|
{
|
||
|
if(!empty($valueColumn))
|
||
|
{
|
||
|
$columnmasked[] = "`$valueColumn`";
|
||
|
}else{
|
||
|
unset($column[$keyColumn]);
|
||
|
}
|
||
|
}
|
||
|
if(empty($column))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
$columnsFound = [];
|
||
|
$indexe = $this->getIndexeCached($table, true);
|
||
|
$indexeFound = [];
|
||
|
if(!empty($indexe))
|
||
|
{
|
||
|
foreach($indexe as $index)
|
||
|
{
|
||
|
if($index['Index_type'] === 'FULLTEXT')
|
||
|
{
|
||
|
$indexeFound[] = $index['Column_name'];
|
||
|
if(!in_array($index['Column_name'], $columnsFound))
|
||
|
{
|
||
|
$columnsFound[] = $index['Column_name'];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$cindexeFound = count($indexeFound);
|
||
|
$column = count($column);
|
||
|
if(($column === $cindexeFound) && (count($columnsFound) === $column))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
if($cindexeFound > 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
$this->app->DB->Query(
|
||
|
"ALTER TABLE `$table`
|
||
|
ADD FULLTEXT INDEX `FullText`
|
||
|
(".implode(',',$columnmasked).");"
|
||
|
);
|
||
|
$error = $this->app->DB->error();
|
||
|
|
||
|
return empty($error);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
* @param string $column
|
||
|
* @param bool $unique
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
function CheckIndex($table, $column, $unique = false)
|
||
|
{
|
||
|
$indexex = null;
|
||
|
$indexexother = null;
|
||
|
$indexe = $this->getIndexeCached($table);
|
||
|
if($indexe)
|
||
|
{
|
||
|
$indexe = $this->CheckDoubleIndex($table, $indexe, true);
|
||
|
foreach($indexe as $index)
|
||
|
{
|
||
|
if(is_array($column) && $index['Key_name'] !== 'PRIMARY')
|
||
|
{
|
||
|
if($unique && !$index['Non_unique'])
|
||
|
{
|
||
|
if(in_array($index['Column_name'], $column))
|
||
|
{
|
||
|
$indexex[$index['Key_name']][$index['Column_name']] = true;
|
||
|
}else{
|
||
|
$indexexother[$index['Key_name']][$index['Column_name']] = true;
|
||
|
}
|
||
|
}
|
||
|
elseif(!$unique){
|
||
|
if(in_array($index['Column_name'], $column)) {
|
||
|
$indexex[$index['Key_name']][$index['Column_name']] = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
elseif(!is_array($column)){
|
||
|
if($index['Column_name'] == $column)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if($this->check_column_missing_run)
|
||
|
{
|
||
|
$this->check_index_missing[$table][] = $column;
|
||
|
}
|
||
|
if(!$unique)
|
||
|
{
|
||
|
if(is_array($column))
|
||
|
{
|
||
|
if($indexex)
|
||
|
{
|
||
|
foreach($indexex as $k => $v) {
|
||
|
if(count($v) === 1 && count($column) > 1) {
|
||
|
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
|
||
|
$this->clearIndexCached($table);
|
||
|
unset($indexex[$k]);
|
||
|
}
|
||
|
}
|
||
|
foreach($indexex as $k => $v)
|
||
|
{
|
||
|
if(count($v) == count($column)){
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
foreach($indexex as $k => $v)
|
||
|
{
|
||
|
if(!isset($indexexother[$k]))
|
||
|
{
|
||
|
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
|
||
|
$cols = null;
|
||
|
foreach($column as $c) {
|
||
|
$cols[] = "`$c`";
|
||
|
}
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(".implode(', ',$cols)."); ",true);
|
||
|
$this->clearIndexCached($table);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$cols = null;
|
||
|
foreach($column as $c) {
|
||
|
$cols[] = "`$c`";
|
||
|
}
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(".implode(', ',$cols)."); ", true);
|
||
|
$this->clearIndexCached($table);
|
||
|
}
|
||
|
else{
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(`$column`); ", true);
|
||
|
$this->clearIndexCached($table);
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
if(is_array($column))
|
||
|
{
|
||
|
if($indexex)
|
||
|
{
|
||
|
foreach($indexex as $k => $v)
|
||
|
{
|
||
|
if(count($v) == count($column))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
foreach($indexex as $k => $v)
|
||
|
{
|
||
|
if(!isset($indexexother[$k]))
|
||
|
{
|
||
|
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
|
||
|
$cols = null;
|
||
|
foreach($column as $c) {
|
||
|
$cols[] = "`$c`";
|
||
|
}
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ", true);
|
||
|
$this->clearIndexCached($table);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$cols = null;
|
||
|
foreach($column as $c) {
|
||
|
$cols[] = "`$c`";
|
||
|
}
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ", true);
|
||
|
$this->clearIndexCached($table);
|
||
|
}else{
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(`$column`); ", true);
|
||
|
$this->clearIndexCached($table);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
elseif(!is_array($column))
|
||
|
{
|
||
|
if(!$unique)
|
||
|
{
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(`$column`); ");
|
||
|
}else{
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(`$column`); ");
|
||
|
}
|
||
|
$this->clearIndexCached($table);
|
||
|
}
|
||
|
elseif(is_array($column))
|
||
|
{
|
||
|
$cols = null;
|
||
|
foreach($column as $c) {
|
||
|
$cols[] = "`$c`";
|
||
|
}
|
||
|
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ");
|
||
|
$this->clearIndexCached($table);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $sql
|
||
|
* @param bool $force
|
||
|
*
|
||
|
* @return mysqli_result|bool
|
||
|
*/
|
||
|
function CheckAlterTable($sql, $force = false)
|
||
|
{
|
||
|
$sqlmd5 = md5($sql);
|
||
|
$check = $this->app->DB->Select("SELECT id FROM checkaltertable WHERE checksum='$sqlmd5' LIMIT 1");
|
||
|
if($check > 0 && !$force) return;
|
||
|
$query = $this->app->DB->Query($sql);
|
||
|
if($query && empty($check) && !$this->app->DB->error()){
|
||
|
$this->app->DB->Insert("INSERT INTO checkaltertable (id,checksum) VALUES ('','$sqlmd5')");
|
||
|
}
|
||
|
return $query;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return void
|
||
|
*/
|
||
|
public function ChangeFirmendatenToMyIsam()
|
||
|
{
|
||
|
$this->app->DB->Query("ALTER TABLE firmendaten ENGINE = MyISAM;");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getSortedIndexColumnsByIndexName($table): array
|
||
|
{
|
||
|
$indexesByName = [];
|
||
|
$indexes = $this->app->DB->SelectArr(sprintf('SHOW INDEX FROM `%s`', $table));
|
||
|
if(empty($indexes)) {
|
||
|
return $indexesByName;
|
||
|
}
|
||
|
foreach($indexes as $index) {
|
||
|
$indexesByName[$index['Key_name']][] = $index['Column_name'];
|
||
|
}
|
||
|
foreach($indexesByName as $indexName => $columns) {
|
||
|
$columns = array_unique($columns);
|
||
|
sort($columns);
|
||
|
$indexesByName[$indexName] = $columns;
|
||
|
}
|
||
|
|
||
|
return $indexesByName;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @deprecated will be removed in 21.4
|
||
|
*
|
||
|
* @param string $table
|
||
|
* @param array $columns
|
||
|
*/
|
||
|
public function dropIndex($table, $columns): void
|
||
|
{
|
||
|
if(empty($table) || empty($columns)) {
|
||
|
return;
|
||
|
}
|
||
|
$columns = array_unique($columns);
|
||
|
sort($columns);
|
||
|
$countColumns = count($columns);
|
||
|
$indexes = $this->getSortedIndexColumnsByIndexName($table);
|
||
|
if(empty($indexes)) {
|
||
|
return;
|
||
|
}
|
||
|
foreach($indexes as $indexName => $indexColumns) {
|
||
|
if(count($indexColumns) !== $countColumns) {
|
||
|
continue;
|
||
|
}
|
||
|
if(count(array_intersect($indexColumns, $columns)) === $countColumns) {
|
||
|
$this->app->DB->Query(sprintf('ALTER TABLE `%s` DROP INDEX `%s`', $table, $indexName));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|