2020-03-11 07:29:52 -04:00
< ? php
declare ( strict_types = 1 );
/**
* @ copyright Copyright ( c ) 2020 Joas Schilling < coding @ schilljs . com >
*
2021-06-04 15:52:51 -04:00
* @ author Christoph Wurst < christoph @ winzerhof - wurst . at >
2020-03-11 07:29:52 -04:00
* @ author Joas Schilling < coding @ schilljs . com >
*
* @ license GNU AGPL version 3 or any later version
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2021-06-04 15:52:51 -04:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2020-03-11 07:29:52 -04:00
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
*
*/
namespace OC\Core\Command\Db ;
2021-01-03 09:28:31 -05:00
use OC\DB\Connection ;
2020-03-11 07:29:52 -04:00
use OC\DB\SchemaWrapper ;
2023-07-19 16:36:59 -04:00
use OCP\DB\Events\AddMissingColumnsEvent ;
use OCP\DB\Types ;
use OCP\EventDispatcher\IEventDispatcher ;
2020-03-11 07:29:52 -04:00
use OCP\IDBConnection ;
use Symfony\Component\Console\Command\Command ;
use Symfony\Component\Console\Input\InputInterface ;
2022-02-21 12:32:17 -05:00
use Symfony\Component\Console\Input\InputOption ;
2020-03-11 07:29:52 -04:00
use Symfony\Component\Console\Output\OutputInterface ;
use Symfony\Component\EventDispatcher\EventDispatcherInterface ;
use Symfony\Component\EventDispatcher\GenericEvent ;
/**
* Class AddMissingColumns
*
* if you added a new lazy column to the database , this is the right place to add
* your update routine for existing instances
*
* @ package OC\Core\Command\Db
*/
class AddMissingColumns extends Command {
2023-06-12 10:37:03 -04:00
public function __construct (
private Connection $connection ,
2023-07-19 16:36:59 -04:00
private EventDispatcherInterface $legacyDispatcher ,
private IEventDispatcher $dispatcher ,
2023-06-12 10:37:03 -04:00
) {
2020-03-11 07:29:52 -04:00
parent :: __construct ();
}
protected function configure () {
$this
-> setName ( 'db:add-missing-columns' )
2022-02-21 12:32:17 -05:00
-> setDescription ( 'Add missing optional columns to the database tables' )
-> addOption ( 'dry-run' , null , InputOption :: VALUE_NONE , " Output the SQL queries instead of running them. " );
2020-03-11 07:29:52 -04:00
}
2020-06-26 08:54:51 -04:00
protected function execute ( InputInterface $input , OutputInterface $output ) : int {
2023-07-19 16:36:59 -04:00
$dryRun = $input -> getOption ( 'dry-run' );
$updated = $this -> addCoreColumns ( $output , $dryRun );
2020-03-11 07:29:52 -04:00
// Dispatch event so apps can also update columns if needed
$event = new GenericEvent ( $output );
2023-07-19 16:36:59 -04:00
$this -> legacyDispatcher -> dispatch ( IDBConnection :: ADD_MISSING_COLUMNS_EVENT , $event );
$event = new AddMissingColumnsEvent ();
$this -> dispatcher -> dispatchTyped ( $event );
$missingColumns = $event -> getMissingColumns ();
if ( ! empty ( $missingColumns )) {
$schema = new SchemaWrapper ( $this -> connection );
foreach ( $missingColumns as $missingColumn ) {
if ( $schema -> hasTable ( $missingColumn [ 'tableName' ])) {
$table = $schema -> getTable ( $missingColumn [ 'tableName' ]);
if ( ! $table -> hasColumn ( $missingColumn [ 'columnName' ])) {
$output -> writeln ( '<info>Adding additional ' . $missingColumn [ 'columnName' ] . ' column to the ' . $missingColumn [ 'tableName' ] . ' table, this can take some time...</info>' );
$table -> addColumn ( $missingColumn [ 'columnName' ], $missingColumn [ 'typeName' ], $missingColumn [ 'options' ]);
$sqlQueries = $this -> connection -> migrateToSchema ( $schema -> getWrappedSchema (), $dryRun );
if ( $dryRun && $sqlQueries !== null ) {
$output -> writeln ( $sqlQueries );
}
$updated = true ;
$output -> writeln ( '<info>' . $missingColumn [ 'tableName' ] . ' table updated successfully.</info>' );
}
}
}
}
if ( ! $updated ) {
$output -> writeln ( '<info>Done.</info>' );
}
2020-06-26 08:54:51 -04:00
return 0 ;
2020-03-11 07:29:52 -04:00
}
/**
2023-07-19 16:36:59 -04:00
* Add missing column for core tables
2020-03-11 07:29:52 -04:00
*
* @ param OutputInterface $output
2022-02-21 12:32:17 -05:00
* @ param bool $dryRun If true , will return the sql queries instead of running them .
2023-07-19 16:36:59 -04:00
* @ return bool True when the schema changed
2020-03-11 07:29:52 -04:00
* @ throws \Doctrine\DBAL\Schema\SchemaException
*/
2023-07-19 16:36:59 -04:00
private function addCoreColumns ( OutputInterface $output , bool $dryRun ) : bool {
2020-03-11 07:29:52 -04:00
$output -> writeln ( '<info>Check columns of the comments table.</info>' );
$schema = new SchemaWrapper ( $this -> connection );
$updated = false ;
if ( $schema -> hasTable ( 'comments' )) {
$table = $schema -> getTable ( 'comments' );
if ( ! $table -> hasColumn ( 'reference_id' )) {
$output -> writeln ( '<info>Adding additional reference_id column to the comments table, this can take some time...</info>' );
2023-07-19 16:36:59 -04:00
$table -> addColumn ( 'reference_id' , Types :: STRING , [
2020-03-11 07:29:52 -04:00
'notnull' => false ,
'length' => 64 ,
]);
2022-02-21 12:32:17 -05:00
$sqlQueries = $this -> connection -> migrateToSchema ( $schema -> getWrappedSchema (), $dryRun );
if ( $dryRun && $sqlQueries !== null ) {
$output -> writeln ( $sqlQueries );
}
2020-03-11 07:29:52 -04:00
$updated = true ;
$output -> writeln ( '<info>Comments table updated successfully.</info>' );
}
}
2023-07-19 16:36:59 -04:00
return $updated ;
2020-03-11 07:29:52 -04:00
}
}