0012416: compare schema of two tine dbs
authorPhilipp Schüle <p.schuele@metaways.de>
Mon, 12 Dec 2016 11:21:12 +0000 (12:21 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Tue, 13 Dec 2016 11:16:32 +0000 (12:16 +0100)
use it like this:

$ php setup.php --compare -- otherdb=tine20other

https://forge.tine20.org/view.php?id=12416

Change-Id: I57004427635928c4c2bd41f4a2dce98f0bcdc9e3
Reviewed-on: http://gerrit.tine20.com/customers/3944
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
tests/setup/Setup/CliTest.php
tine20/Setup/Controller.php
tine20/Setup/Frontend/Cli.php
tine20/Setup/SchemaTool.php
tine20/Setup/Server/Cli.php

index 50c15e1..1524bfd 100644 (file)
@@ -83,4 +83,16 @@ class Setup_CliTest extends TestCase
         $this->assertEquals("foo", $result[0]);
         $this->assertEquals("bar", $result[1]);
     }
+
+    /**
+     * Test compare
+     */
+    public function testCompare()
+    {
+        $this->testSetConfig();
+        $result = $this->_cliHelper('compare', array('--compare','--','otherdb=tine20'));
+        $this->assertContains("Array
+(
+)", $result);
+    }
 }
index d4b7148..6b8cca7 100644 (file)
@@ -1992,7 +1992,7 @@ class Setup_Controller
             throw new Exception("you need to specify the backupDir");
         }
 
-        if ($options['config']) {
+        if (isset($options['config']) && $options['config']) {
             $configBackupFile = $options['backupDir']. '/tine20_config.tar.bz2';
             if (! file_exists($configBackupFile)) {
                 throw new Exception("$configBackupFile not found");
@@ -2013,12 +2013,12 @@ class Setup_Controller
         Setup_Core::setupConfig();
         $config = Setup_Core::getConfig();
 
-        if ($options['db']) {
+        if (isset($options['db']) && $options['db']) {
             $this->_backend->restore($options['backupDir']);
         }
 
         $filesDir = isset($config->filesdir) ? $config->filesdir : false;
-        if ($options['files']) {
+        if (isset($options['files']) && $options['files']) {
             $filesBackupFile = $options['backupDir'] . '/tine20_files.tar.bz2';
             if (! file_exists($filesBackupFile)) {
                 throw new Exception("$filesBackupFile not found");
@@ -2027,4 +2027,13 @@ class Setup_Controller
             `cd $filesDir; tar xf $filesBackupFile`;
         }
     }
+
+    public function compareSchema($options)
+    {
+        if (! isset($options['otherdb'])) {
+            throw new Exception("you need to specify the otherdb");
+        }
+
+        return Setup_SchemaTool::compareSchema($options['otherdb']);
+    }
 }
index 3f3218e..7e6b07a 100644 (file)
@@ -80,6 +80,8 @@ class Setup_Frontend_Cli
             $this->_backup($_opts);
         } elseif(isset($_opts->restore)) {
             $this->_restore($_opts);
+        } elseif(isset($_opts->compare)) {
+            $this->_compare($_opts);
         }
         
         if ($exitAfterHandle) {
@@ -809,4 +811,10 @@ class Setup_Frontend_Cli
         
         return $options;
     }
+
+    protected function _compare(Zend_Console_Getopt $_opts)
+    {
+        $options = $this->_parseRemainingArgs($_opts->getRemainingArgs());
+        print_r(Setup_Controller::getInstance()->compareSchema($options));
+    }
 }
index 30b4e29..6498626 100644 (file)
@@ -11,6 +11,7 @@
 use Doctrine\ORM\Tools\Setup;
 use Doctrine\ORM\EntityManager;
 use \Doctrine\ORM\Tools\SchemaTool;
+use Doctrine\DBAL\Schema\Comparator;
 use Doctrine\Common\Persistence\Mapping\StaticReflectionService;
 use \Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver;
 
@@ -66,15 +67,24 @@ class Setup_SchemaTool
             $tableNames[] = SQL_TABLE_PREFIX . Tinebase_Helper::array_value('name', $modelConfig->getTable());
         }
 
+        $config = self::getBasicConfig();
+        $config->setMetadataDriverImpl($mappingDriver);
+
+        $config->setFilterSchemaAssetsExpression('/'. implode('|',$tableNames) . '/');
+
+        return $config;
+    }
+
+    /**
+     * @return \Doctrine\ORM\Configuration
+     */
+    public static function getBasicConfig()
+    {
         // TODO we could use the tine20 redis cache here if configured (see \Doctrine\ORM\Tools\Setup::createConfiguration)
         // but as createConfiguration() tries to setup a redis cache if redis extension is available, we need to
         // setup a manual ArrayCache for the moment
         $cache = new \Doctrine\Common\Cache\ArrayCache();
         $config = Setup::createConfiguration(/* isDevMode = */ false, /* $proxyDir = */ null, $cache);
-        $config->setMetadataDriverImpl($mappingDriver);
-
-        $config->setFilterSchemaAssetsExpression('/'. implode('|',$tableNames) . '/');
-
         return $config;
     }
 
@@ -117,4 +127,32 @@ class Setup_SchemaTool
 
         $tool->updateSchema($classes, true);
     }
-}
\ No newline at end of file
+
+    /**
+     * compare two tine20 databases with each other
+     *
+     * @param $otherDbName
+     * @return array of sql statements
+     */
+    public static function compareSchema($otherDbName)
+    {
+        $dbParams = self::getDBParams();
+
+        $myConn = \Doctrine\DBAL\DriverManager::getConnection(
+            $dbParams
+        );
+        $mySm = $myConn->getSchemaManager();
+
+        $otherDbParams = $dbParams;
+        $otherDbParams['dbname'] = $otherDbName;
+        $otherConn = \Doctrine\DBAL\DriverManager::getConnection(
+            $otherDbParams
+        );
+        $otherSm = $otherConn->getSchemaManager();
+
+        $comparator = new Comparator();
+        $schemaDiff = $comparator->compare($mySm->createSchema(), $otherSm->createSchema());
+
+        return $schemaDiff->toSql($myConn->getDatabasePlatform());
+    }
+}
index 0ffb4e1..5bf82ec 100644 (file)
@@ -62,6 +62,9 @@ class Setup_Server_Cli implements Tinebase_Server_Interface
                 'restore'                   => 'restore config and data
                          Examples:
                            setup.php --restore -- config=1 db=1 files=1 backupDir=/backup/tine20',
+                'compare'                   => 'compare schemas with another database
+                        Examples:
+                           setup.php --compare -- otherdb=tine20other',
             ));
             $opts->parse();
         } catch (Zend_Console_Getopt_Exception $e) {
@@ -85,6 +88,7 @@ class Setup_Server_Cli implements Tinebase_Server_Interface
             empty($opts->setconfig) && 
             empty($opts->backup) &&
             empty($opts->restore) &&
+            empty($opts->compare) &&
             empty($opts->getconfig)))
         {
             echo $opts->getUsageMessage();