AddMissingIndices.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
  5. *
  6. * @author Bjoern Schiessle <bjoern@schiessle.org>
  7. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  8. * @author Joas Schilling <coding@schilljs.com>
  9. * @author Julius Härtl <jus@bitgrid.net>
  10. * @author Mario Danic <mario@lovelyhq.com>
  11. * @author Morris Jobke <hey@morrisjobke.de>
  12. * @author Robin Appelman <robin@icewind.nl>
  13. * @author Roeland Jago Douma <roeland@famdouma.nl>
  14. * @author Thomas Citharel <nextcloud@tcit.fr>
  15. *
  16. * @license GNU AGPL version 3 or any later version
  17. *
  18. * This program is free software: you can redistribute it and/or modify
  19. * it under the terms of the GNU Affero General Public License as
  20. * published by the Free Software Foundation, either version 3 of the
  21. * License, or (at your option) any later version.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU Affero General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU Affero General Public License
  29. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  30. *
  31. */
  32. namespace OC\Core\Command\Db;
  33. use OC\DB\Connection;
  34. use OC\DB\SchemaWrapper;
  35. use OCP\DB\Events\AddMissingIndicesEvent;
  36. use OCP\EventDispatcher\IEventDispatcher;
  37. use Symfony\Component\Console\Command\Command;
  38. use Symfony\Component\Console\Input\InputInterface;
  39. use Symfony\Component\Console\Input\InputOption;
  40. use Symfony\Component\Console\Output\OutputInterface;
  41. /**
  42. * Class AddMissingIndices
  43. *
  44. * if you added any new indices to the database, this is the right place to add
  45. * your update routine for existing instances
  46. *
  47. * @package OC\Core\Command\Db
  48. */
  49. class AddMissingIndices extends Command {
  50. public function __construct(
  51. private Connection $connection,
  52. private IEventDispatcher $dispatcher,
  53. ) {
  54. parent::__construct();
  55. }
  56. protected function configure() {
  57. $this
  58. ->setName('db:add-missing-indices')
  59. ->setDescription('Add missing indices to the database tables')
  60. ->addOption('dry-run', null, InputOption::VALUE_NONE, "Output the SQL queries instead of running them.");
  61. }
  62. protected function execute(InputInterface $input, OutputInterface $output): int {
  63. $dryRun = $input->getOption('dry-run');
  64. // Dispatch event so apps can also update indexes if needed
  65. $event = new AddMissingIndicesEvent();
  66. $this->dispatcher->dispatchTyped($event);
  67. $missingIndices = $event->getMissingIndices();
  68. if ($missingIndices !== []) {
  69. $schema = new SchemaWrapper($this->connection);
  70. foreach ($missingIndices as $missingIndex) {
  71. if ($schema->hasTable($missingIndex['tableName'])) {
  72. $table = $schema->getTable($missingIndex['tableName']);
  73. if (!$table->hasIndex($missingIndex['indexName'])) {
  74. $output->writeln('<info>Adding additional ' . $missingIndex['indexName'] . ' index to the ' . $table->getName() . ' table, this can take some time...</info>');
  75. if ($missingIndex['dropUnnamedIndex']) {
  76. foreach ($table->getIndexes() as $index) {
  77. $columns = $index->getColumns();
  78. if ($columns === $missingIndex['columns']) {
  79. $table->dropIndex($index->getName());
  80. }
  81. }
  82. }
  83. if ($missingIndex['uniqueIndex']) {
  84. $table->addUniqueIndex($missingIndex['columns'], $missingIndex['indexName'], $missingIndex['options']);
  85. } else {
  86. $table->addIndex($missingIndex['columns'], $missingIndex['indexName'], [], $missingIndex['options']);
  87. }
  88. $sqlQueries = $this->connection->migrateToSchema($schema->getWrappedSchema(), $dryRun);
  89. if ($dryRun && $sqlQueries !== null) {
  90. $output->writeln($sqlQueries);
  91. }
  92. $output->writeln('<info>' . $table->getName() . ' table updated successfully.</info>');
  93. }
  94. }
  95. }
  96. }
  97. return 0;
  98. }
  99. }