88
99namespace OCA \Polls \Db \V10 ;
1010
11+ use Doctrine \DBAL \Schema \Exception \IndexAlreadyExists ;
1112use Doctrine \DBAL \Schema \Exception \IndexDoesNotExist ;
1213use Exception ;
1314use OCA \Polls \Migration \V10 \TableSchema ;
@@ -359,7 +360,7 @@ public function createIndex(string $tableName, string $indexName, array $columns
359360
360361 // Check by name: if a named index already exists, verify its columns
361362 if ($ hasName && $ table ->hasIndex ($ indexName )) {
362- if ($ this ->columnsMatch ($ table ->getIndex ($ indexName )->getColumns (), $ columns )) {
363+ if ($ this ->columnsMatch ($ table ->getIndex ($ indexName )->getUnquotedColumns (), $ columns )) {
363364 // Named index with same columns already exists, skip creation and return success message
364365 return ucfirst ($ type ) . ' ' . $ indexName . ' with correct configuration already exists in ' . $ tableName . '. Skip creation. ' ;
365366 }
@@ -370,7 +371,7 @@ public function createIndex(string $tableName, string $indexName, array $columns
370371
371372 // Check by columns: look further for any existing index with same uniqueness and same columns
372373 foreach ($ table ->getIndexes () as $ index ) {
373- if ($ index ->isUnique () === $ unique && $ this ->columnsMatch ($ index ->getColumns (), $ columns )) {
374+ if ($ index ->isUnique () === $ unique && $ this ->columnsMatch ($ index ->getUnquotedColumns (), $ columns )) {
374375 if (!$ hasName ) {
375376 // If index is unnamed and index with matching configuraton is found, skip creation and return success message
376377 return ucfirst ($ type ) . ' for ' . json_encode ($ columns ) . ' already exists as ' . $ index ->getName () . ' in ' . $ tableName ;
@@ -382,11 +383,36 @@ public function createIndex(string $tableName, string $indexName, array $columns
382383 }
383384 }
384385
385- // now create the new index, either, because it did not exist at all, or because the existing one(s) were dropped due to mismatch
386- if ($ unique ) {
387- $ table ->addUniqueIndex ($ columns , $ hasName ? $ indexName : null );
388- } else {
389- $ table ->addIndex ($ columns , $ hasName ? $ indexName : null );
386+ // now create the new index, either, because it did not exist at all, or
387+ // because the existing one(s) were dropped due to mismatch
388+ try {
389+ if ($ unique ) {
390+ $ table ->addUniqueIndex ($ columns , $ hasName ? $ indexName : null );
391+ } else {
392+ $ table ->addIndex ($ columns , $ hasName ? $ indexName : null );
393+ }
394+ } catch (IndexAlreadyExists ) {
395+ // Catch Exception and treat the index as existing
396+ // Especially catches pgsql error in situations, where the prior
397+ // check did not detect the existing index
398+
399+ // Let's add some details about the existing indices to the log
400+ // collect expected and actual index configurations
401+ $ indexDump = [];
402+ foreach ($ table ->getIndexes () as $ idx ) {
403+ $ indexDump [] = $ idx ->getName () . '[ ' . implode (', ' , $ idx ->getColumns ()) . '] ' . ($ idx ->isUnique () ? ' UNIQUE ' : '' );
404+ }
405+
406+ // Log the exception with details about the existing indices as a warning log entry
407+ $ this ->logger ->warning (
408+ 'IndexAlreadyExists caught for {table}: expected columns {expected}, existing indices: {indices} ' ,
409+ [
410+ 'table ' => $ prefixedTable ,
411+ 'expected ' => json_encode ($ columns ),
412+ 'indices ' => implode (' | ' , $ indexDump ),
413+ ]
414+ );
415+ return ucfirst ($ type ) . ' for ' . json_encode ($ columns ) . ' already exists in ' . $ tableName . ' (detected via exception). Skip creation. ' ;
390416 }
391417 $ message [] = 'Added ' . $ type . ' ' . ($ hasName ? $ indexName : '(auto) ' ) . ' for ' . json_encode ($ columns ) . ' to ' . $ tableName ;
392418
0 commit comments