2017-12-14 10:37:11 -05:00
< ? php
2019-12-03 13:57:53 -05:00
2018-05-24 04:37:33 -04:00
declare ( strict_types = 1 );
2019-12-03 13:57:53 -05:00
2017-12-14 10:37:11 -05:00
/**
2024-05-24 13:43:47 -04:00
* SPDX - FileCopyrightText : 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX - License - Identifier : AGPL - 3.0 - or - later
2017-12-14 10:37:11 -05:00
*/
namespace OC\Core\Command\Db ;
2021-01-03 09:28:31 -05:00
use OC\DB\Connection ;
2017-12-14 10:37:11 -05:00
use OC\DB\SchemaWrapper ;
2023-07-14 04:34:09 -04:00
use OCP\DB\Events\AddMissingIndicesEvent ;
use OCP\EventDispatcher\IEventDispatcher ;
2017-12-14 10:37:11 -05:00
use Symfony\Component\Console\Command\Command ;
use Symfony\Component\Console\Input\InputInterface ;
2023-11-23 04:22:34 -05:00
use Symfony\Component\Console\Input\InputOption ;
2017-12-14 10:37:11 -05:00
use Symfony\Component\Console\Output\OutputInterface ;
2017-12-15 04:45:00 -05:00
/**
* Class AddMissingIndices
*
* if you added any new indices to the database , this is the right place to add
2020-03-11 07:29:52 -04:00
* your update routine for existing instances
2017-12-15 04:45:00 -05:00
*
* @ package OC\Core\Command\Db
*/
class AddMissingIndices extends Command {
2023-06-12 10:37:03 -04:00
public function __construct (
private Connection $connection ,
2023-07-19 18:05:59 -04:00
private IEventDispatcher $dispatcher ,
2023-06-12 10:37:03 -04:00
) {
2017-12-14 10:37:11 -05:00
parent :: __construct ();
}
protected function configure () {
$this
2017-12-15 04:45:00 -05:00
-> setName ( 'db:add-missing-indices' )
2022-02-21 12:32:17 -05:00
-> setDescription ( 'Add missing indices to the database tables' )
2024-08-23 09:10:27 -04:00
-> addOption ( 'dry-run' , null , InputOption :: VALUE_NONE , 'Output the SQL queries instead of running them.' );
2017-12-14 10:37:11 -05:00
}
2020-06-26 08:54:51 -04:00
protected function execute ( InputInterface $input , OutputInterface $output ) : int {
2023-07-14 04:34:09 -04:00
$dryRun = $input -> getOption ( 'dry-run' );
2018-05-24 04:37:33 -04:00
// Dispatch event so apps can also update indexes if needed
2023-07-14 04:34:09 -04:00
$event = new AddMissingIndicesEvent ();
2023-07-19 18:05:59 -04:00
$this -> dispatcher -> dispatchTyped ( $event );
2023-07-14 04:34:09 -04:00
$missingIndices = $event -> getMissingIndices ();
2024-01-30 09:07:17 -05:00
$toReplaceIndices = $event -> getIndicesToReplace ();
if ( $missingIndices !== [] || $toReplaceIndices !== []) {
2023-07-14 04:34:09 -04:00
$schema = new SchemaWrapper ( $this -> connection );
foreach ( $missingIndices as $missingIndex ) {
if ( $schema -> hasTable ( $missingIndex [ 'tableName' ])) {
$table = $schema -> getTable ( $missingIndex [ 'tableName' ]);
if ( ! $table -> hasIndex ( $missingIndex [ 'indexName' ])) {
$output -> writeln ( '<info>Adding additional ' . $missingIndex [ 'indexName' ] . ' index to the ' . $table -> getName () . ' table, this can take some time...</info>' );
2023-07-19 17:19:35 -04:00
if ( $missingIndex [ 'dropUnnamedIndex' ]) {
foreach ( $table -> getIndexes () as $index ) {
$columns = $index -> getColumns ();
if ( $columns === $missingIndex [ 'columns' ]) {
$table -> dropIndex ( $index -> getName ());
}
}
}
if ( $missingIndex [ 'uniqueIndex' ]) {
$table -> addUniqueIndex ( $missingIndex [ 'columns' ], $missingIndex [ 'indexName' ], $missingIndex [ 'options' ]);
} else {
$table -> addIndex ( $missingIndex [ 'columns' ], $missingIndex [ 'indexName' ], [], $missingIndex [ 'options' ]);
}
2024-01-30 09:07:17 -05:00
if ( ! $dryRun ) {
$this -> connection -> migrateToSchema ( $schema -> getWrappedSchema ());
2023-07-14 04:34:09 -04:00
}
$output -> writeln ( '<info>' . $table -> getName () . ' table updated successfully.</info>' );
}
}
}
2024-01-30 09:07:17 -05:00
foreach ( $toReplaceIndices as $toReplaceIndex ) {
if ( $schema -> hasTable ( $toReplaceIndex [ 'tableName' ])) {
$table = $schema -> getTable ( $toReplaceIndex [ 'tableName' ]);
2025-03-12 08:05:37 -04:00
if ( $table -> hasIndex ( $toReplaceIndex [ 'newIndexName' ])) {
2024-01-30 09:07:17 -05:00
continue ;
}
$output -> writeln ( '<info>Adding additional ' . $toReplaceIndex [ 'newIndexName' ] . ' index to the ' . $table -> getName () . ' table, this can take some time...</info>' );
if ( $toReplaceIndex [ 'uniqueIndex' ]) {
$table -> addUniqueIndex ( $toReplaceIndex [ 'columns' ], $toReplaceIndex [ 'newIndexName' ], $toReplaceIndex [ 'options' ]);
} else {
$table -> addIndex ( $toReplaceIndex [ 'columns' ], $toReplaceIndex [ 'newIndexName' ], [], $toReplaceIndex [ 'options' ]);
}
if ( ! $dryRun ) {
$this -> connection -> migrateToSchema ( $schema -> getWrappedSchema ());
}
foreach ( $toReplaceIndex [ 'oldIndexNames' ] as $oldIndexName ) {
2025-03-12 08:05:37 -04:00
if ( $table -> hasIndex ( $oldIndexName )) {
$output -> writeln ( '<info>Removing ' . $oldIndexName . ' index from the ' . $table -> getName () . ' table</info>' );
$table -> dropIndex ( $oldIndexName );
}
2024-01-30 09:07:17 -05:00
}
if ( ! $dryRun ) {
$this -> connection -> migrateToSchema ( $schema -> getWrappedSchema ());
}
$output -> writeln ( '<info>' . $table -> getName () . ' table updated successfully.</info>' );
}
}
if ( $dryRun ) {
$sqlQueries = $this -> connection -> migrateToSchema ( $schema -> getWrappedSchema (), $dryRun );
if ( $sqlQueries !== null ) {
$output -> writeln ( $sqlQueries );
}
}
2023-07-14 04:34:09 -04:00
}
2020-06-26 08:54:51 -04:00
return 0 ;
2017-12-15 04:45:00 -05:00
}
2017-12-14 10:37:11 -05:00
}