mdb2schemamanager.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace OC\DB;
  9. class MDB2SchemaManager {
  10. /**
  11. * @var \OC\DB\Connection $conn
  12. */
  13. protected $conn;
  14. /**
  15. * @param \OC\DB\Connection $conn
  16. */
  17. public function __construct($conn) {
  18. $this->conn = $conn;
  19. }
  20. /**
  21. * @brief saves database scheme to xml file
  22. * @param string $file name of file
  23. * @param int|string $mode
  24. * @return bool
  25. *
  26. * TODO: write more documentation
  27. */
  28. public function getDbStructure( $file, $mode = MDB2_SCHEMA_DUMP_STRUCTURE) {
  29. $sm = $this->conn->getSchemaManager();
  30. return \OC_DB_MDB2SchemaWriter::saveSchemaToFile($file, $sm);
  31. }
  32. /**
  33. * @brief Creates tables from XML file
  34. * @param string $file file to read structure from
  35. * @return bool
  36. *
  37. * TODO: write more documentation
  38. */
  39. public function createDbFromStructure( $file ) {
  40. $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
  41. $toSchema = $schemaReader->loadSchemaFromFile($file);
  42. return $this->executeSchemaChange($toSchema);
  43. }
  44. /**
  45. * @brief update the database scheme
  46. * @param string $file file to read structure from
  47. * @return bool
  48. */
  49. public function updateDbFromStructure($file) {
  50. $sm = $this->conn->getSchemaManager();
  51. $fromSchema = $sm->createSchema();
  52. $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
  53. $toSchema = $schemaReader->loadSchemaFromFile($file);
  54. // remove tables we don't know about
  55. foreach($fromSchema->getTables() as $table) {
  56. if (!$toSchema->hasTable($table->getName())) {
  57. $fromSchema->dropTable($table->getName());
  58. }
  59. }
  60. // remove sequences we don't know about
  61. foreach($fromSchema->getSequences() as $table) {
  62. if (!$toSchema->hasSequence($table->getName())) {
  63. $fromSchema->dropSequence($table->getName());
  64. }
  65. }
  66. $comparator = new \Doctrine\DBAL\Schema\Comparator();
  67. $schemaDiff = $comparator->compare($fromSchema, $toSchema);
  68. $platform = $this->conn->getDatabasePlatform();
  69. $tables = $schemaDiff->newTables + $schemaDiff->changedTables + $schemaDiff->removedTables;
  70. foreach($tables as $tableDiff) {
  71. $tableDiff->name = $platform->quoteIdentifier($tableDiff->name);
  72. }
  73. return $this->executeSchemaChange($schemaDiff);
  74. }
  75. /**
  76. * @brief drop a table
  77. * @param string $tableName the table to drop
  78. */
  79. public function dropTable($tableName) {
  80. $sm = $this->conn->getSchemaManager();
  81. $fromSchema = $sm->createSchema();
  82. $toSchema = clone $fromSchema;
  83. $toSchema->dropTable($tableName);
  84. $sql = $fromSchema->getMigrateToSql($toSchema, $this->conn->getDatabasePlatform());
  85. $this->conn->executeQuery($sql);
  86. }
  87. /**
  88. * remove all tables defined in a database structure xml file
  89. * @param string $file the xml file describing the tables
  90. */
  91. public function removeDBStructure($file) {
  92. $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
  93. $fromSchema = $schemaReader->loadSchemaFromFile($file);
  94. $toSchema = clone $fromSchema;
  95. foreach($toSchema->getTables() as $table) {
  96. $toSchema->dropTable($table->getName());
  97. }
  98. $comparator = new \Doctrine\DBAL\Schema\Comparator();
  99. $schemaDiff = $comparator->compare($fromSchema, $toSchema);
  100. $this->executeSchemaChange($schemaDiff);
  101. }
  102. /**
  103. * @brief replaces the ownCloud tables with a new set
  104. * @param $file string path to the MDB2 xml db export file
  105. */
  106. public function replaceDB( $file ) {
  107. $apps = \OC_App::getAllApps();
  108. $this->conn->beginTransaction();
  109. // Delete the old tables
  110. $this->removeDBStructure( \OC::$SERVERROOT . '/db_structure.xml' );
  111. foreach($apps as $app) {
  112. $path = \OC_App::getAppPath($app).'/appinfo/database.xml';
  113. if(file_exists($path)) {
  114. $this->removeDBStructure( $path );
  115. }
  116. }
  117. // Create new tables
  118. $this->conn->commit();
  119. }
  120. /**
  121. * @param \Doctrine\DBAL\Schema\Schema $schema
  122. * @return bool
  123. */
  124. private function executeSchemaChange($schema) {
  125. $this->conn->beginTransaction();
  126. foreach($schema->toSql($this->conn->getDatabasePlatform()) as $sql) {
  127. $this->conn->query($sql);
  128. }
  129. $this->conn->commit();
  130. return true;
  131. }
  132. }