11574: backup should only dump structure of some tables
authorPaul Mehrer <p.mehrer@metaways.de>
Tue, 12 Apr 2016 11:18:37 +0000 (13:18 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Fri, 13 May 2016 13:52:06 +0000 (15:52 +0200)
added <backupStructureOnly> flag to setup.xml

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

Change-Id: I0959a1f5f3c006770c9ffb507d3f7a8e8fe313d3
Reviewed-on: http://gerrit.tine20.com/customers/3159
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/setup/Setup/ControllerTest.php
tests/setup/Setup/Controller_Mock.php [new file with mode: 0644]
tine20/Felamimail/Setup/setup.xml
tine20/Setup/Backend/Mysql.php
tine20/Setup/Controller.php

index f9905a2..ecdab81 100644 (file)
@@ -315,4 +315,18 @@ class Setup_ControllerTest extends PHPUnit_Framework_TestCase
         $installableApplications = array_keys($installableApplications);
         $this->_uit->installApplications($installableApplications, $_options);
     }
+
+    /**
+     * @see 11574: backup should only dump structure of some tables
+     */
+    public function testGetBackupStructureOnlyTables()
+    {
+        require_once __DIR__ . '/Controller_Mock.php';
+
+        $setupControllerMock = new Setup_Controller_Mock();
+
+        $tables = $setupControllerMock->getBackupStructureOnlyTables();
+
+        $this->assertTrue(in_array(SQL_TABLE_PREFIX . 'felamimail_cache_message', $tables), 'felamimail tables need to be in _getBackupStructureOnlyTables');
+    }
 }
diff --git a/tests/setup/Setup/Controller_Mock.php b/tests/setup/Setup/Controller_Mock.php
new file mode 100644 (file)
index 0000000..d2703b4
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Tine 2.0 - http://www.tine20.org
+ *
+ * @package     Setup
+ * @license     http://www.gnu.org/licenses/agpl.html
+ * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Paul Mehrer <p.mehrer@metaways.de>
+ *
+ */
+
+/**
+ * Test mock
+ */
+
+class Setup_Controller_Mock extends Setup_Controller
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function getBackupStructureOnlyTables()
+    {
+        return $this->_getBackupStructureOnlyTables();
+    }
+}
\ No newline at end of file
index de0a6b8..c20501d 100644 (file)
         <table>
             <name>felamimail_cache_message</name>
             <version>10</version>
+            <backupStructureOnly>true</backupStructureOnly>
             <declaration>
                 <field>
                     <name>id</name>
         <table>
             <name>felamimail_cache_msg_flag</name>
             <version>1</version>
+            <backupStructureOnly>true</backupStructureOnly>
             <declaration>
                 <field>
                     <name>message_id</name>
         <table>
             <name>felamimail_cache_message_to</name>
             <version>2</version>
+            <backupStructureOnly>true</backupStructureOnly>
             <declaration>
                 <field>
                     <name>message_id</name>
         <table>
             <name>felamimail_cache_message_cc</name>
             <version>2</version>
+            <backupStructureOnly>true</backupStructureOnly>
             <declaration>
                 <field>
                     <name>message_id</name>
         <table>
             <name>felamimail_cache_message_bcc</name>
             <version>2</version>
+            <backupStructureOnly>true</backupStructureOnly>
             <declaration>
                 <field>
                     <name>message_id</name>
index 684b577..929b858 100644 (file)
@@ -326,18 +326,35 @@ class Setup_Backend_Mysql extends Setup_Backend_Abstract
     /**
      * Backup Database
      *
-     * @param $backupDir
+     * @param $option
      */
-    public function backup($backupDir)
+    public function backup($option)
     {
+        $backupDir = $option['backupDir'];
+
         // hide password from shell via my.cnf
         $mycnf = $backupDir . '/my.cnf';
         $this->_createMyConf($mycnf, $this->_config->database);
 
-        $cmd = "mysqldump --defaults-extra-file=$mycnf "
+        $ignoreTables = '';
+        if (count($option['structTables']) > 0) {
+            $structDump = 'mysqldump --defaults-extra-file=' . $mycnf . ' --no-data ' .
+                escapeshellarg($this->_config->database->dbname);
+            foreach($option['structTables'] as $table) {
+                $structDump .= ' ' . escapeshellarg($table);
+                $ignoreTables .= '--ignore-table=' . escapeshellarg($this->_config->database->dbname . '.' . $table) . ' ';
+            }
+        } else {
+            $structDump = false;
+        }
+
+        $cmd = ($structDump!==false?'{ ':'')
+              ."mysqldump --defaults-extra-file=$mycnf "
+              .$ignoreTables
               ."--single-transaction "
               ."--opt "
               . escapeshellarg($this->_config->database->dbname)
+              . ($structDump!==false?'; ' . $structDump . '; }':'')
               ." | bzip2 > $backupDir/tine20_mysql.sql.bz2";
 
         exec($cmd);
index cf63595..1f35a77 100644 (file)
@@ -90,7 +90,7 @@ class Setup_Controller
      * the constructor
      *
      */
-    private function __construct()
+    protected function __construct()
     {
         // setup actions could take quite a while we try to set max execution time to unlimited
         Setup_Core::setExecutionLifeTime(0);
@@ -1891,7 +1891,13 @@ class Setup_Controller
             if (! $this->_backend) {
                 throw new Exception('db not configured, cannot backup');
             }
-            $this->_backend->backup($backupDir);
+
+            $backupOptions = array(
+                'backupDir'         => $backupDir,
+                'structTables'      => $this->_getBackupStructureOnlyTables(),
+            );
+
+            $this->_backend->backup($backupOptions);
         }
 
         $filesDir = isset($config->filesdir) ? $config->filesdir : false;
@@ -1901,6 +1907,35 @@ class Setup_Controller
     }
 
     /**
+     * returns an array of all tables of all applications that should only backup the structure
+     *
+     * @return array
+     * @throws Setup_Exception_NotFound
+     */
+    protected function _getBackupStructureOnlyTables()
+    {
+        $tables = array();
+
+        // find tables that only backup structure
+        $applications = Tinebase_Application::getInstance()->getApplications();
+
+        /**
+         * @var $application Tinebase_Model_Application
+         */
+        foreach($applications as $application) {
+            $tableDef = $this->getSetupXml($application->name);
+            $structOnlys = $tableDef->xpath('//table/backupStructureOnly[text()="true"]');
+
+            foreach($structOnlys as $structOnly) {
+                $tableName = $structOnly->xpath('./../name/text()');
+                $tables[] = SQL_TABLE_PREFIX . $tableName[0];
+            }
+        }
+
+        return $tables;
+    }
+
+    /**
      * restore
      *
      * @param $options array(