Fix calculation of default name

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2018-07-19 10:28:52 +02:00
parent 14682dfa7c
commit 960961148e
No known key found for this signature in database
GPG Key ID: 7076EA9751AACDDA
2 changed files with 83 additions and 6 deletions

View File

@ -23,6 +23,10 @@
namespace OC\DB; namespace OC\DB;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException; use Doctrine\DBAL\Schema\SchemaException;
use OC\IntegrityCheck\Helpers\AppLocator; use OC\IntegrityCheck\Helpers\AppLocator;
@ -490,9 +494,25 @@ class MigrationService {
} }
} }
$thing = $table->getPrimaryKey(); $primaryKey = $table->getPrimaryKey();
if ($thing && (\strlen($table->getName()) > 26 || \strlen($thing->getName()) > 30)) { if ($primaryKey instanceof Index) {
throw new \InvalidArgumentException('Primary index name on "' . $table->getName() . '" is too long.'); $indexName = strtolower($primaryKey->getName());
$isUsingDefaultName = $indexName === 'primary';
if ($this->connection->getDatabasePlatform() instanceof PostgreSqlPlatform) {
$defaultName = $table->getName() . '_' . implode('_', $primaryKey->getColumns()) . '_seq';
$isUsingDefaultName = strtolower($defaultName) === $indexName;
} else if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
$defaultName = $table->getName() . '_seq';
$isUsingDefaultName = strtolower($defaultName) === $indexName;
}
if (!$isUsingDefaultName && \strlen($indexName) > 30) {
throw new \InvalidArgumentException('Primary index name on "' . $table->getName() . '" is too long.');
}
if ($isUsingDefaultName && \strlen($table->getName()) > 26) {
throw new \InvalidArgumentException('Primary index name on "' . $table->getName() . '" is too long.');
}
} }
} }

View File

@ -10,6 +10,8 @@
namespace Test\DB; namespace Test\DB;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Index;
@ -271,12 +273,57 @@ class MigrationsTest extends \Test\TestCase {
public function testEnsureOracleIdentifierLengthLimitValidWithPrimaryKey() { public function testEnsureOracleIdentifierLengthLimitValidWithPrimaryKey() {
$index = $this->createMock(Index::class); $index = $this->createMock(Index::class);
$index->expects($this->once()) $index->expects($this->any())
->method('getName') ->method('getName')
->willReturn(\str_repeat('a', 30)); ->willReturn(\str_repeat('a', 30));
$table = $this->createMock(Table::class); $table = $this->createMock(Table::class);
$table->expects($this->exactly(2)) $table->expects($this->any())
->method('getName')
->willReturn(\str_repeat('a', 26));
$table->expects($this->once())
->method('getColumns')
->willReturn([]);
$table->expects($this->once())
->method('getIndexes')
->willReturn([]);
$table->expects($this->once())
->method('getForeignKeys')
->willReturn([]);
$table->expects($this->once())
->method('getPrimaryKey')
->willReturn($index);
$schema = $this->createMock(Schema::class);
$schema->expects($this->once())
->method('getTables')
->willReturn([$table]);
$schema->expects($this->once())
->method('getSequences')
->willReturn([]);
self::invokePrivate($this->migrationService, 'ensureOracleIdentifierLengthLimit', [$schema]);
}
public function testEnsureOracleIdentifierLengthLimitValidWithPrimaryKeyDefault() {
$defaultName = 'PRIMARY';
if ($this->db->getDatabasePlatform() instanceof PostgreSqlPlatform) {
$defaultName = \str_repeat('a', 26) . '_' . \str_repeat('b', 30) . '_seq';
} else if ($this->db->getDatabasePlatform() instanceof OraclePlatform) {
$defaultName = \str_repeat('a', 26) . '_seq';
}
$index = $this->createMock(Index::class);
$index->expects($this->any())
->method('getName')
->willReturn($defaultName);
$index->expects($this->any())
->method('getColumns')
->willReturn([\str_repeat('b', 30)]);
$table = $this->createMock(Table::class);
$table->expects($this->any())
->method('getName') ->method('getName')
->willReturn(\str_repeat('a', 26)); ->willReturn(\str_repeat('a', 26));
@ -325,10 +372,20 @@ class MigrationsTest extends \Test\TestCase {
* @expectedException \InvalidArgumentException * @expectedException \InvalidArgumentException
*/ */
public function testEnsureOracleIdentifierLengthLimitTooLongPrimaryWithDefault() { public function testEnsureOracleIdentifierLengthLimitTooLongPrimaryWithDefault() {
$defaultName = 'PRIMARY';
if ($this->db->getDatabasePlatform() instanceof PostgreSqlPlatform) {
$defaultName = \str_repeat('a', 27) . '_' . \str_repeat('b', 30) . '_seq';
} else if ($this->db->getDatabasePlatform() instanceof OraclePlatform) {
$defaultName = \str_repeat('a', 27) . '_seq';
}
$index = $this->createMock(Index::class); $index = $this->createMock(Index::class);
$index->expects($this->any()) $index->expects($this->any())
->method('getName') ->method('getName')
->willReturn(\str_repeat('a', 30)); ->willReturn($defaultName);
$index->expects($this->any())
->method('getColumns')
->willReturn([\str_repeat('b', 30)]);
$table = $this->createMock(Table::class); $table = $this->createMock(Table::class);
$table->expects($this->any()) $table->expects($this->any())