2022-11-24 12:37:20 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper to compare database structures from files vs. database
|
|
|
|
*
|
|
|
|
* Copyright (c) 2022 OpenXE project
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2022-11-29 20:05:19 +01:00
|
|
|
MariaDB [openxe]> SHOW FULL db_def;
|
2022-11-24 12:37:20 +01:00
|
|
|
+----------------------------------------------+------------+
|
|
|
|
| Tables_in_openxe | Table_type |
|
|
|
|
+----------------------------------------------+------------+
|
|
|
|
| abrechnungsartikel | BASE TABLE |
|
|
|
|
| abrechnungsartikel_gruppe | BASE TABLE |
|
|
|
|
| abschlagsrechnung_rechnung | BASE TABLE |
|
|
|
|
| accordion | BASE TABLE |
|
|
|
|
| adapterbox | BASE TABLE |
|
|
|
|
| adapterbox_log | BASE TABLE |
|
|
|
|
| adapterbox_request_log | BASE TABLE |
|
|
|
|
| adresse | BASE TABLE |
|
|
|
|
| adresse_abosammelrechnungen | BASE TABLE |
|
|
|
|
| adresse_accounts | BASE TABLE |
|
|
|
|
| adresse_filter | BASE TABLE |
|
|
|
|
| adresse_filter_gruppen | BASE TABLE |
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
MariaDB [openxe]> SHOW FULL COLUMNS FROM wiki;
|
|
|
|
+-------------------+--------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
|
|
|
|
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
|
|
|
|
+-------------------+--------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
|
|
|
|
| id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | |
|
|
|
|
| name | varchar(255) | utf8mb3_general_ci | YES | MUL | NULL | | select,insert,update,references | |
|
|
|
|
| content | longtext | utf8mb3_general_ci | NO | | NULL | | select,insert,update,references | |
|
|
|
|
| lastcontent | longtext | utf8mb3_general_ci | NO | | NULL | | select,insert,update,references | |
|
|
|
|
| wiki_workspace_id | int(11) | NULL | NO | | 0 | | select,insert,update,references | |
|
|
|
|
| parent_id | int(11) | NULL | NO | | 0 | | select,insert,update,references | |
|
|
|
|
| language | varchar(32) | utf8mb3_general_ci | NO | | | | select,insert,update,references | |
|
|
|
|
+-------------------+--------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
|
2022-11-29 20:05:19 +01:00
|
|
|
|
|
|
|
MariaDB [openxe]> show keys from wiki;
|
|
|
|
+-------+------------+----------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
|
|
|
|
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Ignored |
|
|
|
|
+-------+------------+----------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
|
|
|
|
| wiki | 0 | PRIMARY | 1 | id | A | 244 | NULL | NULL | | BTREE | | | NO |
|
|
|
|
| wiki | 0 | suche | 1 | name | A | 244 | NULL | NULL | YES | BTREE | | | NO |
|
|
|
|
| wiki | 0 | suche | 2 | wiki_workspace_id | A | 244 | NULL | NULL | | BTREE | | | NO |
|
|
|
|
| wiki | 1 | name | 1 | name | A | 244 | NULL | NULL | YES | BTREE | | | NO |
|
|
|
|
+-------+------------+----------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
|
2022-11-24 12:37:20 +01:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2022-12-02 23:55:58 +01:00
|
|
|
require('mustal_mysql_upgrade_tool.php');
|
2022-11-24 12:37:20 +01:00
|
|
|
|
2022-11-30 22:39:24 +01:00
|
|
|
$connection_info_file_name = "connection_info.json";
|
2022-11-29 20:05:19 +01:00
|
|
|
$target_folder = ".";
|
|
|
|
$tables_file_name_wo_folder = "db_schema.json";
|
|
|
|
$tables_file_name_w_folder = $target_folder."/".$tables_file_name_wo_folder;
|
2022-11-24 12:37:20 +01:00
|
|
|
$delimiter = ";";
|
|
|
|
$quote = '"';
|
|
|
|
|
2022-11-25 12:53:06 +01:00
|
|
|
$sql_file_name = "upgrade.sql";
|
|
|
|
|
2022-11-24 12:37:20 +01:00
|
|
|
$color_red = "\033[31m";
|
|
|
|
$color_green = "\033[32m";
|
|
|
|
$color_yellow = "\033[33m";
|
|
|
|
$color_default = "\033[39m";
|
|
|
|
|
2022-11-30 18:32:10 +01:00
|
|
|
// -------------------------------- START
|
|
|
|
|
2022-11-24 12:37:20 +01:00
|
|
|
echo("\n");
|
|
|
|
|
|
|
|
if ($argc > 1) {
|
|
|
|
|
|
|
|
if (in_array('-v', $argv)) {
|
|
|
|
$verbose = true;
|
|
|
|
} else {
|
|
|
|
$verbose = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (in_array('-f', $argv)) {
|
|
|
|
$force = true;
|
|
|
|
} else {
|
|
|
|
$force = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (in_array('-e', $argv)) {
|
|
|
|
$export = true;
|
|
|
|
} else {
|
|
|
|
$export = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (in_array('-c', $argv)) {
|
|
|
|
$compare = true;
|
|
|
|
} else {
|
|
|
|
$compare = false;
|
|
|
|
}
|
|
|
|
|
2022-11-24 14:59:49 +01:00
|
|
|
if (in_array('-i', $argv)) {
|
|
|
|
$onlytables = true;
|
2022-11-24 12:37:20 +01:00
|
|
|
} else {
|
2022-11-24 14:59:49 +01:00
|
|
|
$onlytables = false;
|
|
|
|
}
|
2022-11-24 12:37:20 +01:00
|
|
|
|
2022-11-24 23:16:50 +01:00
|
|
|
if (in_array('-upgrade', $argv)) {
|
|
|
|
$upgrade = true;
|
|
|
|
} else {
|
|
|
|
$upgrade = false;
|
|
|
|
}
|
|
|
|
|
2022-11-30 18:32:10 +01:00
|
|
|
if (in_array('-do', $argv)) {
|
|
|
|
$doupgrade = true;
|
|
|
|
} else {
|
|
|
|
$doupgrade = false;
|
|
|
|
}
|
|
|
|
|
2022-11-24 23:16:50 +01:00
|
|
|
if (in_array('-clean', $argv)) {
|
|
|
|
$clean = true;
|
|
|
|
} else {
|
|
|
|
$clean = false;
|
|
|
|
}
|
|
|
|
|
2022-12-06 15:43:02 +01:00
|
|
|
if (in_array('-utf8fix', $argv)) {
|
|
|
|
$utf8fix = true;
|
|
|
|
} else {
|
|
|
|
$utf8fix = false;
|
|
|
|
}
|
|
|
|
|
2022-11-30 22:39:24 +01:00
|
|
|
$connection_info_contents = file_get_contents($connection_info_file_name);
|
|
|
|
if (!$connection_info_contents) {
|
|
|
|
echo("Unable to load $connection_info_file_name\n");
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
$connection_info = json_decode($connection_info_contents, true);
|
|
|
|
|
|
|
|
$host = $connection_info['host'];
|
|
|
|
$user = $connection_info['user'];
|
|
|
|
$passwd = $connection_info['passwd'];
|
|
|
|
$schema = $connection_info['database'];
|
|
|
|
|
2022-11-28 13:08:13 +01:00
|
|
|
echo("--------------- Loading from database '$schema@$host'... ---------------\n");
|
2022-12-02 23:55:58 +01:00
|
|
|
$db_def = mustal_load_tables_from_db($host, $schema, $user, $passwd, $mustal_replacers);
|
2022-11-24 12:37:20 +01:00
|
|
|
|
2022-11-29 20:05:19 +01:00
|
|
|
if (empty($db_def)) {
|
2022-11-24 14:59:49 +01:00
|
|
|
echo ("Could not load from $schema@$host\n");
|
2022-11-24 12:37:20 +01:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2022-11-28 13:08:13 +01:00
|
|
|
echo("--------------- Loading from database '$schema@$host' complete. ---------------\n");
|
2022-11-24 12:37:20 +01:00
|
|
|
|
|
|
|
if ($export) {
|
|
|
|
|
2022-11-29 20:05:19 +01:00
|
|
|
echo("--------------- Export to JSON... ---------------\n");
|
|
|
|
// $result = save_tables_to_csv($db_def, $target_folder, $tables_file_name_wo_folder, $delimiter, $quote, $keys_postfix, $force);
|
2022-12-02 23:55:58 +01:00
|
|
|
$result = mustal_save_tables_to_json($db_def, $target_folder, $tables_file_name_wo_folder, $force);
|
2022-11-29 20:05:19 +01:00
|
|
|
|
|
|
|
if ($result != 0) {
|
|
|
|
|
|
|
|
$result_texts = array("ok","key postfix error","table list file error","table file error","key file error");
|
2022-11-24 12:37:20 +01:00
|
|
|
|
2022-11-29 20:05:19 +01:00
|
|
|
echo ("Could not save to JSON (".$result_texts[$result]."). To overwrite, use -f.\n");
|
2022-11-24 12:37:20 +01:00
|
|
|
exit;
|
|
|
|
}
|
2022-11-24 14:59:49 +01:00
|
|
|
|
2022-11-29 20:05:19 +01:00
|
|
|
echo("Exported ".count($db_def['tables'])." tables.\n");
|
|
|
|
echo("--------------- Export to JSON ($tables_file_name_w_folder) complete. ---------------\n");
|
2022-11-24 12:37:20 +01:00
|
|
|
}
|
|
|
|
|
2022-11-24 23:16:50 +01:00
|
|
|
if ($compare || $upgrade) {
|
2022-11-24 12:37:20 +01:00
|
|
|
|
|
|
|
// Results here as ['text'] ['diff']
|
|
|
|
$compare_differences = array();
|
|
|
|
|
2022-11-29 20:05:19 +01:00
|
|
|
echo("--------------- Loading from JSON... ---------------\n");
|
2022-12-02 23:55:58 +01:00
|
|
|
$compare_def = mustal_load_tables_from_json($target_folder, $tables_file_name_wo_folder);
|
2022-11-24 12:37:20 +01:00
|
|
|
|
2022-11-29 20:05:19 +01:00
|
|
|
if (empty($compare_def)) {
|
|
|
|
echo ("Could not load from JSON $tables_file_name_w_folder\n");
|
2022-11-24 12:37:20 +01:00
|
|
|
exit;
|
|
|
|
}
|
2022-11-29 20:05:19 +01:00
|
|
|
echo("--------------- Loading from JSON complete. ---------------\n");
|
2022-11-24 12:37:20 +01:00
|
|
|
|
|
|
|
// Do the comparison
|
2022-11-30 18:32:10 +01:00
|
|
|
/*
|
2022-11-29 20:05:19 +01:00
|
|
|
echo("--------------- Comparing JSON '".$compare_def['database']."@".$compare_def['host']."' vs. database '$schema@$host' ---------------\n");
|
2022-11-24 12:37:20 +01:00
|
|
|
|
2022-11-29 20:05:19 +01:00
|
|
|
echo(count($compare_def['tables'])." tables in JSON, ".count($db_def['tables'])." tables in database.\n");
|
|
|
|
$compare_differences = compare_table_array($db_def,"in DB",$compare_def,"in JSON",false);
|
2022-11-24 12:37:20 +01:00
|
|
|
echo("Comparison found ".(empty($compare_differences)?0:count($compare_differences))." differences.\n");
|
|
|
|
|
2022-11-25 12:53:06 +01:00
|
|
|
if ($verbose) {
|
|
|
|
foreach ($compare_differences as $compare_difference) {
|
|
|
|
$comma = "";
|
|
|
|
foreach ($compare_difference as $key => $value) {
|
|
|
|
echo($comma."$key => '$value'");
|
|
|
|
$comma = ", ";
|
|
|
|
}
|
|
|
|
echo("\n");
|
|
|
|
}
|
2022-11-30 18:32:10 +01:00
|
|
|
}*/
|
2022-11-28 13:08:13 +01:00
|
|
|
|
2022-11-29 20:05:19 +01:00
|
|
|
echo("--------------- Comparing database '$schema@$host' vs. JSON '".$compare_def['database']."@".$compare_def['host']."' ---------------\n");
|
2022-12-06 15:43:02 +01:00
|
|
|
|
|
|
|
if($utf8fix) {
|
|
|
|
$column_collation_aliases = array(
|
|
|
|
['utf8mb3_general_ci','utf8_general_ci']
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$column_collation_aliases = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true,$column_collation_aliases);
|
2022-12-01 21:57:13 +01:00
|
|
|
echo((empty($compare_differences)?0:count($compare_differences))." differences.\n");
|
2022-11-25 12:53:06 +01:00
|
|
|
|
|
|
|
if ($verbose) {
|
|
|
|
foreach ($compare_differences as $compare_difference) {
|
|
|
|
$comma = "";
|
|
|
|
foreach ($compare_difference as $key => $value) {
|
2022-12-01 21:57:13 +01:00
|
|
|
echo($comma."$key => [$value]");
|
2022-11-25 12:53:06 +01:00
|
|
|
$comma = ", ";
|
|
|
|
}
|
|
|
|
echo("\n");
|
|
|
|
}
|
|
|
|
}
|
2022-11-24 12:37:20 +01:00
|
|
|
echo("--------------- Comparison complete. ---------------\n");
|
|
|
|
}
|
|
|
|
|
2022-11-24 23:16:50 +01:00
|
|
|
if ($upgrade) {
|
2022-11-29 20:05:19 +01:00
|
|
|
// First create all db_def that are missing in the db
|
2022-11-28 13:08:13 +01:00
|
|
|
echo("--------------- Calculating database upgrade for '$schema@$host'... ---------------\n");
|
2022-11-24 23:16:50 +01:00
|
|
|
|
2022-11-25 18:01:51 +01:00
|
|
|
$upgrade_sql = array();
|
|
|
|
|
2022-12-06 13:13:14 +01:00
|
|
|
$result = mustal_calculate_db_upgrade($compare_def, $db_def, $upgrade_sql, $mustal_replacers);
|
2022-11-24 23:16:50 +01:00
|
|
|
|
2022-12-02 23:55:58 +01:00
|
|
|
if ($result != 0) {
|
|
|
|
echo("Error: $result\n");
|
|
|
|
exit;
|
2022-11-24 23:16:50 +01:00
|
|
|
}
|
|
|
|
|
2022-12-06 13:13:14 +01:00
|
|
|
if (!empty($result)) {
|
|
|
|
echo(count($result)." errors.\n");
|
|
|
|
if ($verbose) {
|
|
|
|
foreach($result as $error) {
|
|
|
|
echo("Code: ".$error[0]." '".$error[1]."'.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
2022-11-30 18:32:10 +01:00
|
|
|
echo("--------------- Database upgrade for '$schema@$host'... ---------------\n");
|
2022-11-25 18:01:51 +01:00
|
|
|
if ($verbose) {
|
|
|
|
foreach($upgrade_sql as $statement) {
|
|
|
|
echo($statement."\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
echo(count($upgrade_sql)." upgrade statements\n");
|
2022-11-28 13:08:13 +01:00
|
|
|
echo("--------------- Database upgrade calculated for '$schema@$host' (show SQL with -v). ---------------\n");
|
2022-11-30 18:32:10 +01:00
|
|
|
|
|
|
|
if ($doupgrade) {
|
2022-12-02 23:55:58 +01:00
|
|
|
echo("--------------- Executing database upgrade for '$schema@$host' database will be written! ---------------\n");
|
2022-11-30 18:32:10 +01:00
|
|
|
|
|
|
|
// First get the contents of the database table structure
|
|
|
|
$mysqli = mysqli_connect($host, $user, $passwd, $schema);
|
|
|
|
|
|
|
|
/* Check if the connection succeeded */
|
|
|
|
if (!$mysqli) {
|
|
|
|
echo ("Failed to connect!\n");
|
|
|
|
} else {
|
|
|
|
|
|
|
|
$counter = 0;
|
|
|
|
$error_counter = 0;
|
|
|
|
$number_of_statements = count($upgrade_sql);
|
|
|
|
|
|
|
|
foreach ($upgrade_sql as $sql) {
|
|
|
|
|
|
|
|
$counter++;
|
2022-12-01 21:57:13 +01:00
|
|
|
echo("\rUpgrade step $counter of $number_of_statements... ");
|
2022-11-30 18:32:10 +01:00
|
|
|
|
|
|
|
if ($verbose) {
|
|
|
|
echo("(".substr($sql,0,100)."...) ");
|
|
|
|
}
|
|
|
|
|
|
|
|
$query_result = mysqli_query($mysqli, $sql);
|
|
|
|
if (!$query_result) {
|
2022-11-30 20:17:27 +01:00
|
|
|
$error = " not ok: ". mysqli_error($mysqli)."\n";
|
2022-11-30 18:32:10 +01:00
|
|
|
echo($error);
|
|
|
|
file_put_contents("./errors.txt",$error.$sql."\n",FILE_APPEND);
|
|
|
|
$error_counter++;
|
|
|
|
} else {
|
2022-12-01 21:57:13 +01:00
|
|
|
echo("ok.\r");
|
2022-11-30 18:32:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-12-01 21:57:13 +01:00
|
|
|
echo("--------------- Executing database upgrade for '$schema@$host' executed. ---------------\n");
|
2022-11-30 18:32:10 +01:00
|
|
|
echo("$error_counter errors.\n");
|
|
|
|
echo("--------------- Executing database upgrade for '$schema@$host' done. ---------------\n");
|
2022-12-01 21:57:13 +01:00
|
|
|
|
|
|
|
echo("--------------- Checking database upgrade for '$schema@$host'... ---------------\n");
|
2022-12-02 23:55:58 +01:00
|
|
|
$db_def = mustal_load_tables_from_db($host, $schema, $user, $passwd, $mustal_replacers);
|
2022-12-01 21:57:13 +01:00
|
|
|
|
|
|
|
echo("--------------- Comparing database '$schema@$host' vs. JSON '".$compare_def['database']."@".$compare_def['host']."' ---------------\n");
|
2022-12-06 13:13:14 +01:00
|
|
|
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true);
|
2022-12-01 21:57:13 +01:00
|
|
|
echo((empty($compare_differences)?0:count($compare_differences))." differences.\n");
|
|
|
|
|
2022-11-30 18:32:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // upgrade
|
2022-11-24 23:16:50 +01:00
|
|
|
|
2022-11-24 12:37:20 +01:00
|
|
|
echo("--------------- Done. ---------------\n");
|
|
|
|
|
|
|
|
echo("\n");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
info();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2022-11-24 12:42:45 +01:00
|
|
|
function info() {
|
|
|
|
echo("OpenXE database compare\n");
|
|
|
|
echo("Copyright 2022 (c) OpenXE project\n");
|
|
|
|
echo("\n");
|
|
|
|
echo("Export database structures in a defined format for database comparison / upgrade\n");
|
|
|
|
echo("Options:\n");
|
|
|
|
echo("\t-v: verbose output\n");
|
|
|
|
echo("\t-f: force override of existing files\n");
|
|
|
|
echo("\t-e: export database structure to files\n");
|
|
|
|
echo("\t-c: compare content of files with database structure\n");
|
2022-11-24 14:59:49 +01:00
|
|
|
echo("\t-i: ignore column definitions\n");
|
2022-12-06 15:43:02 +01:00
|
|
|
echo("\t-utf8fix: apply fix for 'utf8' != 'utf8mb3'\n");
|
2022-11-29 20:05:19 +01:00
|
|
|
echo("\t-upgrade: Create the needed SQL to upgrade the database to match the JSON\n");
|
2022-11-30 18:32:10 +01:00
|
|
|
echo("\t-do: Execute the SQL to upgrade the database to match the JSON (risky!)\n");
|
2022-11-29 20:05:19 +01:00
|
|
|
echo("\t-clean: (not yet implemented) Create the needed SQL to remove items from the database not in the JSON\n");
|
2022-11-24 12:42:45 +01:00
|
|
|
echo("\n");
|
|
|
|
}
|
2022-11-24 12:37:20 +01:00
|
|
|
|