Skip to content

Commit

Permalink
Add foreign key support to OC
Browse files Browse the repository at this point in the history
  • Loading branch information
mrow4a committed Oct 2, 2017
1 parent 84340ed commit 4caa4fc
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 11 deletions.
5 changes: 2 additions & 3 deletions core/Migrations/Version20170927145820.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ public function changeSchema(Schema $schema, array $options) {
// This set of values has to be unique
$table->addUniqueIndex(['backend_group_id', 'account_id', 'membership_type'], 'group_account_membership_index');

//TODO: Do it later since it requires changes here for Oracle https://github.com/owncloud/core/blob/master/lib/private/DB/OracleMigrator.php#L158-L160
// Add foreign keys on backend_group and accounts tables
//$table->addForeignKeyConstraint("{$prefix}backend_groups",array('backend_group_id'), array('id'));
//$table->addForeignKeyConstraint("{$prefix}accounts", array('account_id'), array('id'));
$table->addForeignKeyConstraint("{$prefix}backend_groups",array('backend_group_id'), array('id'));
$table->addForeignKeyConstraint("{$prefix}accounts", array('account_id'), array('id'));
}
}
40 changes: 36 additions & 4 deletions lib/private/DB/OracleMigrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;

class OracleMigrator extends NoCheckMigrator {

Expand Down Expand Up @@ -79,6 +80,27 @@ protected function quoteIndex($index) {
);
}

/**
* Quote an ForeignKeyConstraint's name but changing the name requires recreating
* the ForeignKeyConstraint instance and copying over all properties.
*
* @param ForeignKeyConstraint $fkc old fkc
* @return ForeignKeyConstraint new fkc instance with new name
*/
protected function quoteForeignKeyConstraint($fkc) {
return new ForeignKeyConstraint(
array_map(function($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $fkc->getLocalColumns()),
$this->connection->quoteIdentifier($fkc->getForeignTableName()),
array_map(function($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $fkc->getForeignColumns()),
$fkc->getName(),
$fkc->getOptions()
);
}

/**
* @param Schema $targetSchema
* @param \Doctrine\DBAL\Connection $connection
Expand All @@ -97,7 +119,9 @@ protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $conn
array_map(function(Index $index) {
return $this->quoteIndex($index);
}, $table->getIndexes()),
$table->getForeignKeys(),
array_map(function(ForeignKeyConstraint $fck) {
return $this->quoteForeignKeyConstraint($fck);
}, $table->getForeignKeys()),
0,
$table->getOptions()
);
Expand Down Expand Up @@ -155,9 +179,17 @@ protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $conn
return $this->quoteIndex($index);
}, $tableDiff->renamedIndexes);

// TODO handle $tableDiff->addedForeignKeys
// TODO handle $tableDiff->changedForeignKeys
// TODO handle $tableDiff->removedForeignKeys
$tableDiff->addedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) {
return $this->quoteForeignKeyConstraint($fkc);
}, $tableDiff->addedForeignKeys);

$tableDiff->changedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) {
return $this->quoteForeignKeyConstraint($fkc);
}, $tableDiff->changedForeignKeys);

$tableDiff->removedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) {
return $this->quoteForeignKeyConstraint($fkc);
}, $tableDiff->removedForeignKeys);
}

return $schemaDiff;
Expand Down
39 changes: 37 additions & 2 deletions tests/lib/DB/MigratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,32 @@ class MigratorTest extends \Test\TestCase {
/** @var string */
private $tableName;

/** @var string */
private $tableNameTmp;

protected function setUp() {
parent::setUp();

$this->config = \OC::$server->getConfig();
$this->connection = \OC::$server->getDatabaseConnection();
$this->manager = new \OC\DB\MDB2SchemaManager($this->connection);
$this->tableName = strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix', 'oc_') . 'test_'));
$this->tableName = $this->getUniqueTableName();
$this->tableNameTmp = $this->getUniqueTableName();
}

private function getUniqueTableName() {
return strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix', 'oc_') . 'test_'));
}

protected function tearDown() {
$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableName));
// Try to delete if exists (IF EXISTS NOT SUPPORTED IN ORACLE)
try {
$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableNameTmp));
} catch (\Doctrine\DBAL\DBALException $e) {}

try {
$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableName));
} catch (\Doctrine\DBAL\DBALException $e) {}
parent::tearDown();
}

Expand Down Expand Up @@ -269,4 +284,24 @@ public function testReservedKeywords() {

$this->assertTrue(true);
}

public function testAddingForeignKey() {
$startSchema = new Schema([], [], $this->getSchemaConfig());
$table = $startSchema->createTable($this->tableName);
$table->addColumn('id', 'integer', ['autoincrement' => true]);
$table->addColumn('name', 'string');
$table->setPrimaryKey(['id']);

$fkName = "fkc";
$tableFk = $startSchema->createTable($this->tableNameTmp);
$tableFk->addColumn('fk_id', 'integer');
$tableFk->addColumn('name', 'string');
$tableFk->addForeignKeyConstraint($this->tableName, array('fk_id'), array('id'), array(), $fkName);

$migrator = $this->manager->getMigrator();
$migrator->migrate($startSchema);


$this->assertTrue($startSchema->getTable($this->tableNameTmp)->hasForeignKey($fkName));
}
}
4 changes: 2 additions & 2 deletions version.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
$OC_Version = [10, 0, 4, 0];
$OC_Version = [10, 0, 3, 4];

// The human readable string
$OC_VersionString = '10.0.4';
$OC_VersionString = '10.0.3';

$OC_VersionCanBeUpgradedFrom = [[8, 2, 11],[9, 0, 9],[9, 1]];

Expand Down

0 comments on commit 4caa4fc

Please sign in to comment.