schema.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. class OC_DB_Schema {
  9. /**
  10. * @brief saves database scheme to xml file
  11. * @param \Doctrine\DBAL\Connection $conn
  12. * @param string $file name of file
  13. * @param int|string $mode
  14. * @return bool
  15. *
  16. * TODO: write more documentation
  17. */
  18. public static function getDbStructure( $conn, $file, $mode=MDB2_SCHEMA_DUMP_STRUCTURE) {
  19. $sm = $conn->getSchemaManager();
  20. return OC_DB_MDB2SchemaWriter::saveSchemaToFile($file, $sm);
  21. }
  22. /**
  23. * @brief Creates tables from XML file
  24. * @param string $file file to read structure from
  25. * @return bool
  26. *
  27. * TODO: write more documentation
  28. */
  29. public static function createDbFromStructure( $conn, $file ) {
  30. $toSchema = OC_DB_MDB2SchemaReader::loadSchemaFromFile($file, $conn->getDatabasePlatform());
  31. return self::executeSchemaChange($conn, $toSchema);
  32. }
  33. /**
  34. * @brief update the database scheme
  35. * @param string $file file to read structure from
  36. * @return bool
  37. */
  38. public static function updateDbFromStructure($conn, $file) {
  39. $sm = $conn->getSchemaManager();
  40. $fromSchema = $sm->createSchema();
  41. $toSchema = OC_DB_MDB2SchemaReader::loadSchemaFromFile($file, $conn->getDatabasePlatform());
  42. // remove tables we don't know about
  43. foreach($fromSchema->getTables() as $table) {
  44. if (!$toSchema->hasTable($table->getName())) {
  45. $fromSchema->dropTable($table->getName());
  46. }
  47. }
  48. // remove sequences we don't know about
  49. foreach($fromSchema->getSequences() as $table) {
  50. if (!$toSchema->hasSequence($table->getName())) {
  51. $fromSchema->dropSequence($table->getName());
  52. }
  53. }
  54. $comparator = new \Doctrine\DBAL\Schema\Comparator();
  55. $schemaDiff = $comparator->compare($fromSchema, $toSchema);
  56. $platform = $conn->getDatabasePlatform();
  57. $tables = $schemaDiff->newTables + $schemaDiff->changedTables + $schemaDiff->removedTables;
  58. foreach($tables as $tableDiff) {
  59. $tableDiff->name = $platform->quoteIdentifier($tableDiff->name);
  60. }
  61. //$from = $fromSchema->toSql($conn->getDatabasePlatform());
  62. //$to = $toSchema->toSql($conn->getDatabasePlatform());
  63. //echo($from[9]);
  64. //echo '<br>';
  65. //echo($to[9]);
  66. //var_dump($from, $to);
  67. return self::executeSchemaChange($conn, $schemaDiff);
  68. }
  69. /**
  70. * @brief drop a table
  71. * @param string $tableName the table to drop
  72. */
  73. public static function dropTable($conn, $tableName) {
  74. $sm = $conn->getSchemaManager();
  75. $fromSchema = $sm->createSchema();
  76. $toSchema = clone $fromSchema;
  77. $toSchema->dropTable($tableName);
  78. $sql = $fromSchema->getMigrateToSql($toSchema, $conn->getDatabasePlatform());
  79. $conn->execute($sql);
  80. }
  81. /**
  82. * remove all tables defined in a database structure xml file
  83. * @param string $file the xml file describing the tables
  84. */
  85. public static function removeDBStructure($conn, $file) {
  86. $fromSchema = OC_DB_MDB2SchemaReader::loadSchemaFromFile($file, $conn->getDatabasePlatform());
  87. $toSchema = clone $fromSchema;
  88. foreach($toSchema->getTables() as $table) {
  89. $toSchema->dropTable($table->getName());
  90. }
  91. $comparator = new \Doctrine\DBAL\Schema\Comparator();
  92. $schemaDiff = $comparator->compare($fromSchema, $toSchema);
  93. self::executeSchemaChange($conn, $schemaDiff);
  94. }
  95. /**
  96. * @brief replaces the ownCloud tables with a new set
  97. * @param $file string path to the MDB2 xml db export file
  98. */
  99. public static function replaceDB( $conn, $file ) {
  100. $apps = OC_App::getAllApps();
  101. self::beginTransaction();
  102. // Delete the old tables
  103. self::removeDBStructure( $conn, OC::$SERVERROOT . '/db_structure.xml' );
  104. foreach($apps as $app) {
  105. $path = OC_App::getAppPath($app).'/appinfo/database.xml';
  106. if(file_exists($path)) {
  107. self::removeDBStructure( $conn, $path );
  108. }
  109. }
  110. // Create new tables
  111. self::commit();
  112. }
  113. private static function executeSchemaChange($conn, $schema) {
  114. $conn->beginTransaction();
  115. foreach($schema->toSql($conn->getDatabasePlatform()) as $sql) {
  116. $conn->query($sql);
  117. }
  118. $conn->commit();
  119. }
  120. }