]> source.dussan.org Git - nextcloud-server.git/commitdiff
Check sqlite migration on a copy of the database file
authorRobin Appelman <icewind@owncloud.com>
Thu, 27 Mar 2014 13:44:19 +0000 (14:44 +0100)
committerRobin Appelman <icewind@owncloud.com>
Tue, 3 Jun 2014 09:17:21 +0000 (11:17 +0200)
lib/private/db/migrator.php
lib/private/db/sqlitemigrator.php [new file with mode: 0644]
tests/lib/db/migrator.php

index 3f32e8c603edd16fa4d9a4343cbd0c6c299a3907..5ba16e34311349b97de4a0b2dd42c6f8603de250 100644 (file)
@@ -37,6 +37,7 @@ class Migrator {
 
        /**
         * @param Schema $targetSchema
+        * @throws \OC\DB\MigrationException
         */
        public function checkMigrate(Schema $targetSchema) {
                /**
diff --git a/lib/private/db/sqlitemigrator.php b/lib/private/db/sqlitemigrator.php
new file mode 100644 (file)
index 0000000..f5f7898
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\DB;
+
+use Doctrine\DBAL\DBALException;
+
+class SQLiteMigrator extends Migrator {
+       /**
+        * @param \Doctrine\DBAL\Schema\Schema $targetSchema
+        * @throws \OC\DB\MigrationException
+        *
+        * For sqlite we simple make a copy of the entire database, and test the migration on that
+        */
+       public function checkMigrate(\Doctrine\DBAL\Schema\Schema $targetSchema) {
+               $dbFile = $this->connection->getDatabase();
+               $tmpFile = \OC_Helper::tmpFile('.db');
+               copy($dbFile, $tmpFile);
+
+               $connectionParams = array(
+                       'path' => $tmpFile,
+                       'driver' => 'pdo_sqlite',
+               );
+               $conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams);
+               try {
+                       $this->applySchema($targetSchema, $conn);
+                       $conn->close();
+                       unlink($tmpFile);
+               } catch (DBALException $e) {
+                       $conn->close();
+                       unlink($tmpFile);
+                       throw new MigrationException('', $e->getMessage());
+               }
+       }
+}
index 88f6d7dcc63451341df86cb476f4f1f95edafad2..31dc1c4951ac1cfc6be19712ab3ba7fdd3447901 100644 (file)
@@ -9,6 +9,7 @@
 
 namespace Test\DB;
 
+use \Doctrine\DBAL\DBALException;
 use \Doctrine\DBAL\Schema\Schema;
 use \Doctrine\DBAL\Schema\SchemaConfig;
 
@@ -23,31 +24,29 @@ class Migrator extends \PHPUnit_Framework_TestCase {
        public function setUp() {
                $this->tableName = 'test_' . uniqid();
                $this->connection = \OC_DB::getConnection();
-               if ($this->connection->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
-                       $this->markTestSkipped('Migration tests dont function on sqlite since sqlite doesnt give an error on existing duplicate data');
-               }
        }
 
        public function tearDown() {
                $this->connection->exec('DROP TABLE ' . $this->tableName);
        }
 
-       private function getInitialSchema() {
-               $schema = new Schema(array(), array(), $this->getSchemaConfig());
-               $table = $schema->createTable($this->tableName);
+       /**
+        * @return \Doctrine\DBAL\Schema\Schema[]
+        */
+       private function getDuplicateKeySchemas() {
+               $startSchema = new Schema(array(), array(), $this->getSchemaConfig());
+               $table = $startSchema->createTable($this->tableName);
                $table->addColumn('id', 'integer');
                $table->addColumn('name', 'string');
                $table->addIndex(array('id'), $this->tableName . '_id');
-               return $schema;
-       }
 
-       private function getNewSchema() {
-               $schema = new Schema(array(), array(), $this->getSchemaConfig());
-               $table = $schema->createTable($this->tableName);
+               $endSchema = new Schema(array(), array(), $this->getSchemaConfig());
+               $table = $endSchema->createTable($this->tableName);
                $table->addColumn('id', 'integer');
                $table->addColumn('name', 'string');
                $table->addUniqueIndex(array('id'), $this->tableName . '_id');
-               return $schema;
+
+               return array($startSchema, $endSchema);
        }
 
        private function getSchemaConfig() {
@@ -56,36 +55,65 @@ class Migrator extends \PHPUnit_Framework_TestCase {
                return $config;
        }
 
+       private function isSQLite() {
+               return $this->connection->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver;
+       }
+
        private function getMigrator() {
-               return new \OC\DB\Migrator($this->connection);
+               if ($this->isSQLite()) {
+                       return new \OC\DB\SQLiteMigrator($this->connection);
+               } else {
+                       return new \OC\DB\Migrator($this->connection);
+               }
        }
 
        /**
         * @expectedException \OC\DB\MigrationException
         */
        public function testDuplicateKeyUpgrade() {
+               if ($this->isSQLite()) {
+                       $this->markTestSkipped('sqlite doesnt throw errors when creating a new key on existing data');
+               }
+               list($startSchema, $endSchema) = $this->getDuplicateKeySchemas();
                $migrator = $this->getMigrator();
-               $migrator->migrate($this->getInitialSchema());
+               $migrator->migrate($startSchema);
 
                $this->connection->insert($this->tableName, array('id' => 1, 'name' => 'foo'));
                $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'bar'));
                $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'qwerty'));
 
-               $migrator->checkMigrate($this->getNewSchema());
+               $migrator->checkMigrate($endSchema);
                $this->fail('checkMigrate should have failed');
        }
 
        public function testUpgrade() {
+               list($startSchema, $endSchema) = $this->getDuplicateKeySchemas();
                $migrator = $this->getMigrator();
-               $migrator->migrate($this->getInitialSchema());
+               $migrator->migrate($startSchema);
 
                $this->connection->insert($this->tableName, array('id' => 1, 'name' => 'foo'));
                $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'bar'));
                $this->connection->insert($this->tableName, array('id' => 3, 'name' => 'qwerty'));
 
-               $newSchema = $this->getNewSchema();
-               $migrator->checkMigrate($newSchema);
-               $migrator->migrate($newSchema);
+               $migrator->checkMigrate($endSchema);
+               $migrator->migrate($endSchema);
                $this->assertTrue(true);
        }
+
+       public function testInsertAfterUpgrade() {
+               list($startSchema, $endSchema) = $this->getDuplicateKeySchemas();
+               $migrator = $this->getMigrator();
+               $migrator->migrate($startSchema);
+
+               $migrator->migrate($endSchema);
+
+               $this->connection->insert($this->tableName, array('id' => 1, 'name' => 'foo'));
+               $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'bar'));
+               try {
+                       $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'qwerty'));
+                       $this->fail('Expected duplicate key insert to fail');
+               } catch (DBALException $e) {
+                       $this->assertTrue(true);
+               }
+       }
 }