RapidMod

Compare 2 Mysql Tables and Generate Create/Alter Statements

Jan 25th, 2020 (edited)
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.94 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Database Schema Comparison Tool
  4.  *
  5.  * This script is designed to compare two database tables and generate the required MySQL CREATE or ALTER scripts
  6.  * to synchronize them. It's intended for developers and database administrators who need to keep database environments
  7.  * aligned, such as development, staging, and production. The script automates the generation of SQL scripts necessary
  8.  * for updating table structures, including adding missing tables, columns, and adjusting column definitions to match
  9.  * between two specified databases.
  10.  *
  11.  * Features:
  12.  * - Generates SQL scripts for synchronizing database schemas.
  13.  * - Supports CREATE and ALTER TABLE commands based on comparison results.
  14.  * - Automates the identification of discrepancies between two database tables.
  15.  *
  16.  * Usage:
  17.  * Modify the `$connections` array with the database connection details and specify the databases to compare.
  18.  * Execute the script in a PHP-supported command line or web server environment to get the SQL commands for synchronization.
  19.  *
  20.  * Note:
  21.  * This script stops execution immediately to prevent unauthorized access. Remove the `header` and `die` function calls
  22.  * to enable its functionality in a secure environment.
  23.  *
  24.  * Author: RapidMod.io
  25.  * Website: https://rapidmod.io/
  26.  *
  27.  * Please ensure proper security measures are in place when using this script to prevent unauthorized database access.
  28.  */
  29. header("File not found",1,404); die(404);
  30. //ini_set('display_errors', 1);
  31. //ini_set('display_startup_errors', 1);
  32. //error_reporting(E_ALL);
  33.  
  34. function executeQ($connections) {
  35.  
  36.     if(!empty($connections)){
  37.         foreach ($connections as $conn){
  38.  
  39.         }
  40.     }
  41.  
  42.     $conn = array(
  43.         "name" => "",
  44.         "type" => "",
  45.         "user" => "",
  46.         "password" => '',
  47.         "host" => "",
  48.         "port"=>""
  49.     );
  50.    
  51.     $data = [];
  52.     $dbNames = ["table1","table2"];
  53.     /** @var PDO $pdo */
  54.     $pdo = new PDO(
  55.         "mysql:host={$conn['host']}; dbname={$conn['name']}",
  56.         $conn['user'],
  57.         $conn['password']
  58.     );
  59.  
  60.     foreach ($dbNames as $dbName){
  61.         $data["additional_tables"][$dbName] = [];
  62.         $data["additional_columns"][$dbName] = [];
  63.         $data["changes"][$dbName] = [];
  64.         $data["schema"][$dbName] = [];
  65.         $data[$dbName] = [ "tables" => [], "columns" => [] ];
  66.         $params = [];
  67.         $schema = fetchQ($pdo,"SHOW TABLES in {$dbName}",$params);
  68.         if(!empty($schema)){
  69.             foreach ($schema as $i => $x){
  70.                 $table = trim($x["Tables_in_{$dbName}"]);
  71.                 $data[$dbName]["tables"][$table] = $table;
  72.                 $data[$dbName]["columns"][$table] = [];
  73.                 $schemaA = fetchQ($pdo,"DESCRIBE `{$dbName}`.`{$table}` ",$params);
  74.                 if(!empty($schemaA)){
  75.                     $formattedSchema = array();
  76.                     foreach ($schemaA as $colInfo){
  77.                         $data[$dbName]["columns"][$table][$colInfo["Field"]] = $colInfo["Type"];
  78.                         $formattedSchema[$colInfo["Field"]] = $colInfo;
  79.                     }
  80.                     $data["schema"][$dbName][$table] = $formattedSchema;
  81.                 }
  82.             }
  83.         }
  84.     }
  85.    // die("<pre>".print_r($data,1));
  86.     foreach ($data as $dbName => $info){
  87.         if($dbName === $dbNames[0]){$check = $dbNames[1];}
  88.         else{$check = $dbNames[0];}
  89.         $tables = $data[$dbName]["tables"];
  90.         if(!$tables){
  91.             continue;
  92.             die(":nothing #1125");
  93.         }
  94.         $dbChanges[$dbName] = [];
  95.         foreach ($tables as $table){
  96.             if(!isset($data[$check]["tables"][trim($table)])){
  97.                 $data["additional_tables"][$dbName][] = trim($table);
  98.                 $x = fetchQ($pdo,"show create table {$dbName}.{$table}",[]);
  99.                 if(!empty($x[0]["Create Table"])){
  100.                     $data["changes"][$dbName][]  = $x[0]["Create Table"].";";
  101.                 }else{
  102.                     die(":nothing #1124");
  103.                 }
  104.             }
  105.             if($data[$dbName]["columns"][$table]){
  106.                 foreach ($data[$dbName]["columns"][$table] as $col => $type){
  107.                     if(isset($data[$check]["columns"][$table])){
  108.                         if(!isset($data[$check]["columns"][$table][$col])){
  109.                             $data["additional_columns"][$dbName][$table][] = $col;
  110.                             $data["changes"][$dbName][] = getAlterTableStatement($table,$col,$data["schema"][$dbName][$table][$col]);
  111.                         }
  112.                     }
  113.                 }
  114.             }
  115.         }
  116.     }
  117.     $changes = $data["changes"]["table1"];
  118.     if(!empty($changes)){
  119.         $changes = implode(PHP_EOL.PHP_EOL,$changes);
  120.         echo str_replace(PHP_EOL,PHP_EOL."<br>","SET FOREIGN_KEY_CHECKS=0;".PHP_EOL.PHP_EOL.$changes.PHP_EOL.PHP_EOL."SET FOREIGN_KEY_CHECKS=1;");
  121.         die("");
  122.     }
  123.     die(":nothing #1123");
  124. }
  125.  
  126. /**
  127.  *
  128.  * Name getAlterTableStatement
  129.  *
  130.  * @param $table
  131.  * @param $column
  132.  * @param $info
  133.  *
  134.  * @return string
  135.  *
  136.  * @author RapidMod.io
  137.  * @author 813.330.0522
  138.  * @created 1/25/20
  139.  */
  140.  function getAlterTableStatement($table,$column,$info){
  141.     $alter = "";
  142.     $stmnt = "ALTER TABLE `{$table}` ADD COLUMN `{$column}` {$info["Type"]}";
  143.     if($info["Key"]){
  144.         switch (strtolower($info["Key"])){
  145.             case "pri" : return $stmnt. " PRIMARY KEY AUTO_INCREMENT ;"; break;
  146.             case "mul" : $alter = PHP_EOL."ALTER TABLE `$table` ADD INDEX {$column} ({$column}); "; break;
  147.             case "uni" : $alter = PHP_EOL."ALTER TABLE `$table` ADD UNIQUE INDEX {$column} ({$column}); ";break;
  148.             default : break;
  149.         }
  150.     }
  151.  
  152.  
  153.     if($info["Null"] === "YES"){
  154.         $stmnt .= " NULL";
  155.     }else{
  156.         $stmnt .= " NOT NULL";
  157.     }
  158.     if($info["Default"]){
  159.         if(in_array(strtolower($info["Type"]),["datetime","timestamp"]) && $info["Default"] !== "CURRENT_TIMESTAMP"){
  160.             $var = "0000-00-00 00:00:00";
  161.         }else if(is_numeric($info["Default"]) || $info["Default"] === "CURRENT_TIMESTAMP"){
  162.             $var = $info["Default"];
  163.         }else{
  164.             $var = "'{$info["Default"]}'";
  165.         }
  166.         $stmnt .= " DEFAULT {$var}";
  167.     }
  168.  
  169.     return "{$stmnt};{$alter}";
  170. }
  171.  
  172. /**
  173.  *
  174.  * Name fetchQ
  175.  *
  176.  * @param PDO $pdo
  177.  * @param string $query
  178.  * @param array $params
  179.  *
  180.  * @return array
  181.  *
  182.  * @author RapidMod.io
  183.  * @author 813.330.0522
  184.  * @created 1/24/20
  185.  */
  186. function fetchQ(PDO $pdo, string $query,array $params = []){
  187.         $stmnt = $pdo->prepare($query,[PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true]);
  188.  
  189.         $x = array();
  190.  
  191.         if(isset($params[0]) && is_array($params[0])){$params = $params[0];}
  192.         if(empty($params)){$params=null;}
  193.         $success = $stmnt->execute($params);
  194.         //\Rapidmod\Dev::printVar($stmnt);
  195.         if($success){
  196.             while($row = $stmnt->fetch(PDO::FETCH_ASSOC)){
  197.                 $x[] = $row;
  198.             }
  199.         }
  200.         return $x;
  201.     }
  202.     executeQ([]);
  203. ?>
Advertisement
Add Comment
Please, Sign In to add comment