migrator.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. /**
  3. * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
  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 Test\DB;
  9. use \Doctrine\DBAL\DBALException;
  10. use Doctrine\DBAL\Platforms\OraclePlatform;
  11. use Doctrine\DBAL\Platforms\SQLServerPlatform;
  12. use \Doctrine\DBAL\Schema\Schema;
  13. use \Doctrine\DBAL\Schema\SchemaConfig;
  14. class Migrator extends \Test\TestCase {
  15. /**
  16. * @var \Doctrine\DBAL\Connection $connection
  17. */
  18. private $connection;
  19. /**
  20. * @var \OC\DB\MDB2SchemaManager
  21. */
  22. private $manager;
  23. private $tableName;
  24. protected function setUp() {
  25. parent::setUp();
  26. $this->connection = \OC_DB::getConnection();
  27. if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
  28. $this->markTestSkipped('DB migration tests are not supported on OCI');
  29. }
  30. if ($this->connection->getDatabasePlatform() instanceof SQLServerPlatform) {
  31. $this->markTestSkipped('DB migration tests are not supported on MSSQL');
  32. }
  33. $this->manager = new \OC\DB\MDB2SchemaManager($this->connection);
  34. $this->tableName = strtolower($this->getUniqueID('oc_test_'));
  35. }
  36. protected function tearDown() {
  37. $this->connection->exec('DROP TABLE ' . $this->tableName);
  38. parent::tearDown();
  39. }
  40. /**
  41. * @return \Doctrine\DBAL\Schema\Schema[]
  42. */
  43. private function getDuplicateKeySchemas() {
  44. $startSchema = new Schema(array(), array(), $this->getSchemaConfig());
  45. $table = $startSchema->createTable($this->tableName);
  46. $table->addColumn('id', 'integer');
  47. $table->addColumn('name', 'string');
  48. $table->addIndex(array('id'), $this->tableName . '_id');
  49. $endSchema = new Schema(array(), array(), $this->getSchemaConfig());
  50. $table = $endSchema->createTable($this->tableName);
  51. $table->addColumn('id', 'integer');
  52. $table->addColumn('name', 'string');
  53. $table->addUniqueIndex(array('id'), $this->tableName . '_id');
  54. return array($startSchema, $endSchema);
  55. }
  56. private function getSchemaConfig() {
  57. $config = new SchemaConfig();
  58. $config->setName($this->connection->getDatabase());
  59. return $config;
  60. }
  61. private function isSQLite() {
  62. return $this->connection->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver;
  63. }
  64. /**
  65. * @expectedException \OC\DB\MigrationException
  66. */
  67. public function testDuplicateKeyUpgrade() {
  68. if ($this->isSQLite()) {
  69. $this->markTestSkipped('sqlite does not throw errors when creating a new key on existing data');
  70. }
  71. list($startSchema, $endSchema) = $this->getDuplicateKeySchemas();
  72. $migrator = $this->manager->getMigrator();
  73. $migrator->migrate($startSchema);
  74. $this->connection->insert($this->tableName, array('id' => 1, 'name' => 'foo'));
  75. $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'bar'));
  76. $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'qwerty'));
  77. $migrator->checkMigrate($endSchema);
  78. $this->fail('checkMigrate should have failed');
  79. }
  80. public function testUpgrade() {
  81. list($startSchema, $endSchema) = $this->getDuplicateKeySchemas();
  82. $migrator = $this->manager->getMigrator();
  83. $migrator->migrate($startSchema);
  84. $this->connection->insert($this->tableName, array('id' => 1, 'name' => 'foo'));
  85. $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'bar'));
  86. $this->connection->insert($this->tableName, array('id' => 3, 'name' => 'qwerty'));
  87. $migrator->checkMigrate($endSchema);
  88. $migrator->migrate($endSchema);
  89. $this->assertTrue(true);
  90. }
  91. public function testInsertAfterUpgrade() {
  92. list($startSchema, $endSchema) = $this->getDuplicateKeySchemas();
  93. $migrator = $this->manager->getMigrator();
  94. $migrator->migrate($startSchema);
  95. $migrator->migrate($endSchema);
  96. $this->connection->insert($this->tableName, array('id' => 1, 'name' => 'foo'));
  97. $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'bar'));
  98. try {
  99. $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'qwerty'));
  100. $this->fail('Expected duplicate key insert to fail');
  101. } catch (DBALException $e) {
  102. $this->assertTrue(true);
  103. }
  104. }
  105. public function testAddingPrimaryKeyWithAutoIncrement() {
  106. $startSchema = new Schema(array(), array(), $this->getSchemaConfig());
  107. $table = $startSchema->createTable($this->tableName);
  108. $table->addColumn('id', 'integer');
  109. $table->addColumn('name', 'string');
  110. $endSchema = new Schema(array(), array(), $this->getSchemaConfig());
  111. $table = $endSchema->createTable($this->tableName);
  112. $table->addColumn('id', 'integer', array('autoincrement' => true));
  113. $table->addColumn('name', 'string');
  114. $table->setPrimaryKey(array('id'));
  115. $migrator = $this->manager->getMigrator();
  116. $migrator->migrate($startSchema);
  117. $migrator->checkMigrate($endSchema);
  118. $migrator->migrate($endSchema);
  119. $this->assertTrue(true);
  120. }
  121. public function testReservedKeywords() {
  122. $startSchema = new Schema(array(), array(), $this->getSchemaConfig());
  123. $table = $startSchema->createTable($this->tableName);
  124. $table->addColumn('id', 'integer', array('autoincrement' => true));
  125. $table->addColumn('user', 'string', array('length' => 255));
  126. $table->setPrimaryKey(array('id'));
  127. $endSchema = new Schema(array(), array(), $this->getSchemaConfig());
  128. $table = $endSchema->createTable($this->tableName);
  129. $table->addColumn('id', 'integer', array('autoincrement' => true));
  130. $table->addColumn('user', 'string', array('length' => 64));
  131. $table->setPrimaryKey(array('id'));
  132. $migrator = $this->manager->getMigrator();
  133. $migrator->migrate($startSchema);
  134. $migrator->checkMigrate($endSchema);
  135. $migrator->migrate($endSchema);
  136. $this->assertTrue(true);
  137. }
  138. }