DBmodel/src/Maintenance.php
igor 616dc01c21 added namespace for created new model,
added method getListByID for new model,
added type of object for import method,
extends definition tor checkDBTable,
fixed typo in parameters of method existsColumn
2025-06-12 07:48:08 +02:00

234 lines
6.2 KiB
PHP

<?php
/*
Copyright (c) TPsoft.org 2000-2025
Author: Ing. Igor Mino <mino@tpsoft.org>
License: GNU GPL-3.0 or later
Description: Tool for automatic maintenance of database in your project.
Version: 1.0.0
Milestones:
2025-05-29 07:59 Igor - Forked from Beteha to standalone public library
*/
namespace TPsoft\DBmodel;
class Maintenance
{
public const ABNORMAL = 0;
public const OK = 1;
public const FIXED = 2;
public const FIX_FAILED = 3;
public const UPDATED = 4;
public const UPDATE_FAIL = 5;
public string $lastMessage = '';
protected DBmodel $dbh;
public function __construct(?DBmodel $dbh)
{
if (is_null($dbh)) {
if (!is_null(DBmodel::$instance)) {
$this->dbh = DBmodel::$instance;
} else {
throw new \Exception('DB handler is null');
}
} else {
$this->dbh = $dbh;
}
}
public function testDB($test, $test_out)
{
if (is_array($test_out)) {
$test_out = array_change_key_case($test_out, CASE_LOWER);
$row = $this->dbh->getRow($test);
if (!is_array($row)) return false;
$row = array_change_key_case($row, CASE_LOWER);
foreach ($test_out as $col => $val) {
if (strlen($row[$col]) != strlen($val)) {
$max_len = min(strlen($row[$col]), strlen($val));
if (substr(strtolower($row[$col]), 0, $max_len) != substr(strtolower($val), 0, $max_len)) {
return false;
}
} else {
if (strtolower($row[$col]) != strtolower($val)) {
return false;
}
}
}
return true;
} else {
return $this->dbh->getOne($test) == $test_out;
}
}
public function checkDB($test, $test_out, $fix)
{
if ($this->testDB($test, $test_out)) {
return Maintenance::OK;
} else {
$this->dbh->query($fix);
if ($this->testDB($test, $test_out)) {
return Maintenance::FIXED;
} else {
return Maintenance::FIX_FAILED;
}
}
return 0;
}
public function existsTable($table_name)
{
return $this->testDB(
'SHOW TABLES LIKE "' . $table_name . '"',
$table_name
);
}
public function checkDBTable($table_name, $definition, $after_definition = '')
{
if (strlen($table_name) <= 0) {
$this->lastMessage = 'Table ' . strtoupper($table_name) . ' - invalid index';
return Maintenance::ABNORMAL;
}
$status = $this->checkDB(
// TEST query
'SHOW TABLES LIKE "' . $table_name . '"',
// TEST output
$table_name,
// FIX query
'CREATE TABLE `' . $table_name . '` (' . $definition . ') ' . $after_definition
);
$this->lastMessage = 'Table ' . strtoupper($table_name) . ' (' . $table_name . ')';
return $status;
}
public function existsColumn($table_name, $column)
{
return $this->testDB(
'DESCRIBE `' . $table_name . '` `' . $column . '`',
$column
);
}
public function checkDBAdd($table_name, $column, $definition)
{
$status = $this->checkDB(
// TEST query
'DESCRIBE `' . $table_name . '` `' . $column . '`',
// TEST output
$column,
// FIX query
'ALTER TABLE `' . $table_name . '` ADD `' . $column . '` ' . $definition
);
$this->lastMessage = "Added column $column to table $table_name";
return $status;
}
public function checkDBRename($table_name, $column_old, $column_new, $definition, $test = null)
{
if (!$this->existsColumn($table_name, $column_old)) {
return Maintenance::ABNORMAL;
}
$status = $this->checkDB(
// TEST query
'DESCRIBE `' . $table_name . '` `' . $column_old . '`',
// TEST output
$test,
// FIX query
'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_old . '` `' . $column_new . '` ' . $definition
);
$this->lastMessage = "Renamed column $column_old to $column_new for $table_name";
return $status;
}
public function checkDBRetype($table_name, $column, $new_type, $definition)
{
if (!$this->existsColumn($table_name, $column)) {
return Maintenance::ABNORMAL;
}
$status = $this->checkDB(
// TEST query
'DESCRIBE `' . $table_name . '` `' . $column . '`',
// TEST output
array('type' => strtolower($new_type)),
// FIX query
'ALTER TABLE `' . $table_name . '` CHANGE `' . $column . '` `' . $column . '` ' . $definition
);
$this->lastMessage = "Changed type of column $column for table " . strtoupper($table_name) . " to tyoe " . strtoupper($new_type);
return $status;
}
public function checkDBRemove($table_name, $column)
{
$status = $this->checkDB(
// TEST query
'DESCRIBE `' . $table_name . '` `' . $column . '`',
// TEST output
NULL,
// FIX query
'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column . '`'
);
$this->lastMessage = "Removed column $column for " . strtoupper($table_name);
return $status;
}
public function addKey($table_name, $key)
{
$test = 'SHOW INDEX FROM `' . $table_name . '` WHERE column_name = "' . $key . '"';
$test_out = array('table' => $table_name);
if ($this->testDB($test, $test_out)) {
$status = Maintenance::OK;
} else {
$fix = 'CREATE INDEX `' . $key . '` ON `' . $table_name . '` (`' . $key . '`)';
$this->dbh->query($fix);
if ($this->testDB($test, $test_out)) {
$status = Maintenance::FIXED;
} else {
$status = Maintenance::FIX_FAILED;
}
}
$this->lastMessage = 'Added KEY ' . $key . ' for ' . strtoupper($table_name);
return $status;
}
public function dropKey($table_name, $key)
{
$test = 'SHOW INDEX FROM `' . $table_name . '` WHERE column_name = "' . $key . '"';
$test_out = null;
if ($this->testDB($test, $test_out)) {
$status = Maintenance::OK;
} else {
$index_info = $this->dbh->getRow('SHOW INDEX FROM `' . $table_name . '` WHERE column_name = "' . $key . '"');
$index_info = array_change_key_case($index_info, CASE_LOWER);
$index_name = $index_info['key_name'];
$fix = 'ALTER TABLE `' . $table_name . '` DROP INDEX `' . $index_name . '`';
$this->dbh->query($fix);
if ($this->testDB($test, $test_out)) {
$status = Maintenance::FIXED;
} else {
$status = Maintenance::FIX_FAILED;
}
}
$this->lastMessage = 'Deleted KEY ' . $key . ' for ' . strtoupper($table_name);
return $status;
}
public function updateDB($test, $test_out, $update)
{
if (!$this->testDB($test, $test_out)) {
return Maintenance::OK;
} else {
$suc = $this->dbh->query($update);
if ($suc !== false) {
return Maintenance::UPDATED;
} else {
return Maintenance::UPDATE_FAIL;
}
}
return 0;
}
}