You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(DB): support up to 63 character long table and index names
We do not support Oracle 11 anymore but at least Oracle 12c (12.2).
So the limitation is gone (Oracle now supports up to 128 character long
names).
Instead we are now limited by MySQL (64 characters) and PostgreSQL (63
characters).
Signed-off-by: Ferdinand Thiessen <[email protected]>
@@ -531,12 +535,108 @@ public function executeStep($version, $schemaOnly = false) {
531
535
}
532
536
533
537
/**
538
+
* Enforces some naming conventions to make sure tables can be used on all supported database engines.
539
+
*
534
540
* Naming constraints:
535
-
* - Tables names must be 30 chars or shorter (27 + oc_ prefix)
536
-
* - Column names must be 30 chars or shorter
537
-
* - Index names must be 30 chars or shorter
538
-
* - Sequence names must be 30 chars or shorter
539
-
* - Primary key names must be set or the table name 23 chars or shorter
541
+
* - Tables names must be 63 chars or shorter (including its prefix (default 'oc_'))
542
+
* - Column names must be 63 chars or shorter
543
+
* - Index names must be 63 chars or shorter
544
+
* - Sequence names must be 63 chars or shorter
545
+
* - Primary key names must be set to 63 chars or shorts - or the table name must be <= 56 characters (63 - 5 for '_pKey' suffix) including the tablename prefix
546
+
*
547
+
* This is based on the identifier limits set by our supported database engines:
548
+
* - MySQL and MariaDB support 64 characters
549
+
* - Oracle supports 128 characters (since 12.2 (12c) before it was 30)
if (\strlen($table->getName()) + $prefixLength > $MAX_NAME_LENGTH) {
567
+
thrownew \InvalidArgumentException('Table name "' . $table->getName() . '" exceeds the maximum length of ' . $MAX_NAME_LENGTH);
568
+
}
569
+
$sourceTable = null;
570
+
}
571
+
572
+
foreach ($table->getColumns() as$thing) {
573
+
// If the table doesn't exist OR if the column doesn't exist in the table
574
+
if ((!$sourceTableinstanceof Table || !$sourceTable->hasColumn($thing->getName()))
575
+
&& \strlen($thing->getName()) > $MAX_NAME_LENGTH
576
+
) {
577
+
thrownew \InvalidArgumentException('Column name "' . $table->getName() . '"."' . $thing->getName() . '" exceeds the maximum length of ' . $MAX_NAME_LENGTH);
578
+
}
579
+
}
580
+
581
+
foreach ($table->getIndexes() as$thing) {
582
+
if ((!$sourceTableinstanceof Table || !$sourceTable->hasIndex($thing->getName()))
583
+
&& \strlen($thing->getName()) > $MAX_NAME_LENGTH
584
+
) {
585
+
thrownew \InvalidArgumentException('Index name "' . $table->getName() . '"."' . $thing->getName() . '" exceeds the maximum length of ' . $MAX_NAME_LENGTH);
586
+
}
587
+
}
588
+
589
+
foreach ($table->getForeignKeys() as$thing) {
590
+
if ((!$sourceTableinstanceof Table || !$sourceTable->hasForeignKey($thing->getName()))
591
+
&& \strlen($thing->getName()) > $MAX_NAME_LENGTH
592
+
) {
593
+
thrownew \InvalidArgumentException('Foreign key name "' . $table->getName() . '"."' . $thing->getName() . '" exceeds the maximum length of ' . $MAX_NAME_LENGTH);
594
+
}
595
+
}
596
+
597
+
$primaryKey = $table->getPrimaryKey();
598
+
// only check if there is a primary key
599
+
// and there was non in the old table or there was no old table
thrownew \InvalidArgumentException('Column "' . $table->getName() . '"."' . $thing->getName() . '" is NotNull, but has empty string or null as default.');
663
+
if (!$sourceTableinstanceof Table || !$sourceTable->hasColumn($column->getName())) {
664
+
if ($column->getNotnull() && $column->getDefault() === ''
// null and empty string are the same on Oracle SQL
667
+
thrownew \InvalidArgumentException('Column "' . $table->getName() . '"."' . $column->getName() . '" is NotNull, but has empty string or null as default.');
578
668
}
579
669
580
-
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
670
+
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE
thrownew \InvalidArgumentException('Column "' . $table->getName() . '"."' . $thing->getName() . '" is type String, but exceeding the 4.000 length limit.');
597
-
}
598
-
}
599
-
600
-
foreach ($table->getIndexes() as$thing) {
601
-
if ((!$sourceTableinstanceof Table || !$sourceTable->hasIndex($thing->getName())) && \strlen($thing->getName()) > 30) {
602
-
thrownew \InvalidArgumentException('Index name "' . $table->getName() . '"."' . $thing->getName() . '" is too long.');
603
-
}
604
-
}
605
-
606
-
foreach ($table->getForeignKeys() as$thing) {
607
-
if ((!$sourceTableinstanceof Table || !$sourceTable->hasForeignKey($thing->getName())) && \strlen($thing->getName()) > 30) {
608
-
thrownew \InvalidArgumentException('Foreign key name "' . $table->getName() . '"."' . $thing->getName() . '" is too long.');
thrownew \InvalidArgumentException('Column "' . $table->getName() . '"."' . $column->getName() . '" is type String, but exceeding the 4.000 length limit.');
609
690
}
610
691
}
611
692
@@ -628,26 +709,13 @@ public function ensureOracleConstraints(Schema $sourceSchema, Schema $targetSche
$logger->error('Table "' . $table->getName() . '" has no primary key and therefor will not behave sane in clustered setups. This will throw an exception and not be installable in a future version of Nextcloud.');
642
716
// throw new \InvalidArgumentException('Table "' . $table->getName() . '" has no primary key and therefor will not behave sane in clustered setups.');
643
717
}
644
718
}
645
-
646
-
foreach ($sequencesas$sequence) {
647
-
if (!$sourceSchema->hasSequence($sequence->getName()) && \strlen($sequence->getName()) > 30) {
648
-
thrownew \InvalidArgumentException('Sequence name "' . $sequence->getName() . '" is too long.');
0 commit comments