Example #1
0
 public function tag($table)
 {
     foreach ($this->sourceBucket as &$entry1) {
         if (is_null($entry1)) {
             continue;
         }
         foreach ($this->targetBucket as &$entry2) {
             if (is_null($entry2)) {
                 continue;
             }
             if ($this->isKeyEqual($entry1, $entry2)) {
                 // unset the fields to ignore
                 $params = ParamsFactory::get();
                 if (isset($params->fieldsToIgnore[$table])) {
                     foreach ($params->fieldsToIgnore[$table] as $fieldToIgnore) {
                         unset($entry1[$fieldToIgnore]);
                         unset($entry2[$fieldToIgnore]);
                     }
                 }
                 $differ = new MapDiffer();
                 $diff = $differ->doDiff($entry2, $entry1);
                 if (!empty($diff)) {
                     $this->diffBucket[] = ['keys' => array_only($entry1, $this->key), 'diff' => $diff];
                 }
                 $entry1 = null;
                 $entry2 = null;
             }
         }
     }
 }
Example #2
0
 function getDiff()
 {
     $params = ParamsFactory::get();
     $diffSequence = [];
     // Tables
     $tableData = new TableData($this->manager);
     $sourceTables = $this->manager->getTables('source');
     $targetTables = $this->manager->getTables('target');
     if (isset($params->tablesToIgnore)) {
         $sourceTables = array_diff($sourceTables, $params->tablesToIgnore);
         $targetTables = array_diff($targetTables, $params->tablesToIgnore);
     }
     $commonTables = array_intersect($sourceTables, $targetTables);
     foreach ($commonTables as $table) {
         try {
             $diffs = $tableData->getDiff($table);
             $diffSequence = array_merge($diffSequence, $diffs);
         } catch (DataException $e) {
             Logger::error($e->getMessage());
         }
     }
     $addedTables = array_diff($sourceTables, $targetTables);
     foreach ($addedTables as $table) {
         $diffs = $tableData->getNewData($table);
         $diffSequence = array_merge($diffSequence, $diffs);
     }
     $deletedTables = array_diff($targetTables, $sourceTables);
     foreach ($deletedTables as $table) {
         $diffs = $tableData->getOldData($table);
         $diffSequence = array_merge($diffSequence, $diffs);
     }
     return $diffSequence;
 }
Example #3
0
 public function getChangeDiff($table, $key)
 {
     $params = ParamsFactory::get();
     $diffSequence = [];
     $db1 = $this->source->getDatabaseName();
     $db2 = $this->target->getDatabaseName();
     $columns1 = $this->manager->getColumns('source', $table);
     $columns2 = $this->manager->getColumns('target', $table);
     if (isset($params->fieldsToIgnore[$table])) {
         $columns1 = array_diff($columns1, $params->fieldsToIgnore[$table]);
         $columns2 = array_diff($columns2, $params->fieldsToIgnore[$table]);
     }
     $wrapAs = function ($arr, $p1, $p2) {
         return array_map(function ($el) use($p1, $p2) {
             return "`{$p1}`.`{$el}` as `{$p2}{$el}`";
         }, $arr);
     };
     $wrapCast = function ($arr, $p) {
         return array_map(function ($el) use($p) {
             return "CAST(`{$p}`.`{$el}` AS CHAR CHARACTER SET utf8)";
         }, $arr);
     };
     $columnsAas = implode(',', $wrapAs($columns1, 'a', 's_'));
     $columnsA = implode(',', $wrapCast($columns1, 'a'));
     $columnsBas = implode(',', $wrapAs($columns2, 'b', 't_'));
     $columnsB = implode(',', $wrapCast($columns2, 'b'));
     $keyCols = implode(' AND ', array_map(function ($el) {
         return "a.{$el} = b.{$el}";
     }, $key));
     $this->source->setFetchMode(\PDO::FETCH_NAMED);
     $result = $this->source->select("SELECT * FROM (\n                SELECT {$columnsAas}, {$columnsBas}, MD5(concat({$columnsA})) AS hash1,\n                MD5(concat({$columnsB})) AS hash2 FROM {$db1}.{$table} as a \n                INNER JOIN {$db2}.{$table} as b  \n                ON {$keyCols}\n            ) t WHERE hash1 <> hash2");
     $this->source->setFetchMode(\PDO::FETCH_ASSOC);
     foreach ($result as $row) {
         $diff = [];
         $keys = [];
         foreach ($row as $k => $value) {
             if (starts_with($k, 's_')) {
                 $theKey = substr($k, 2);
                 $targetKey = 't_' . $theKey;
                 $sourceValue = $value;
                 if (in_array($theKey, $key)) {
                     $keys[$theKey] = $value;
                 }
                 if (isset($row[$targetKey])) {
                     $targetValue = $row[$targetKey];
                     if ($sourceValue != $targetValue) {
                         $diff[$theKey] = new \Diff\DiffOp\DiffOpChange($targetValue, $sourceValue);
                     }
                 } else {
                     $diff[$theKey] = new \Diff\DiffOp\DiffOpChange(NULL, $sourceValue);
                 }
             }
         }
         $diffSequence[] = new UpdateData($table, ['keys' => $keys, 'diff' => $diff]);
     }
     return $diffSequence;
 }
Example #4
0
 public function run()
 {
     // Increase memory limit
     ini_set('memory_limit', '512M');
     try {
         // Params
         $paramsFactory = new ParamsFactory();
         $params = $paramsFactory->get();
         // Diff
         $diffCalculator = new DiffCalculator();
         $diff = $diffCalculator->getDiff($params);
         // Empty diff
         if (empty($diff['schema']) && empty($diff['data'])) {
             Logger::info("Identical resources");
         } else {
             // SQL
             $sqlGenerator = new SQLGenerator($diff);
             $up = '';
             $down = '';
             if ($params->include !== 'down') {
                 $up = $sqlGenerator->getUp();
             }
             if ($params->include !== 'up') {
                 $down = $sqlGenerator->getDown();
             }
             // Generate
             $templater = new Templater($params, $up, $down);
             $templater->output();
         }
         Logger::success("Completed");
     } catch (\Exception $e) {
         if ($e instanceof BaseException) {
             Logger::error($e->getMessage(), true);
         } else {
             Logger::error("Unexpected error: ");
             throw $e;
         }
     }
 }
Example #5
0
 function getDiff()
 {
     $params = ParamsFactory::get();
     $diffs = [];
     // Collation
     $dbName = $this->manager->getDB('target')->getDatabaseName();
     $sourceCollation = $this->getDBVariable('source', 'collation_database');
     $targetCollation = $this->getDBVariable('target', 'collation_database');
     if ($sourceCollation !== $targetCollation) {
         $diffs[] = new SetDBCollation($dbName, $sourceCollation, $targetCollation);
     }
     // Charset
     $sourceCharset = $this->getDBVariable('source', 'character_set_database');
     $targetCharset = $this->getDBVariable('target', 'character_set_database');
     if ($sourceCharset !== $targetCharset) {
         $diffs[] = new SetDBCharset($dbName, $sourceCharset, $targetCharset);
     }
     // Tables
     $tableSchema = new TableSchema($this->manager);
     $sourceTables = $this->manager->getTables('source');
     $targetTables = $this->manager->getTables('target');
     if (isset($params->tablesToIgnore)) {
         $sourceTables = array_diff($sourceTables, $params->tablesToIgnore);
         $targetTables = array_diff($targetTables, $params->tablesToIgnore);
     }
     $addedTables = array_diff($sourceTables, $targetTables);
     foreach ($addedTables as $table) {
         $diffs[] = new AddTable($table, $this->manager->getDB('source'));
     }
     $commonTables = array_intersect($sourceTables, $targetTables);
     foreach ($commonTables as $table) {
         $tableDiff = $tableSchema->getDiff($table);
         $diffs = array_merge($diffs, $tableDiff);
     }
     $deletedTables = array_diff($targetTables, $sourceTables);
     foreach ($deletedTables as $table) {
         $diffs[] = new DropTable($table, $this->manager->getDB('target'));
     }
     return $diffs;
 }