mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-25 06:00:28 +01:00
Bestellvorschlag table for saved values and auftrag WIP
This commit is contained in:
parent
aa3dea0277
commit
5b74049f5c
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"host": "localhost",
|
|
||||||
"database": "openxe",
|
|
||||||
"user": "openxe",
|
|
||||||
"passwd": "openxe"
|
|
||||||
}
|
|
@ -1,343 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper to compare database structures from files vs. database
|
|
||||||
*
|
|
||||||
* Copyright (c) 2022 OpenXE project
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
MariaDB [openxe]> SHOW FULL db_def;
|
|
||||||
+----------------------------------------------+------------+
|
|
||||||
| 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 | |
|
|
||||||
+-------------------+--------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
|
|
||||||
|
|
||||||
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 |
|
|
||||||
+-------+------------+----------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
require('mustal_mysql_upgrade_tool.php');
|
|
||||||
|
|
||||||
$connection_info_file_name = "connection_info.json";
|
|
||||||
$target_folder = ".";
|
|
||||||
$tables_file_name_wo_folder = "db_schema.json";
|
|
||||||
$tables_file_name_w_folder = $target_folder."/".$tables_file_name_wo_folder;
|
|
||||||
$delimiter = ";";
|
|
||||||
$quote = '"';
|
|
||||||
|
|
||||||
$sql_file_name = "upgrade.sql";
|
|
||||||
|
|
||||||
$color_red = "\033[31m";
|
|
||||||
$color_green = "\033[32m";
|
|
||||||
$color_yellow = "\033[33m";
|
|
||||||
$color_default = "\033[39m";
|
|
||||||
|
|
||||||
// -------------------------------- START
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('-i', $argv)) {
|
|
||||||
$onlytables = true;
|
|
||||||
} else {
|
|
||||||
$onlytables = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('-upgrade', $argv)) {
|
|
||||||
$upgrade = true;
|
|
||||||
} else {
|
|
||||||
$upgrade = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('-do', $argv)) {
|
|
||||||
$doupgrade = true;
|
|
||||||
} else {
|
|
||||||
$doupgrade = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('-clean', $argv)) {
|
|
||||||
$clean = true;
|
|
||||||
} else {
|
|
||||||
$clean = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('-utf8fix', $argv)) {
|
|
||||||
$utf8fix = true;
|
|
||||||
} else {
|
|
||||||
$utf8fix = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$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'];
|
|
||||||
|
|
||||||
echo("--------------- Loading from database '$schema@$host'... ---------------\n");
|
|
||||||
$db_def = mustal_load_tables_from_db($host, $schema, $user, $passwd, $mustal_replacers);
|
|
||||||
|
|
||||||
if (empty($db_def)) {
|
|
||||||
echo ("Could not load from $schema@$host\n");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo("--------------- Loading from database '$schema@$host' complete. ---------------\n");
|
|
||||||
|
|
||||||
if ($export) {
|
|
||||||
|
|
||||||
echo("--------------- Export to JSON... ---------------\n");
|
|
||||||
// $result = save_tables_to_csv($db_def, $target_folder, $tables_file_name_wo_folder, $delimiter, $quote, $keys_postfix, $force);
|
|
||||||
$result = mustal_save_tables_to_json($db_def, $target_folder, $tables_file_name_wo_folder, $force);
|
|
||||||
|
|
||||||
if ($result != 0) {
|
|
||||||
|
|
||||||
$result_texts = array("ok","key postfix error","table list file error","table file error","key file error");
|
|
||||||
|
|
||||||
echo ("Could not save to JSON (".$result_texts[$result]."). To overwrite, use -f.\n");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo("Exported ".count($db_def['tables'])." tables.\n");
|
|
||||||
echo("--------------- Export to JSON ($tables_file_name_w_folder) complete. ---------------\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($compare || $upgrade) {
|
|
||||||
|
|
||||||
// Results here as ['text'] ['diff']
|
|
||||||
$compare_differences = array();
|
|
||||||
|
|
||||||
echo("--------------- Loading from JSON... ---------------\n");
|
|
||||||
$compare_def = mustal_load_tables_from_json($target_folder, $tables_file_name_wo_folder);
|
|
||||||
|
|
||||||
if (empty($compare_def)) {
|
|
||||||
echo ("Could not load from JSON $tables_file_name_w_folder\n");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
echo("--------------- Loading from JSON complete. ---------------\n");
|
|
||||||
|
|
||||||
// Do the comparison
|
|
||||||
/*
|
|
||||||
echo("--------------- Comparing JSON '".$compare_def['database']."@".$compare_def['host']."' vs. database '$schema@$host' ---------------\n");
|
|
||||||
|
|
||||||
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);
|
|
||||||
echo("Comparison found ".(empty($compare_differences)?0:count($compare_differences))." differences.\n");
|
|
||||||
|
|
||||||
if ($verbose) {
|
|
||||||
foreach ($compare_differences as $compare_difference) {
|
|
||||||
$comma = "";
|
|
||||||
foreach ($compare_difference as $key => $value) {
|
|
||||||
echo($comma."$key => '$value'");
|
|
||||||
$comma = ", ";
|
|
||||||
}
|
|
||||||
echo("\n");
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
echo("--------------- Comparing database '$schema@$host' vs. JSON '".$compare_def['database']."@".$compare_def['host']."' ---------------\n");
|
|
||||||
|
|
||||||
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);
|
|
||||||
echo((empty($compare_differences)?0:count($compare_differences))." differences.\n");
|
|
||||||
|
|
||||||
if ($verbose) {
|
|
||||||
foreach ($compare_differences as $compare_difference) {
|
|
||||||
$comma = "";
|
|
||||||
foreach ($compare_difference as $key => $value) {
|
|
||||||
echo($comma."$key => [$value]");
|
|
||||||
$comma = ", ";
|
|
||||||
}
|
|
||||||
echo("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo("--------------- Comparison complete. ---------------\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($upgrade) {
|
|
||||||
// First create all db_def that are missing in the db
|
|
||||||
echo("--------------- Calculating database upgrade for '$schema@$host'... ---------------\n");
|
|
||||||
|
|
||||||
$upgrade_sql = array();
|
|
||||||
|
|
||||||
$result = mustal_calculate_db_upgrade($compare_def, $db_def, $upgrade_sql, $mustal_replacers);
|
|
||||||
|
|
||||||
if ($result != 0) {
|
|
||||||
echo("Error: $result\n");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($result)) {
|
|
||||||
echo(count($result)." errors.\n");
|
|
||||||
if ($verbose) {
|
|
||||||
foreach($result as $error) {
|
|
||||||
echo("Code: ".$error[0]." '".$error[1]."'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo("--------------- Database upgrade for '$schema@$host'... ---------------\n");
|
|
||||||
if ($verbose) {
|
|
||||||
foreach($upgrade_sql as $statement) {
|
|
||||||
echo($statement."\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo(count($upgrade_sql)." upgrade statements\n");
|
|
||||||
echo("--------------- Database upgrade calculated for '$schema@$host' (show SQL with -v). ---------------\n");
|
|
||||||
|
|
||||||
if ($doupgrade) {
|
|
||||||
echo("--------------- Executing database upgrade for '$schema@$host' database will be written! ---------------\n");
|
|
||||||
|
|
||||||
// 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++;
|
|
||||||
echo("\rUpgrade step $counter of $number_of_statements... ");
|
|
||||||
|
|
||||||
if ($verbose) {
|
|
||||||
echo("(".substr($sql,0,100)."...) ");
|
|
||||||
}
|
|
||||||
|
|
||||||
$query_result = mysqli_query($mysqli, $sql);
|
|
||||||
if (!$query_result) {
|
|
||||||
$error = " not ok: ". mysqli_error($mysqli)."\n";
|
|
||||||
echo($error);
|
|
||||||
file_put_contents("./errors.txt",$error.$sql."\n",FILE_APPEND);
|
|
||||||
$error_counter++;
|
|
||||||
} else {
|
|
||||||
echo("ok.\r");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
echo("--------------- Executing database upgrade for '$schema@$host' executed. ---------------\n");
|
|
||||||
echo("$error_counter errors.\n");
|
|
||||||
echo("--------------- Executing database upgrade for '$schema@$host' done. ---------------\n");
|
|
||||||
|
|
||||||
echo("--------------- Checking database upgrade for '$schema@$host'... ---------------\n");
|
|
||||||
$db_def = mustal_load_tables_from_db($host, $schema, $user, $passwd, $mustal_replacers);
|
|
||||||
|
|
||||||
echo("--------------- Comparing database '$schema@$host' vs. JSON '".$compare_def['database']."@".$compare_def['host']."' ---------------\n");
|
|
||||||
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true);
|
|
||||||
echo((empty($compare_differences)?0:count($compare_differences))." differences.\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // upgrade
|
|
||||||
|
|
||||||
echo("--------------- Done. ---------------\n");
|
|
||||||
|
|
||||||
echo("\n");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
info();
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
echo("\t-i: ignore column definitions\n");
|
|
||||||
echo("\t-utf8fix: apply fix for 'utf8' != 'utf8mb3'\n");
|
|
||||||
echo("\t-upgrade: Create the needed SQL to upgrade the database to match the JSON\n");
|
|
||||||
echo("\t-do: Execute the SQL to upgrade the database to match the JSON (risky!)\n");
|
|
||||||
echo("\t-clean: (not yet implemented) Create the needed SQL to remove items from the database not in the JSON\n");
|
|
||||||
echo("\n");
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,661 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
MUSTAL Mysql Upgrade Schema Tool by Alex Ledis
|
|
||||||
Helper to compare database structures from JSON files vs. database and upgrade database
|
|
||||||
Copyright (c) 2022 Alex Ledis
|
|
||||||
Licensed under AGPL v3
|
|
||||||
|
|
||||||
Version 1.0
|
|
||||||
|
|
||||||
function mustal_load_tables_from_db(string $host, string $schema, string $user, string $passwd, $replacers) : array
|
|
||||||
Load structure from db connection to an array.
|
|
||||||
|
|
||||||
function mustal_save_tables_to_json(array $db_def, string $path, string $tables_file_name, bool $force) : int
|
|
||||||
Save structure from array to a JSON file.
|
|
||||||
|
|
||||||
function mustal_load_tables_from_json(string $path, string $tables_file_name) : array
|
|
||||||
Load structure from JSON file into array.
|
|
||||||
|
|
||||||
function mustal_compare_table_array(array $nominal, string $nominal_name, array $actual, string $actual_name, bool $check_column_definitions) : array
|
|
||||||
Compare two database structures
|
|
||||||
Returns a structured array containing information on all the differences.
|
|
||||||
|
|
||||||
function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$upgrade_sql) : int
|
|
||||||
Generate the SQL needed to upgrade the database to match the definition, based on a comparison.
|
|
||||||
|
|
||||||
Data structure in Array and JSON
|
|
||||||
{
|
|
||||||
"host": "hostname",
|
|
||||||
"database": "schemaname",
|
|
||||||
"user": "username",
|
|
||||||
"tables": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "",
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"Field": "",
|
|
||||||
"Type": "",
|
|
||||||
"Collation": "",
|
|
||||||
"Null": "",
|
|
||||||
"Key": "",
|
|
||||||
"Default": "",
|
|
||||||
"Extra": "",
|
|
||||||
"Privileges": "",
|
|
||||||
"Comment": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"keys": [
|
|
||||||
{
|
|
||||||
"Key_name": "",
|
|
||||||
"columns": [
|
|
||||||
"",
|
|
||||||
""
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// These default values will not be in quotes, converted to lowercase and be replaced by the second entry
|
|
||||||
$mustal_replacers = [
|
|
||||||
['current_timestamp','current_timestamp()'],
|
|
||||||
['on update current_timestamp','on update current_timestamp()']
|
|
||||||
];
|
|
||||||
|
|
||||||
// Load all db_def from a DB connection into a db_def array
|
|
||||||
function mustal_load_tables_from_db(string $host, string $schema, string $user, string $passwd, $replacers) : array {
|
|
||||||
|
|
||||||
// First get the contents of the database table structure
|
|
||||||
$mysqli = mysqli_connect($host, $user, $passwd, $schema);
|
|
||||||
|
|
||||||
/* Check if the connection succeeded */
|
|
||||||
if (!$mysqli) {
|
|
||||||
return(array());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get db_def and views
|
|
||||||
|
|
||||||
$sql = "SHOW FULL tables";
|
|
||||||
$query_result = mysqli_query($mysqli, $sql);
|
|
||||||
if (!$query_result) {
|
|
||||||
return(array());
|
|
||||||
}
|
|
||||||
while ($row = mysqli_fetch_assoc($query_result)) {
|
|
||||||
$table = array();
|
|
||||||
$table['name'] = $row['Tables_in_'.$schema];
|
|
||||||
$table['type'] = $row['Table_type'];
|
|
||||||
$tables[] = $table; // Add table to list of tables
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get and add columns of the table
|
|
||||||
foreach ($tables as &$table) {
|
|
||||||
$sql = "SHOW FULL COLUMNS FROM ".$table['name'];
|
|
||||||
$query_result = mysqli_query($mysqli, $sql);
|
|
||||||
|
|
||||||
if (!$query_result) {
|
|
||||||
return(array());
|
|
||||||
}
|
|
||||||
|
|
||||||
$columns = array();
|
|
||||||
while ($column = mysqli_fetch_assoc($query_result)) {
|
|
||||||
// Do some harmonization
|
|
||||||
|
|
||||||
if ($column['Default'] !== NULL) {
|
|
||||||
mustal_sql_replace_reserved_functions($column,$replacers);
|
|
||||||
$column['Default'] = mustal_mysql_put_text_type_in_quotes($column['Type'],$column['Default']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$columns[] = $column; // Add column to list of columns
|
|
||||||
}
|
|
||||||
$table['columns'] = $columns;
|
|
||||||
|
|
||||||
$sql = "SHOW KEYS FROM ".$table['name'];
|
|
||||||
$query_result = mysqli_query($mysqli, $sql);
|
|
||||||
if (!$query_result) {
|
|
||||||
return(array());
|
|
||||||
}
|
|
||||||
$keys = array();
|
|
||||||
while ($key = mysqli_fetch_assoc($query_result)) {
|
|
||||||
$keys[] = $key; // Add key to list of keys
|
|
||||||
}
|
|
||||||
// Compose comparable format for keys
|
|
||||||
$composed_keys = array();
|
|
||||||
foreach ($keys as $key) {
|
|
||||||
|
|
||||||
// Check if this key exists already
|
|
||||||
|
|
||||||
$key_pos = array_search($key['Key_name'],array_column($composed_keys,'Key_name'));
|
|
||||||
|
|
||||||
if ($key_pos == false) {
|
|
||||||
// New key
|
|
||||||
$composed_key = array();
|
|
||||||
$composed_key['Key_name'] = $key['Key_name'];
|
|
||||||
$composed_key['Index_type'] = $key['Index_type'];
|
|
||||||
$composed_key['columns'][] = $key['Column_name'];
|
|
||||||
$composed_keys[] = $composed_key;
|
|
||||||
} else {
|
|
||||||
// Given key, add column
|
|
||||||
$composed_keys[$key_pos]['columns'][] .= $key['Column_name'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($key);
|
|
||||||
$table['keys'] = $composed_keys;
|
|
||||||
unset($composed_keys);
|
|
||||||
}
|
|
||||||
unset($table);
|
|
||||||
|
|
||||||
$result = array();
|
|
||||||
$result['host'] = $host;
|
|
||||||
$result['database'] = $schema;
|
|
||||||
$result['user'] = $user;
|
|
||||||
$result['tables'] = $tables;
|
|
||||||
return($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mustal_save_tables_to_json(array $db_def, string $path, string $tables_file_name, bool $force) : int {
|
|
||||||
|
|
||||||
// Prepare db_def file
|
|
||||||
if (!is_dir($path)) {
|
|
||||||
mkdir($path);
|
|
||||||
}
|
|
||||||
if (!$force && file_exists($path."/".$tables_file_name)) {
|
|
||||||
return(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
$tables_file = fopen($path."/".$tables_file_name, "w");
|
|
||||||
if (empty($tables_file)) {
|
|
||||||
return(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite($tables_file, json_encode($db_def,JSON_PRETTY_PRINT));
|
|
||||||
|
|
||||||
fclose($tables_file);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load all db_def from JSON file
|
|
||||||
function mustal_load_tables_from_json(string $path, string $tables_file_name) : array {
|
|
||||||
|
|
||||||
$db_def = array();
|
|
||||||
|
|
||||||
$contents = file_get_contents($path."/".$tables_file_name);
|
|
||||||
|
|
||||||
if (!$contents) {
|
|
||||||
return(array());
|
|
||||||
}
|
|
||||||
|
|
||||||
$db_def = json_decode($contents, true);
|
|
||||||
|
|
||||||
if (!$db_def) {
|
|
||||||
return(array());
|
|
||||||
}
|
|
||||||
|
|
||||||
return($db_def);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare two definitions
|
|
||||||
// Report based on the first array
|
|
||||||
// Return Array
|
|
||||||
// $column_collation_aliases may contain synonyms for collations e.g. utf8mb3_general_ci vs utf8_general_ci
|
|
||||||
function mustal_compare_table_array(array $nominal, string $nominal_name, array $actual, string $actual_name, bool $check_column_definitions, array $column_collation_aliases = array()) : array {
|
|
||||||
|
|
||||||
$compare_differences = array();
|
|
||||||
|
|
||||||
if (count($nominal['tables']) != count($actual['tables'])) {
|
|
||||||
$compare_difference = array();
|
|
||||||
$compare_difference['type'] = "Table count";
|
|
||||||
$compare_difference[$nominal_name] = count($nominal['tables']);
|
|
||||||
$compare_difference[$actual_name] = count($actual['tables']);
|
|
||||||
$compare_differences[] = $compare_difference;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($nominal['tables'] as $database_table) {
|
|
||||||
|
|
||||||
$found_table = array();
|
|
||||||
foreach ($actual['tables'] as $compare_table) {
|
|
||||||
if ($database_table['name'] == $compare_table['name']) {
|
|
||||||
$found_table = $compare_table;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($compare_table);
|
|
||||||
|
|
||||||
if ($found_table) {
|
|
||||||
|
|
||||||
// Check type table vs view
|
|
||||||
|
|
||||||
if ($database_table['type'] != $found_table['type']) {
|
|
||||||
$compare_difference = array();
|
|
||||||
$compare_difference['type'] = "Table type";
|
|
||||||
$compare_difference['table'] = $database_table['name'];
|
|
||||||
$compare_difference[$nominal_name] = $database_table['type'];
|
|
||||||
$compare_difference[$actual_name] = $found_table['type'];
|
|
||||||
$compare_differences[] = $compare_difference;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only BASE TABLE supported now
|
|
||||||
if ($found_table['type'] != 'BASE TABLE') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check columns
|
|
||||||
$compare_table_columns = array_column($found_table['columns'],'Field');
|
|
||||||
foreach ($database_table['columns'] as $column) {
|
|
||||||
|
|
||||||
$column_name_to_find = $column['Field'];
|
|
||||||
$column_key = array_search($column_name_to_find,$compare_table_columns,true);
|
|
||||||
if ($column_key !== false) {
|
|
||||||
|
|
||||||
// Compare the properties of the columns
|
|
||||||
if ($check_column_definitions) {
|
|
||||||
$found_column = $found_table['columns'][$column_key];
|
|
||||||
foreach ($column as $key => $value) {
|
|
||||||
|
|
||||||
// Apply aliases
|
|
||||||
if (!empty($column_collation_aliases)) {
|
|
||||||
foreach($column_collation_aliases as $column_collation_alias) {
|
|
||||||
if ($value == $column_collation_alias[0]) {
|
|
||||||
$value = $column_collation_alias[1];
|
|
||||||
}
|
|
||||||
if ($found_column[$key] == $column_collation_alias[0]) {
|
|
||||||
$found_column[$key] = $column_collation_alias[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($found_column[$key] != $value) {
|
|
||||||
if ($key != 'Key') { // Keys will be handled separately
|
|
||||||
$compare_difference = array();
|
|
||||||
$compare_difference['type'] = "Column definition";
|
|
||||||
$compare_difference['table'] = $database_table['name'];
|
|
||||||
$compare_difference['column'] = $column['Field'];
|
|
||||||
$compare_difference['property'] = $key;
|
|
||||||
$compare_difference[$nominal_name] = $value;
|
|
||||||
$compare_difference[$actual_name] = $found_column[$key];
|
|
||||||
$compare_differences[] = $compare_difference;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($value);
|
|
||||||
} // $check_column_definitions
|
|
||||||
} else {
|
|
||||||
$compare_difference = array();
|
|
||||||
$compare_difference['type'] = "Column existence";
|
|
||||||
$compare_difference['table'] = $database_table['name'];
|
|
||||||
$compare_difference[$nominal_name] = $column['Field'];
|
|
||||||
$compare_differences[] = $compare_difference;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($column);
|
|
||||||
|
|
||||||
|
|
||||||
// Check keys
|
|
||||||
$compare_table_sql_indexs = array_column($found_table['keys'],'Key_name');
|
|
||||||
foreach ($database_table['keys'] as $sql_index) {
|
|
||||||
|
|
||||||
$sql_index_name_to_find = $sql_index['Key_name'];
|
|
||||||
$sql_index_key = array_search($sql_index_name_to_find,$compare_table_sql_indexs,true);
|
|
||||||
if ($sql_index_key !== false) {
|
|
||||||
|
|
||||||
// Compare the properties of the sql_indexs
|
|
||||||
if ($check_column_definitions) {
|
|
||||||
$found_sql_index = $found_table['keys'][$sql_index_key];
|
|
||||||
foreach ($sql_index as $key => $value) {
|
|
||||||
if ($found_sql_index[$key] != $value) {
|
|
||||||
|
|
||||||
// if ($key != 'permissions') {
|
|
||||||
$compare_difference = array();
|
|
||||||
$compare_difference['type'] = "Key definition";
|
|
||||||
$compare_difference['table'] = $database_table['name'];
|
|
||||||
$compare_difference['key'] = $sql_index['Key_name'];
|
|
||||||
$compare_difference['property'] = $key;
|
|
||||||
$compare_difference[$nominal_name] = implode(',',$value);
|
|
||||||
$compare_difference[$actual_name] = implode(',',$found_sql_index[$key]);
|
|
||||||
$compare_differences[] = $compare_difference;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($value);
|
|
||||||
} // $check_sql_index_definitions
|
|
||||||
} else {
|
|
||||||
$compare_difference = array();
|
|
||||||
$compare_difference['type'] = "Key existence";
|
|
||||||
$compare_difference['table'] = $database_table['name'];
|
|
||||||
$compare_difference[$nominal_name] = $sql_index['Key_name'];
|
|
||||||
$compare_differences[] = $compare_difference;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql_index);
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$compare_difference = array();
|
|
||||||
$compare_difference['type'] = "Table existence";
|
|
||||||
$compare_difference[$nominal_name] = $database_table['name'];
|
|
||||||
$compare_differences[] = $compare_difference;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($database_table);
|
|
||||||
|
|
||||||
return($compare_differences);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Generate SQL to create or modify column
|
|
||||||
function mustal_column_sql_definition(string $table_name, array $column, array $reserved_words_without_quote) : string {
|
|
||||||
|
|
||||||
foreach($column as $key => &$value) {
|
|
||||||
$value = (string) $value;
|
|
||||||
$value = mustal_column_sql_create_property_definition($key,$value,$reserved_words_without_quote);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default handling here
|
|
||||||
if ($column['Default'] == " DEFAULT ''") {
|
|
||||||
$column['Default'] = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql =
|
|
||||||
$column['Type'].
|
|
||||||
$column['Null'].
|
|
||||||
$column['Default'].
|
|
||||||
$column['Extra'].
|
|
||||||
$column['Collation'];
|
|
||||||
|
|
||||||
return($sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate SQL to modify a single column property
|
|
||||||
function mustal_column_sql_create_property_definition(string $property, string $property_value, array $reserved_words_without_quote) : string {
|
|
||||||
|
|
||||||
switch ($property) {
|
|
||||||
case 'Type':
|
|
||||||
break;
|
|
||||||
case 'Null':
|
|
||||||
if ($property_value == "NO") {
|
|
||||||
$property_value = " NOT NULL"; // Idiotic...
|
|
||||||
}
|
|
||||||
if ($property_value == "YES") {
|
|
||||||
$property_value = " NULL"; // Also Idiotic...
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Default':
|
|
||||||
// Check for MYSQL function mustal_call as default
|
|
||||||
|
|
||||||
if (in_array(strtolower($property_value),$reserved_words_without_quote)) {
|
|
||||||
$quote = "";
|
|
||||||
} else {
|
|
||||||
// Remove quotes if there are
|
|
||||||
$property_value = trim($property_value,"'");
|
|
||||||
$quote = "'";
|
|
||||||
}
|
|
||||||
$property_value = " DEFAULT $quote".$property_value."$quote";
|
|
||||||
break;
|
|
||||||
case 'Extra':
|
|
||||||
if ($property_value != '') {
|
|
||||||
$property_value = " ".$property_value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Collation':
|
|
||||||
if ($property_value != '') {
|
|
||||||
$property_value = " COLLATE ".$property_value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$property_value = "";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return($property_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replaces different variants of the same function mustal_to allow comparison
|
|
||||||
function mustal_sql_replace_reserved_functions(array &$column, array $replacers) {
|
|
||||||
|
|
||||||
$result = strtolower($column['Default']);
|
|
||||||
foreach ($replacers as $replace) {
|
|
||||||
if ($result == $replace[0]) {
|
|
||||||
$result = $replace[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$column['Default'] = $result;
|
|
||||||
|
|
||||||
$result = strtolower($column['Extra']);
|
|
||||||
foreach ($replacers as $replace) {
|
|
||||||
if ($result == $replace[0]) {
|
|
||||||
$result = $replace[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$column['Extra'] = $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is it a text type? -> Use quotes then
|
|
||||||
function mustal_mysql_put_text_type_in_quotes(string $checktype, string $value) : string {
|
|
||||||
$types = array('char','varchar','tinytext','text','mediumtext','longtext');
|
|
||||||
|
|
||||||
foreach($types as $type) {
|
|
||||||
if (stripos($checktype, $type) !== false) {
|
|
||||||
return("'".$value."'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mustal_implode_with_quote(string $quote, string $delimiter, array $array_to_implode) : string {
|
|
||||||
return($quote.implode($quote.$delimiter.$quote, $array_to_implode).$quote);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate the sql neccessary to update the database
|
|
||||||
// returns array(code,text)
|
|
||||||
// Error codes:
|
|
||||||
// 0 ok
|
|
||||||
// 1 Upgrade type of table not supported
|
|
||||||
// 2 Error on table upgrade
|
|
||||||
// 3 Error on column existence upgrade
|
|
||||||
// 4 Error on column existence upgrade
|
|
||||||
// 5 Error on column definition upgrade
|
|
||||||
// 6 Error on column definition upgrade
|
|
||||||
// 7 Error on key existence upgrade
|
|
||||||
// 8 Error on key existence upgrade
|
|
||||||
// 9 Error on key definition upgrade
|
|
||||||
// 10 Error on key definition upgrade
|
|
||||||
// 11 Table type upgrade not supported
|
|
||||||
// 12 Upgrade type not supported
|
|
||||||
|
|
||||||
function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$upgrade_sql, array $replacers) : array {
|
|
||||||
|
|
||||||
$result = array();
|
|
||||||
$upgrade_sql = array();
|
|
||||||
|
|
||||||
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true);
|
|
||||||
if (count($compare_differences) > 0) {
|
|
||||||
$upgrade_sql[] = ("SET SQL_MODE='ALLOW_INVALID_DATES';");
|
|
||||||
$upgrade_sql[] = ("SET SESSION innodb_strict_mode=OFF;");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($compare_differences as $compare_difference) {
|
|
||||||
switch ($compare_difference['type']) {
|
|
||||||
case 'Table existence':
|
|
||||||
|
|
||||||
// Get table definition from JSON
|
|
||||||
|
|
||||||
$table_name = $compare_difference['in JSON'];
|
|
||||||
|
|
||||||
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
|
|
||||||
|
|
||||||
if ($table_key !== false) {
|
|
||||||
$table = $compare_def['tables'][$table_key];
|
|
||||||
|
|
||||||
switch ($table['type']) {
|
|
||||||
case 'BASE TABLE':
|
|
||||||
|
|
||||||
// Create table in DB
|
|
||||||
$sql = "";
|
|
||||||
$sql = "CREATE TABLE `".$table['name']."` (";
|
|
||||||
$comma = "";
|
|
||||||
|
|
||||||
foreach ($table['columns'] as $column) {
|
|
||||||
$sql .= $comma."`".$column['Field']."` ".mustal_column_sql_definition($table_name, $column,array_column($replacers,1));
|
|
||||||
$comma = ", ";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add keys
|
|
||||||
$comma = ", ";
|
|
||||||
foreach ($table['keys'] as $key) {
|
|
||||||
if ($key['Key_name'] == 'PRIMARY') {
|
|
||||||
$keystring = "PRIMARY KEY ";
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if(array_key_exists('Index_type', $key)) {
|
|
||||||
$index_type = $key['Index_type'];
|
|
||||||
} else {
|
|
||||||
$index_type = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
$keystring = $index_type." KEY `".$key['Key_name']."` ";
|
|
||||||
}
|
|
||||||
$sql .= $comma.$keystring."(`".implode("`,`",$key['columns'])."`) ";
|
|
||||||
}
|
|
||||||
$sql .= ")";
|
|
||||||
$upgrade_sql[] = $sql;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$result[] = array(1,"Upgrade type '".$table['type']."' on table '".$table['name']."' not supported.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result[] = array(2,"Error table_key while creating upgrade for table existence `$table_name`.");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'Column existence':
|
|
||||||
$table_name = $compare_difference['table'];
|
|
||||||
$column_name = $compare_difference['in JSON'];
|
|
||||||
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
|
|
||||||
if ($table_key !== false) {
|
|
||||||
$table = $compare_def['tables'][$table_key];
|
|
||||||
$columns = $table['columns'];
|
|
||||||
$column_key = array_search($column_name,array_column($columns,'Field'));
|
|
||||||
if ($column_key !== false) {
|
|
||||||
$column = $table['columns'][$column_key];
|
|
||||||
$sql = "ALTER TABLE `$table_name` ADD COLUMN `".$column_name."` ";
|
|
||||||
$sql .= mustal_column_sql_definition($table_name, $column, array_column($replacers,1));
|
|
||||||
$sql .= ";";
|
|
||||||
$upgrade_sql[] = $sql;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result[] = array(3,"Error column_key while creating column '$column_name' in table '".$table['name']."'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result[] = array(4,"Error table_key while creating upgrade for column existence '$column_name' in table '$table_name'.");
|
|
||||||
}
|
|
||||||
// Add Column in DB
|
|
||||||
break;
|
|
||||||
case 'Column definition':
|
|
||||||
$table_name = $compare_difference['table'];
|
|
||||||
$column_name = $compare_difference['column'];
|
|
||||||
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
|
|
||||||
if ($table_key !== false) {
|
|
||||||
$table = $compare_def['tables'][$table_key];
|
|
||||||
$columns = $table['columns'];
|
|
||||||
|
|
||||||
$column_names = array_column($columns,'Field');
|
|
||||||
$column_key = array_search($column_name,$column_names);
|
|
||||||
|
|
||||||
if ($column_key !== false) {
|
|
||||||
$column = $table['columns'][$column_key];
|
|
||||||
|
|
||||||
$sql = "ALTER TABLE `$table_name` MODIFY COLUMN `".$column_name."` ";
|
|
||||||
$sql .= mustal_column_sql_definition($table_name, $column,array_column($replacers,1));
|
|
||||||
$sql .= ";";
|
|
||||||
$upgrade_sql[] = $sql;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result[] = array(5,"Error column_key while modifying column '$column_name' in table '".$table['name']."'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result[] = array(6,"Error table_key while modifying column '$column_name' in table '$table_name'.");
|
|
||||||
return(6);
|
|
||||||
}
|
|
||||||
// Modify Column in DB
|
|
||||||
break;
|
|
||||||
case 'Key existence':
|
|
||||||
|
|
||||||
$table_name = $compare_difference['table'];
|
|
||||||
$key_name = $compare_difference['in JSON'];
|
|
||||||
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
|
|
||||||
if ($table_key !== false) {
|
|
||||||
$table = $compare_def['tables'][$table_key];
|
|
||||||
$keys = $table['keys'];
|
|
||||||
|
|
||||||
$key_names = array_column($keys,'Key_name');
|
|
||||||
$key_key = array_search($key_name,$key_names);
|
|
||||||
|
|
||||||
if ($key_key !== false) {
|
|
||||||
$key = $table['keys'][$key_key];
|
|
||||||
|
|
||||||
$sql = "ALTER TABLE `$table_name` ADD KEY `".$key_name."` ";
|
|
||||||
$sql .= "(`".implode("`,`",$key['columns'])."`)";
|
|
||||||
$sql .= ";";
|
|
||||||
$upgrade_sql[] = $sql;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result[] = array(7,"Error key_key while adding key '$key_name' in table '".$table['name']."'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result[] = array(8,"Error table_key while adding key '$key_name' in table '$table_name'.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Key definition":
|
|
||||||
$table_name = $compare_difference['table'];
|
|
||||||
$key_name = $compare_difference['key'];
|
|
||||||
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
|
|
||||||
if ($table_key !== false) {
|
|
||||||
$table = $compare_def['tables'][$table_key];
|
|
||||||
$keys = $table['keys'];
|
|
||||||
|
|
||||||
$key_names = array_column($keys,'Key_name');
|
|
||||||
$key_key = array_search($key_name,$key_names);
|
|
||||||
|
|
||||||
if ($key_key !== false) {
|
|
||||||
$key = $table['keys'][$key_key];
|
|
||||||
|
|
||||||
$sql = "ALTER TABLE `$table_name` DROP KEY `".$key_name."`;";
|
|
||||||
$upgrade_sql[] = $sql;
|
|
||||||
|
|
||||||
$sql = "ALTER TABLE `$table_name` ADD KEY `".$key_name."` ";
|
|
||||||
$sql .= "(`".implode("`,`",$key['columns'])."`)";
|
|
||||||
$sql .= ";";
|
|
||||||
$upgrade_sql[] = $sql;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result[] = array(9, "Error key_key while changing key '$key_name' in table '".$table['name']."'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result[] = array(10,"Error table_key while changing key '$key_name' in table '$table_name'.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Table count':
|
|
||||||
// Nothing to do
|
|
||||||
break;
|
|
||||||
case 'Table type':
|
|
||||||
$result[] = array(11,"Upgrade type '".$compare_difference['type']."' on table '".$compare_difference['table']."' not supported.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$result[] = array(12,"Upgrade type '".$compare_difference['type']."' not supported.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$upgrade_sql = array_unique($upgrade_sql);
|
|
||||||
|
|
||||||
return($result);
|
|
||||||
}
|
|
@ -28444,6 +28444,55 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "bestellvorschlag",
|
||||||
|
"type": "BASE TABLE",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"Field": "user",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Collation": null,
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "PRI",
|
||||||
|
"Default": null,
|
||||||
|
"Extra": "",
|
||||||
|
"Privileges": "select,insert,update,references",
|
||||||
|
"Comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "artikel",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Collation": null,
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "PRI",
|
||||||
|
"Default": null,
|
||||||
|
"Extra": "",
|
||||||
|
"Privileges": "select,insert,update,references",
|
||||||
|
"Comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "menge",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Collation": null,
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": null,
|
||||||
|
"Extra": "",
|
||||||
|
"Privileges": "select,insert,update,references",
|
||||||
|
"Comment": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"keys": [
|
||||||
|
{
|
||||||
|
"Key_name": "PRIMARY",
|
||||||
|
"Index_type": "BTREE",
|
||||||
|
"columns": [
|
||||||
|
"artikel",
|
||||||
|
"user"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "bestellvorschlag_app",
|
"name": "bestellvorschlag_app",
|
||||||
"type": "BASE TABLE",
|
"type": "BASE TABLE",
|
||||||
|
3
vendor/mustal/mustal_mysql_upgrade_tool.php
vendored
3
vendor/mustal/mustal_mysql_upgrade_tool.php
vendored
@ -127,10 +127,9 @@ function mustal_load_tables_from_db(string $host, string $schema, string $user,
|
|||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
|
|
||||||
// Check if this key exists already
|
// Check if this key exists already
|
||||||
|
|
||||||
$key_pos = array_search($key['Key_name'],array_column($composed_keys,'Key_name'));
|
$key_pos = array_search($key['Key_name'],array_column($composed_keys,'Key_name'));
|
||||||
|
|
||||||
if ($key_pos == false) {
|
if ($key_pos === false) {
|
||||||
// New key
|
// New key
|
||||||
$composed_key = array();
|
$composed_key = array();
|
||||||
$composed_key['Key_name'] = $key['Key_name'];
|
$composed_key['Key_name'] = $key['Key_name'];
|
||||||
|
@ -15,9 +15,9 @@ class Bestellvorschlag {
|
|||||||
|
|
||||||
$this->app->ActionHandlerInit($this);
|
$this->app->ActionHandlerInit($this);
|
||||||
$this->app->ActionHandler("list", "bestellvorschlag_list");
|
$this->app->ActionHandler("list", "bestellvorschlag_list");
|
||||||
$this->app->ActionHandler("create", "bestellvorschlag_edit"); // This automatically adds a "New" button
|
// $this->app->ActionHandler("create", "bestellvorschlag_edit"); // This automatically adds a "New" button
|
||||||
$this->app->ActionHandler("edit", "bestellvorschlag_edit");
|
// $this->app->ActionHandler("edit", "bestellvorschlag_edit");
|
||||||
$this->app->ActionHandler("delete", "bestellvorschlag_delete");
|
// $this->app->ActionHandler("delete", "bestellvorschlag_delete");
|
||||||
$this->app->DefaultActionHandler("list");
|
$this->app->DefaultActionHandler("list");
|
||||||
$this->app->ActionHandlerListen($app);
|
$this->app->ActionHandlerListen($app);
|
||||||
}
|
}
|
||||||
@ -30,20 +30,24 @@ class Bestellvorschlag {
|
|||||||
switch ($name) {
|
switch ($name) {
|
||||||
case "bestellvorschlag_list":
|
case "bestellvorschlag_list":
|
||||||
$allowed['bestellvorschlag_list'] = array('list');
|
$allowed['bestellvorschlag_list'] = array('list');
|
||||||
$heading = array('', '', 'Nr.', 'Artikel','Lieferant','Mindestlager','Lager','Bestellt','Vorschlag','Eingabe','');
|
|
||||||
$width = array('1%','1%','1%', '20%', '10%', '1%', '1%', '1%', '1%', '5%', '1%');
|
$monate_absatz = $app->Secure->GetPOST('monate_absatz');
|
||||||
|
$monate_voraus = $app->Secure->GetPOST('monate_voraus');
|
||||||
|
|
||||||
|
$heading = array('', '', 'Nr.', 'Artikel','Lieferant','Mindestlager','Lager','Bestellt','Auftrag','Vorschlag','Eingabe','');
|
||||||
|
$width = array('1%','1%','1%', '20%', '10%', '1%', '1%', '1%', '1%', '1%', '1%', '1%');
|
||||||
|
|
||||||
// columns that are aligned right (numbers etc)
|
// columns that are aligned right (numbers etc)
|
||||||
// $alignright = array(4,5,6,7,8);
|
// $alignright = array(4,5,6,7,8);
|
||||||
|
|
||||||
$findcols = array('a.id','a.id','a.nummer','a.name_de','l.name','mindestlager','lager','bestellt','vorschlag');
|
$findcols = array('a.id','a.id','a.nummer','a.name_de','l.name','mindestlager','lager','bestellt','auftrag','vorschlag');
|
||||||
$searchsql = array('a.name_de');
|
$searchsql = array('a.name_de');
|
||||||
|
|
||||||
$defaultorder = 1;
|
$defaultorder = 1;
|
||||||
$defaultorderdesc = 0;
|
$defaultorderdesc = 0;
|
||||||
$numbercols = array(6,7,8,9);
|
$numbercols = array(6,7,8,9,10);
|
||||||
// $sumcol = array(6);
|
// $sumcol = array(6);
|
||||||
$alignright = array(6,7,8,9);
|
$alignright = array(6,7,8,9,10);
|
||||||
|
|
||||||
$dropnbox = "'<img src=./themes/new/images/details_open.png class=details>' AS `open`, CONCAT('<input type=\"checkbox\" name=\"auswahl[]\" value=\"',a.id,'\" />') AS `auswahl`";
|
$dropnbox = "'<img src=./themes/new/images/details_open.png class=details>' AS `open`, CONCAT('<input type=\"checkbox\" name=\"auswahl[]\" value=\"',a.id,'\" />') AS `auswahl`";
|
||||||
|
|
||||||
@ -54,39 +58,142 @@ class Bestellvorschlag {
|
|||||||
' name=\"menge_',
|
' name=\"menge_',
|
||||||
a.id,
|
a.id,
|
||||||
'\" value=\"',
|
'\" value=\"',
|
||||||
(SELECT mengen.vorschlag),
|
ROUND((SELECT mengen.vorschlag)),
|
||||||
'\" style=\"text-align:right\">',
|
'\" style=\"text-align:right; width:100%\">',
|
||||||
'</input>'
|
'</input>'
|
||||||
)";
|
)";
|
||||||
|
|
||||||
$sql_artikel_mengen = "
|
$user = $app->User->GetID();
|
||||||
SELECT
|
|
||||||
a.id,
|
$sql_artikel_mengen = "
|
||||||
(
|
SELECT
|
||||||
SELECT
|
a.id,
|
||||||
COALESCE(SUM(menge),0)
|
(
|
||||||
FROM
|
SELECT
|
||||||
lager_platz_inhalt lpi
|
COALESCE(SUM(menge),
|
||||||
INNER JOIN lager_platz lp ON
|
0)
|
||||||
lp.id = lpi.lager_platz
|
FROM
|
||||||
WHERE
|
lager_platz_inhalt lpi
|
||||||
lpi.artikel = a.id AND lp.sperrlager = 0
|
INNER JOIN lager_platz lp ON
|
||||||
) AS lager_ber,
|
lp.id = lpi.lager_platz
|
||||||
(
|
WHERE
|
||||||
SELECT
|
lpi.artikel = a.id AND lp.sperrlager = 0
|
||||||
COALESCE(SUM(menge-geliefert))
|
) AS lager,
|
||||||
FROM
|
(
|
||||||
bestellung_position bp INNER JOIN bestellung b ON bp.bestellung = b.id
|
SELECT
|
||||||
WHERE bp.artikel = a.id AND b.status IN ('versendet','freigegeben')
|
COALESCE(SUM(menge - geliefert))
|
||||||
) AS bestellt_ber,
|
FROM
|
||||||
a.mindestlager - (SELECT lager_ber) - COALESCE((SELECT bestellt_ber),0) as vorschlag_ber,
|
bestellung_position bp
|
||||||
FORMAT (a.mindestlager,0,'de_DE') as mindestlager,
|
INNER JOIN bestellung b ON
|
||||||
FORMAT((SELECT lager_ber),0,'de_DE') as lager,
|
bp.bestellung = b.id
|
||||||
FORMAT(COALESCE((SELECT bestellt_ber),0),0,'de_DE') as bestellt,
|
WHERE
|
||||||
if ((SELECT vorschlag_ber) > 0,FORMAT((SELECT vorschlag_ber),'0','de_DE'),0) as vorschlag
|
bp.artikel = a.id AND b.status IN(
|
||||||
FROM
|
'versendet',
|
||||||
artikel a
|
'freigegeben',
|
||||||
";
|
'angelegt'
|
||||||
|
)
|
||||||
|
) AS bestellt,
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
COALESCE(SUM(menge - geliefert))
|
||||||
|
FROM
|
||||||
|
auftrag_position aufp
|
||||||
|
INNER JOIN auftrag auf ON
|
||||||
|
aufp.auftrag = auf.id
|
||||||
|
WHERE
|
||||||
|
aufp.artikel = a.id AND auf.status IN(
|
||||||
|
'versendet',
|
||||||
|
'freigegeben',
|
||||||
|
'angelegt'
|
||||||
|
)
|
||||||
|
) AS auftrag,
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
menge
|
||||||
|
FROM
|
||||||
|
bestellvorschlag bv
|
||||||
|
WHERE
|
||||||
|
bv.artikel = a.id AND bv.user = '$user'
|
||||||
|
) AS vorschlag_save,
|
||||||
|
a.mindestlager -(
|
||||||
|
SELECT
|
||||||
|
lager
|
||||||
|
) - COALESCE((
|
||||||
|
SELECT
|
||||||
|
bestellt
|
||||||
|
),
|
||||||
|
0)
|
||||||
|
+ COALESCE((
|
||||||
|
SELECT
|
||||||
|
auftrag
|
||||||
|
),
|
||||||
|
0) AS vorschlag_ber_raw,
|
||||||
|
IF(
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
vorschlag_ber_raw
|
||||||
|
) > 0,
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
vorschlag_ber_raw
|
||||||
|
),
|
||||||
|
0
|
||||||
|
) AS vorschlag_ber,
|
||||||
|
COALESCE(
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
vorschlag_save
|
||||||
|
),
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
vorschlag_ber
|
||||||
|
)
|
||||||
|
) AS vorschlag,
|
||||||
|
FORMAT(a.mindestlager, 0, 'de_DE') AS mindestlager_form,
|
||||||
|
FORMAT((
|
||||||
|
SELECT
|
||||||
|
lager
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
'de_DE') AS lager_form,
|
||||||
|
FORMAT(
|
||||||
|
COALESCE((
|
||||||
|
SELECT
|
||||||
|
bestellt
|
||||||
|
),
|
||||||
|
0),
|
||||||
|
0,
|
||||||
|
'de_DE'
|
||||||
|
) AS bestellt_form,
|
||||||
|
FORMAT(
|
||||||
|
COALESCE((
|
||||||
|
SELECT
|
||||||
|
auftrag
|
||||||
|
),
|
||||||
|
0),
|
||||||
|
0,
|
||||||
|
'de_DE'
|
||||||
|
) AS auftrag_form,
|
||||||
|
FORMAT(
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
vorschlag_ber
|
||||||
|
),
|
||||||
|
'0',
|
||||||
|
'de_DE'
|
||||||
|
) AS vorschlag_ber_form
|
||||||
|
,
|
||||||
|
FORMAT(
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
vorschlag
|
||||||
|
),
|
||||||
|
'0',
|
||||||
|
'de_DE'
|
||||||
|
) AS vorschlag_form
|
||||||
|
FROM
|
||||||
|
artikel a
|
||||||
|
";
|
||||||
|
|
||||||
$sql = "SELECT SQL_CALC_FOUND_ROWS
|
$sql = "SELECT SQL_CALC_FOUND_ROWS
|
||||||
a.id,
|
a.id,
|
||||||
@ -94,11 +201,12 @@ class Bestellvorschlag {
|
|||||||
a.nummer,
|
a.nummer,
|
||||||
a.name_de,
|
a.name_de,
|
||||||
l.name,
|
l.name,
|
||||||
mengen.mindestlager,
|
mengen.mindestlager_form,
|
||||||
mengen.lager,
|
mengen.lager_form,
|
||||||
mengen.bestellt,
|
mengen.bestellt_form,
|
||||||
mengen.vorschlag,"
|
mengen.auftrag_form,
|
||||||
.$input_for_menge
|
mengen.vorschlag_ber_form,"
|
||||||
|
.$input_for_menge
|
||||||
."FROM
|
."FROM
|
||||||
artikel a
|
artikel a
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
@ -125,6 +233,31 @@ class Bestellvorschlag {
|
|||||||
|
|
||||||
function bestellvorschlag_list() {
|
function bestellvorschlag_list() {
|
||||||
|
|
||||||
|
|
||||||
|
$submit = $this->app->Secure->GetPOST('submit');
|
||||||
|
$user = $this->app->User->GetID();
|
||||||
|
|
||||||
|
switch ($submit) {
|
||||||
|
case 'loeschen':
|
||||||
|
$sql = "DELETE FROM bestellvorschlag where user = $user";
|
||||||
|
$this->app->DB->Delete($sql);
|
||||||
|
break;
|
||||||
|
case 'speichern':
|
||||||
|
|
||||||
|
$menge_input = $this->app->Secure->GetPOSTArray();
|
||||||
|
$mengen = array();
|
||||||
|
foreach ($menge_input as $key => $menge) {
|
||||||
|
if ((strpos($key,'menge_') === 0) && ($menge !== '')) {
|
||||||
|
$artikel = substr($key,'6');
|
||||||
|
if ($menge > 0) {
|
||||||
|
$sql = "INSERT INTO bestellvorschlag (artikel, user, menge) VALUES($artikel,$user,$menge) ON DUPLICATE KEY UPDATE menge = $menge";
|
||||||
|
$this->app->DB->Insert($sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$this->app->erp->MenuEintrag("index.php?module=bestellvorschlag&action=list", "Übersicht");
|
$this->app->erp->MenuEintrag("index.php?module=bestellvorschlag&action=list", "Übersicht");
|
||||||
$this->app->erp->MenuEintrag("index.php?module=bestellvorschlag&action=create", "Neu anlegen");
|
$this->app->erp->MenuEintrag("index.php?module=bestellvorschlag&action=create", "Neu anlegen");
|
||||||
|
|
||||||
|
@ -1,17 +1,70 @@
|
|||||||
<div id="tabs-1">
|
<div id="tabs-1">
|
||||||
[MESSAGE]
|
[MESSAGE]
|
||||||
<form>
|
<form action="" method="post">
|
||||||
[TAB1]
|
<div class="row">
|
||||||
<fieldset>
|
<div class="row-height">
|
||||||
<table>
|
<div class="col-xs-14 col-md-4 col-md-height">
|
||||||
<legend>Stapelverarbeitung</legend>
|
<div class="inside inside-full-height">
|
||||||
<tr>
|
<fieldset>
|
||||||
<td><input type="checkbox" value="1" id="autoalle" /> alle markieren </td>
|
<!---
|
||||||
<td><input type="submit" class="btnBlue" name="ausfuehren" value="{|Bestellung erzeugen|}"/></td>
|
<table width="100%" border="0" class="mkTableFormular">
|
||||||
</tr>
|
<legend>{|Einstellungen|}</legend>
|
||||||
</table>
|
|
||||||
</fieldset>
|
<td>{|Absatz der letzten Monate|}:</td>
|
||||||
</form>
|
<td><input type="number" min="0" name="monate_absatz" id="monate_absatz" value="[MONATE_ABSATZ]" size="20""></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{|Vorausplanen Monate|}:</td>
|
||||||
|
<td><input type="number" min="0" name="monate_voraus" id="monate_voraus" value="[MONATE_VORAUS]" size="20""></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
--!>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-14 col-md-8 col-md-height">
|
||||||
|
<div class="inside inside-full-height">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-14 col-md-2 col-md-height">
|
||||||
|
<div class="inside inside-full-height">
|
||||||
|
<fieldset>
|
||||||
|
<table>
|
||||||
|
<legend>Aktionen</legend>
|
||||||
|
<tr>
|
||||||
|
<td><button name="submit" class="ui-button-icon" style="width:100%;" value="loeschen">{|Zurücksetzen|}</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><button name="submit" class="ui-button-icon" style="width:100%;" value="speichern">{|Speichern|}</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><button name"submit" class="ui-button-icon" style="width:100%;" value="bestellungen_erzeugen">{|Bestellungen erzeugen|}</button></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row-height">
|
||||||
|
<div class="col-xs-14 col-md-6 col-md-height">
|
||||||
|
<div class="inside inside-full-height">
|
||||||
|
[TAB1]
|
||||||
|
<fieldset>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" value="1" id="autoalle" /> alle markieren
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
[TAB1NEXT]
|
[TAB1NEXT]
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -24,3 +77,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user