Skip to content

Commit

Permalink
Add smwgEntityCollation to upgrade key matrix, refs 3095 (#4713)
Browse files Browse the repository at this point in the history
  • Loading branch information
mwjames committed Apr 12, 2020
1 parent b4f58dc commit 00c8413
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 30 deletions.
1 change: 1 addition & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,7 @@
"smw-pendingtasks-intro": "This page provides information about tasks that have been classified as pending, incomplete, or outstanding in connection with Semantic MediaWiki.",
"smw-pendingtasks-setup-no-tasks-intro": "The installation (or upgrade) has been completed, currently there are no pending or outstanding tasks.",
"smw-pendingtasks-tab-setup": "Setup",
"smw-updateentitycollation-incomplete": "The <code>[https://www.semantic-mediawiki.org/wiki/Help:$smwgEntityCollation $smwgEntityCollation]</code> setting was recently altered and requires that the <code>[https://www.semantic-mediawiki.org/wiki/Help:updateEntityCollation.php updateEntityCollation.php]</code> script is executed so that entities are updated and contain the correct sort field value.",
"smw-updateentitycountmap-incomplete": "The <code>smw_countmap</code> field was added in a recent release and requires that the <code>[https://www.semantic-mediawiki.org/wiki/Help:updateEntityCountMap.php updateEntityCountMap.php]</code> script is executed so that functions can access the content of this field.",
"smw-populatehashfield-incomplete": "The <code>smw_hash</code> field population was skipped during the setup, the <code>[https://www.semantic-mediawiki.org/wiki/Help:populateHashField.php populateHashField.php] </code>script is required to be executed.",
"smw-install-incomplete-populate-hash-field": "The <code>smw_hash</code> field population was skipped during the setup, the <code>[https://www.semantic-mediawiki.org/wiki/Help:populateHashField.php populateHashField.php]</code> script is required to be executed.",
Expand Down
2 changes: 1 addition & 1 deletion i18n/local/setupcheck.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"en": "<a href='https://www.semantic-mediawiki.org/'>Semantic MediaWiki</a> was installed and enabled but is missing an appropriate <a href='https://www.semantic-mediawiki.org/wiki/Help:Upgrade_key'>upgrade key</a>."
},
"smw-setupcheck-reason-for-invalid-upgrade-key": {
"en": "Semantic MediaWiki's internal database structure has changed and requires some adjustments to be fully functional. There can be several reasons including:<ul><li>Additional fixed properties (requires additional table setup) were added</li><li>Changes to tables or indices making an interception obligatory before accessing the data</li><li>Changes to the storage or query engine</li></ul>"
"en": "Semantic MediaWiki's internal database structure has changed and requires some adjustments to be fully functional. There can be several reasons including:<ul><li>Changes to the list of fixed properties and may require additional table(s)</li><li>Changes to the overall table structure or indices requirements</li><li>Changes to the selected storage or query engine</li><li>Changes to the required <a href='https://www.semantic-mediawiki.org/wiki/Entity_collation'>entity collation</a></li></ul>"
},
"smw-setupcheck-registry-enablesemantics-conflict": {
"en": "<code>LocalSettings.php</code> contains both <code>enableSemantics</code> and <code>wfLoadExtension( 'SemanticMediaWiki' )</code> forcing the ExtensionRegistry to abort the registration process."
Expand Down
44 changes: 21 additions & 23 deletions maintenance/updateEntityCollation.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
use SMWDataItem as DataItem;
use SMW\Exception\PredefinedPropertyLabelMismatchException;
use SMW\Setup;
use SMW\SetupFile;
use SMW\Utils\CliMsgFormatter;
use SMW\MediaWiki\HookDispatcher;
use Onoi\MessageReporter\MessageReporter;
use SMW\Maintenance\MaintenanceCheck;

/**
* Load the required class
Expand All @@ -31,6 +33,11 @@
*/
class updateEntityCollation extends \Maintenance {

/**
* Incomplete task message
*/
const ENTITY_COLLATION_INCOMPLETE = 'smw-updateentitycollation-incomplete';

/**
* @var Store
*/
Expand Down Expand Up @@ -89,12 +96,13 @@ public function reportMessage( $message ) {
*/
public function execute() {

if ( $this->canExecute() !== true ) {
exit;
if ( ( $maintenanceCheck = new MaintenanceCheck() )->canExecute() === false ) {
exit ( $maintenanceCheck->getMessage() );
}

$applicationFactory = ApplicationFactory::getInstance();
$maintenanceFactory = $applicationFactory->newMaintenanceFactory();
$setupFile = $applicationFactory->singleton( 'SetupFile' );

$this->store = $applicationFactory->getStore(
SQLStore::class
Expand Down Expand Up @@ -151,12 +159,20 @@ public function execute() {
);

$this->messageReporter->reportMessage(
$cliMsgFormatter->twoCols( "... `smw_sort` field records ...", "$count (rows)", 3 )
$cliMsgFormatter->twoCols( "... found `smw_sort` field records ...", "$count (rows)", 3 )
);

$this->runUpdate( $rows, $count );
$this->messageReporter->reportMessage( "\n ... done.\n" );

$setupFile->removeIncompleteTask( self::ENTITY_COLLATION_INCOMPLETE );

$setupFile->set(
[
SetupFile::ENTITY_COLLATION => $smwgEntityCollation
]
);

$this->hookDispatcher->onAfterUpdateEntityCollationComplete( $this->store, $this->messageReporter );
}

Expand All @@ -179,7 +195,7 @@ private function informAboutDifferences( $smwgEntityCollation, $wgCategoryCollat
);

$this->messageReporter->reportMessage(
$cliMsgFormatter->oneCol( 'Settings ...' )
$cliMsgFormatter->oneCol( 'Collation settings ...' )
);

$this->messageReporter->reportMessage(
Expand Down Expand Up @@ -224,24 +240,6 @@ private function fetchRows() {
);
}

private function canExecute() {

if ( !Setup::isEnabled() ) {
return $this->messageReporter->reportMessage(
"\nYou need to have SMW enabled in order to run the maintenance script!\n"
);
}

if ( !Setup::isValid( true ) ) {
return $this->messageReporter->reportMessage(
"\nYou need to run `update.php` or `setupStore.php` first before continuing\n" .
"with this maintenance task!\n"
);
}

return true;
}

private function runUpdate( $rows, $count ) {

$tableFieldUpdater = new TableFieldUpdater(
Expand Down Expand Up @@ -272,7 +270,7 @@ private function runUpdate( $rows, $count ) {
$progress = $cliMsgFormatter->progressCompact( ++$i, $count, $row->smw_id, $this->lastId );

$this->messageReporter->reportMessage(
$cliMsgFormatter->twoColsOverride( "... updating field (current/last) ...", $progress, 3 )
$cliMsgFormatter->twoColsOverride( "... updating entity (current/last) ...", $progress, 3 )
);

$tableFieldUpdater->updateSortField( $row->smw_id, $search );
Expand Down
94 changes: 94 additions & 0 deletions src/SQLStore/TableBuilder/Examiner/EntityCollation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace SMW\SQLStore\TableBuilder\Examiner;

use Onoi\MessageReporter\MessageReporterAwareTrait;
use SMW\SQLStore\SQLStore;
use SMW\SQLStore\TableBuilder;
use SMW\SetupFile;
use SMW\Maintenance\updateEntityCollation as UpdateEntityCollation;
use SMW\Utils\CliMsgFormatter;

/**
* @license GNU GPL v2+
* @since 3.2
*
* @author mwjames
*/
class EntityCollation {

use MessageReporterAwareTrait;

/**
* @var SQLStore
*/
private $store;

/**
* @var SetupFile
*/
private $setupFile;

/**
* @var string
*/
private $entityCollation = '';

/**
* @since 3.2
*
* @param SQLStore $store
*/
public function __construct( SQLStore $store ) {
$this->store = $store;
}

/**
* @since 3.2
*
* @param SetupFile $setupFile
*/
public function setSetupFile( SetupFile $setupFile ) {
$this->setupFile = $setupFile;
}

/**
* @since 3.2
*
* @param string $entityCollation
*/
public function setEntityCollation( string $entityCollation ) {
$this->entityCollation = $entityCollation;
}

/**
* @since 3.2
*/
public function check() {

$cliMsgFormatter = new CliMsgFormatter();

$this->messageReporter->reportMessage(
$cliMsgFormatter->firstCol( "Checking entity collation type ..." )
);

$entityCollation = $this->setupFile->get( SetupFile::ENTITY_COLLATION ) ?? 'identity';

if ( $this->entityCollation !== $entityCollation ) {

$this->messageReporter->reportMessage(
"\n ... adding incomplete task for entity collation conversion ...\n"
);

$this->setupFile->addIncompleteTask( UpdateEntityCollation::ENTITY_COLLATION_INCOMPLETE );

} else {
$this->messageReporter->reportMessage(
$cliMsgFormatter->secondCol( CliMsgFormatter::OK )
);
}

$this->messageReporter->reportMessage( " ... done.\n" );
}

}
7 changes: 7 additions & 0 deletions src/SQLStore/TableBuilder/TableBuildExaminer.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ public function checkOnPostCreation( ITableBuilder $tableBuilder ) {
$countMapField->setMessageReporter( $this->messageReporter );
$countMapField->check( $tableBuilder->getLog() );

$entityCollation = $this->tableBuildExaminerFactory->newEntityCollation(
$this->store
);

$entityCollation->setMessageReporter( $this->messageReporter );
$entityCollation->check();

// Call out for RDBMS specific implementations
$tableBuilder->checkOn( TableBuilder::POST_CREATION );
}
Expand Down
27 changes: 27 additions & 0 deletions src/SQLStore/TableBuilder/TableBuildExaminerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use SMW\SQLStore\TableBuilder\Examiner\IdBorder;
use SMW\SQLStore\TableBuilder\Examiner\PredefinedProperties;
use SMW\SQLStore\TableBuilder\Examiner\CountMapField;
use SMW\SQLStore\TableBuilder\Examiner\EntityCollation;

/**
* @private
Expand All @@ -21,6 +22,32 @@
*/
class TableBuildExaminerFactory {

/**
* @since 3.2
*
* @param SQLStore $store
*
* @return EntityCollation
*/
public function newEntityCollation( SQLStore $store ) : EntityCollation {

$servicesFactory = ServicesFactory::getInstance();

$entityCollation = new EntityCollation(
$store
);

$entityCollation->setSetupFile(
$servicesFactory->singleton( 'SetupFile' )
);

$entityCollation->setEntityCollation(
$servicesFactory->getSettings()->get( 'smwgEntityCollation' )
);

return $entityCollation;
}

/**
* @since 3.2
*
Expand Down
15 changes: 15 additions & 0 deletions src/SetupFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class SetupFile {
*/
const DB_REQUIREMENTS = 'db_requirements';

/**
* Describes the entity collection setting
*/
const ENTITY_COLLATION = 'entity_collation';

/**
* Key that describes the date of the last table optimization run.
*/
Expand Down Expand Up @@ -503,6 +508,11 @@ public function write( array $args, array $vars ) {
}
}

/**
* Listed keys will have a "global" impact of how data are stored, formatted,
* or represented in Semantic MediaWiki. In most cases it will require an action
* from an adminstrator when one of those keys are altered.
*/
private static function makeKey( $vars ) {

// Only recognize those properties that require a fixed table
Expand Down Expand Up @@ -531,6 +541,11 @@ private static function makeKey( $vars ) {
$pageSpecialProperties
];

// Only add the key when it is different from the default setting
if ( $vars['smwgEntityCollation'] !== 'identity' ) {
$components += [ 'smwgEntityCollation' => $vars['smwgEntityCollation'] ];
}

if ( $vars['smwgFieldTypeFeatures'] !== false ) {
$components += [ 'smwgFieldTypeFeatures' => $vars['smwgFieldTypeFeatures'] ];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace SMW\Tests\SQLStore\TableBuilder\Examiner;

use SMW\SQLStore\TableBuilder\Examiner\CountMapField;
use SMW\Tests\TestEnvironment;
use SMW\Tests\PHPUnitCompat;

/**
* @covers \SMW\SQLStore\TableBuilder\Examiner\CountMapField
* @group semantic-mediawiki
*
* @license GNU GPL v2+
* @since 3.2
*
* @author mwjames
*/
class CountMapFieldTest extends \PHPUnit_Framework_TestCase {

use PHPUnitCompat;

private $spyMessageReporter;
private $store;
private $setupFile;

protected function setUp() : void {
parent::setUp();
$this->spyMessageReporter = TestEnvironment::getUtilityFactory()->newSpyMessageReporter();

$this->connection = $this->getMockBuilder( '\SMW\MediaWiki\Database' )
->disableOriginalConstructor()
->getMock();

$this->store = $this->getMockBuilder( '\SMW\SQLStore\SQLStore' )
->disableOriginalConstructor()
->getMock();

$this->store->expects( $this->any() )
->method( 'getConnection' )
->will( $this->returnValue( $this->connection ) );

$this->setupFile = $this->getMockBuilder( '\SMW\SetupFile' )
->disableOriginalConstructor()
->getMock();
}

public function testCanConstruct() {

$this->assertInstanceOf(
CountMapField::class,
new CountMapField( $this->store )
);
}

public function testCheck_NewFieldTriggerIncompleteTask() {

$this->connection->expects( $this->once() )
->method( 'tableName' )
->will( $this->returnValue( 'smw_objects_aux' ) );

$instance = new CountMapField(
$this->store
);

$instance->setMessageReporter( $this->spyMessageReporter );
$instance->setSetupFile( $this->setupFile );
$instance->check( [ 'smw_objects_aux' => [ 'smw_countmap' => 'field.new' ] ]);

$this->assertContains(
'adding incomplete task for `smw_countmap` conversion',
$this->spyMessageReporter->getMessagesAsString()
);
}

public function testCheckOk() {

$instance = new CountMapField(
$this->store
);

$instance->setMessageReporter( $this->spyMessageReporter );
$instance->setSetupFile( $this->setupFile );
$instance->check();

$this->assertContains(
'Checking smw_countmap field consistency',
$this->spyMessageReporter->getMessagesAsString()
);
}

}
Loading

0 comments on commit 00c8413

Please sign in to comment.