Mwjames has uploaded a new change for review. https://gerrit.wikimedia.org/r/133949
Change subject: Clean-up ...................................................................... Clean-up Functionality is unaltered while the PR focuses on: - Minimize static use - Use composition where possible - Rename some classes to be more expressive - Limit BagOStuff/MediaWiki dependency to GlossaryCache only - Added MwDBSQLStoreIntegrationTest to test a "real" DB/Store integration Change-Id: Id0e0e1c19afc3aceb06fe75f2d5892cd2a065f34 --- M README.md M SemanticGlossary.php M maintenance/rebuildGlossaryCache.php A src/Cache/CacheInvalidator.php M src/Cache/ElementsCacheBuilder.php A src/Cache/GlossaryCache.php D src/CacheHelper.php D src/CacheInvalidator.php M src/LingoBackendAdapter.php M src/Maintenance/GlossaryCacheRebuilder.php M src/PropertyRegistry.php R src/SemanticDataComparator.php M tests/bootstrap.php R tests/phpunit/Cache/CacheInvalidatorTest.php M tests/phpunit/Cache/ElementsCacheBuilderTest.php A tests/phpunit/Cache/GlossaryCacheTest.php D tests/phpunit/CacheHelperTest.php M tests/phpunit/ConfigurationIntegrityTest.php M tests/phpunit/Maintenance/GlossaryCacheRebuilderTest.php A tests/phpunit/MwDBSQLStoreIntegrationTest.php R tests/phpunit/SemanticDataComparatorTest.php 21 files changed, 565 insertions(+), 389 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticGlossary refs/changes/49/133949/1 diff --git a/README.md b/README.md index 4982fc6..9702c58 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Semantic Glossary -[![Latest Stable Version](https://poser.pugx.org/mediawiki/semantic-glossary/version.png)](https://packagist.org/packages/mediawiki/chameleon-skin) -[![Packagist download count](https://poser.pugx.org/mediawiki/semantic-glossary/d/total.png)](https://packagist.org/packages/mediawiki/chameleon-skin) -[![Dependency Status](https://www.versioneye.com/php/mediawiki:semantic-glossary/badge.png)](https://www.versioneye.com/php/mediawiki:chameleon-skin) +[![Latest Stable Version](https://poser.pugx.org/mediawiki/semantic-glossary/version.png)](https://packagist.org/packages/mediawiki/semantic-glossary) +[![Packagist download count](https://poser.pugx.org/mediawiki/semantic-glossary/d/total.png)](https://packagist.org/packages/mediawiki/semantic-glossary) +[![Dependency Status](https://www.versioneye.com/php/mediawiki:semantic-glossary/badge.png)](https://www.versioneye.com/php/mediawiki:semantic-glossary) The [Semantic Glossary][mw-semantic-glossary] (a.k.a SG) is a [Semantic MediaWiki][smw] extension where terms and abbreviations can be defined using semantic properties. @@ -10,6 +10,7 @@ - PHP 5.3.2 or later - MediaWiki 1.20 or later - [Lingo extension][mw-lingo] 1.0 or later +- [Semantic MediaWiki][smw] 1.9 or later ## Installation diff --git a/SemanticGlossary.php b/SemanticGlossary.php index 511b7e6..68ff876 100644 --- a/SemanticGlossary.php +++ b/SemanticGlossary.php @@ -57,12 +57,12 @@ // register class files with the Autoloader $autoloadClasses = array( 'SG\PropertyRegistry' => $dir . '/src/PropertyRegistry.php', - 'SG\CacheInvalidator' => $dir . '/src/CacheInvalidator.php', - 'SG\CacheHelper' => $dir . '/src/CacheHelper.php', - 'SG\DataComparator' => $dir . '/src/DataComparator.php', 'SG\Maintenance\GlossaryCacheRebuilder' => $dir . '/src/Maintenance/GlossaryCacheRebuilder.php', - 'SG\LingoBackendAdapter' => $dir . '/src/LingoBackendAdapter.php', - 'SG\Cache\ElementsCacheBuilder' => $dir . '/src/Cache/ElementsCacheBuilder.php' + 'SG\LingoBackendAdapter' => $dir . '/src/LingoBackendAdapter.php', + 'SG\SemanticDataComparator' => $dir . '/src/SemanticDataComparator.php', + 'SG\Cache\ElementsCacheBuilder' => $dir . '/src/Cache/ElementsCacheBuilder.php', + 'SG\Cache\CacheInvalidator' => $dir . '/src/Cache/CacheInvalidator.php', + 'SG\Cache\GlossaryCache' => $dir . '/src/Cache/GlossaryCache.php', ); $GLOBALS[ 'wgAutoloadClasses' ] = array_merge( $GLOBALS[ 'wgAutoloadClasses' ], $autoloadClasses ); @@ -87,7 +87,7 @@ * @since 1.0 */ $GLOBALS['wgHooks']['SMWStore::updateDataBefore'][] = function ( SMWStore $store, SMWSemanticData $semanticData ) { - return \SG\CacheInvalidator::getInstance()->invalidateCacheOnStoreUpdate( $store, $semanticData ); + return \SG\Cache\CacheInvalidator::getInstance()->invalidateCacheOnStoreUpdate( $store, $semanticData ); }; /** @@ -96,7 +96,7 @@ * @since 1.0 */ $GLOBALS['wgHooks']['smwDeleteSemanticData'][] = function ( SMWDIWikiPage $subject ) { - return \SG\CacheInvalidator::getInstance()->invalidateCacheOnPageDelete( smwfGetStore(), $subject ); + return \SG\Cache\CacheInvalidator::getInstance()->invalidateCacheOnPageDelete( smwfGetStore(), $subject ); }; /** @@ -105,7 +105,7 @@ * @since 1.0 */ $GLOBALS['wgHooks']['TitleMoveComplete'][] = function ( &$old_title, &$new_title, &$user, $pageid, $redirid ) { - return \SG\CacheInvalidator::getInstance()->invalidateCacheOnPageMove( $old_title ); + return \SG\Cache\CacheInvalidator::getInstance()->invalidateCacheOnPageMove( $old_title ); }; } ); diff --git a/maintenance/rebuildGlossaryCache.php b/maintenance/rebuildGlossaryCache.php index d58a118..dc62c81 100644 --- a/maintenance/rebuildGlossaryCache.php +++ b/maintenance/rebuildGlossaryCache.php @@ -3,7 +3,7 @@ namespace SG\Maintenance; use SG\Maintenance\GlossaryCacheRebuilder; -use SG\CacheHelper; +use SG\Cache\GlossaryCache; use SMW\StoreFactory; @@ -18,6 +18,7 @@ * php rebuildGlossaryCache.php [options...] * * @ingroup SG + * @ingroup SemanticGlossary * @ingroup Maintenance * * @license GNU GPL v2+ @@ -54,7 +55,7 @@ $glossaryCacheRebuilder = new GlossaryCacheRebuilder( StoreFactory::getStore(), - CacheHelper::getCache(), + new GlossaryCache(), array( $this, 'reportMessage' ) ); diff --git a/src/Cache/CacheInvalidator.php b/src/Cache/CacheInvalidator.php new file mode 100644 index 0000000..abe2955 --- /dev/null +++ b/src/Cache/CacheInvalidator.php @@ -0,0 +1,178 @@ +<?php + +namespace SG\Cache; + +use SG\SemanticDataComparator; +use SG\PropertyRegistry; + +use SMW\Store; +use SMW\SemanticData; +use SMW\DIWikiPage; +use SMW\DIProperty; + +use LingoParser; + +use Title; + +/** + * @ingroup SG + * @ingroup SemanticGlossary + * + * @license GNU GPL v2+ + * @since 1.0 + * + * @author Stephan Gambke + * @author mwjames + */ +class CacheInvalidator { + + protected static $instance = null; + + /* @var GlossaryCache */ + protected $cache = null; + + /** + * @since 1.0 + * + * @return CacheInvalidator + */ + public static function getInstance() { + + if ( self::$instance === null ) { + + $instance = new self(); + $instance->setCache( new GlossaryCache() ); + + self::$instance = $instance; + } + + return self::$instance; + } + + /** + * @since 1.0 + */ + public static function clear() { + self::$instance = null; + } + + /** + * @since 1.0 + * + * @param GlossaryCache $glossaryCache + */ + public function setCache( GlossaryCache $glossaryCache ) { + $this->glossaryCache = $glossaryCache; + } + + /** + * @since 1.0 + * + * @param Store $store + * @param SemanticData $semanticData + * + * @return boolean + */ + public function invalidateCacheOnStoreUpdate( Store $store, SemanticData $semanticData ) { + + wfProfileIn( __METHOD__ ); + + $this->matchAllSubobjects( $store, $semanticData ); + + if ( $this->hasSemanticDataDeviation( $store, $semanticData ) ) { + $this->purgeCache( $semanticData->getSubject() ); + LingoParser::purgeCache(); + } + + wfProfileOut( __METHOD__ ); + return true; + } + + /** + * @since 1.0 + * + * @param Store $store + * @param DIWikiPage $subject + * @param boolean|true $purgeLingo + * + * @return boolean + */ + public function invalidateCacheOnPageDelete( Store $store, DIWikiPage $subject, $purgeLingo = true ) { + + wfProfileIn( __METHOD__ ); + + $this->matchSubobjectsToSubject( $store, $subject ); + $this->purgeCache( $subject ); + + if ( $purgeLingo ) { + LingoParser::purgeCache(); + } + + wfProfileOut( __METHOD__ ); + return true; + } + + /** + * @since 1.0 + * + * @param Title $title + * + * @return boolean + */ + public function invalidateCacheOnPageMove( Title $title ) { + $this->purgeCache( DIWikiPage::newFromTitle( $title ) ); + return true; + } + + protected function matchAllSubobjects( Store $store, SemanticData $semanticData ) { + + $properties = $semanticData->getProperties(); + + if ( array_key_exists( DIProperty::TYPE_SUBOBJECT, $properties ) ) { + foreach ( $semanticData->getPropertyValues( $properties[ DIProperty::TYPE_SUBOBJECT ] ) as $subobject ) { + $this->invalidateCacheOnStoreUpdate( + $store, + $semanticData->findSubSemanticData( $subobject->getSubobjectName() ), + false + ); + } + } + } + + protected function matchSubobjectsToSubject( Store $store, DIWikiPage $subject ) { + + $properties = $store->getProperties( $subject ); + + if ( array_key_exists( DIProperty::TYPE_SUBOBJECT, $properties ) ) { + foreach ( $store->getPropertyValues( $subject, $properties[ DIProperty::TYPE_SUBOBJECT ] ) as $subobject ) { + $this->invalidateCacheOnPageDelete( + $store, + $subobject->getSubject(), + false + ); + } + } + } + + protected function hasSemanticDataDeviation( Store $store, SemanticData $semanticData ) { + + $dataComparator = new SemanticDataComparator( $store, $semanticData ); + + return $dataComparator->byPropertyId( PropertyRegistry::SG_TERM ) || + $dataComparator->byPropertyId( PropertyRegistry::SG_DEFINITION ) || + $dataComparator->byPropertyId( PropertyRegistry::SG_LINK ) || + $dataComparator->byPropertyId( PropertyRegistry::SG_STYLE ); + } + + protected function purgeCache( DIWikiPage $subject ) { + wfProfileIn( __METHOD__ ); + + $this->glossaryCache->getCache()->delete( + $this->glossaryCache->getKeyForSubject( $subject ) + ); + + wfProfileOut( __METHOD__ ); + return true; + } + +} diff --git a/src/Cache/ElementsCacheBuilder.php b/src/Cache/ElementsCacheBuilder.php index a036123..ed201b8 100644 --- a/src/Cache/ElementsCacheBuilder.php +++ b/src/Cache/ElementsCacheBuilder.php @@ -2,19 +2,20 @@ namespace SG\Cache; -use SG\CacheHelper; +use SG\Cache\GlossaryCache; +use SG\PropertyRegistry; -use SMWStore; -use SMWDIProperty; -use SMWStringValue; -use SMWPrintRequest; -use SMWPropertyValue; -use SMWThingDescription; -use SMWSomeProperty; -use SMWQuery; +use SMW\Store; +use SMW\DIProperty; + +use SMWStringValue as StringValue; +use SMWPrintRequest as PrintRequest; +use SMWPropertyValue as PropertyValue; +use SMWThingDescription as ThingDescription; +use SMWSomeProperty as SomeProperty; +use SMWQuery as Query; + use LingoElement; - -use BagOStuff; /** * @ingroup SG @@ -31,8 +32,8 @@ /* @var Store */ protected $store; - /* @var BagOStuff */ - protected $cache; + /* @var GlossaryCache */ + protected $glossaryCache; protected $mDiTerm; protected $mDiDefinition; @@ -50,15 +51,11 @@ * @since 1.1 * * @param SMWStore $store - * @param BagOStuff|null $cache + * @param GlossaryCache $cache */ - public function __construct( SMWStore $store, BagOStuff $cache = null ) { + public function __construct( Store $store, GlossaryCache $glossaryCache ) { $this->store = $store; - $this->cache = $cache; - - if ( $this->cache === null ) { - $this->cache = CacheHelper::getCache(); - } + $this->glossaryCache = $glossaryCache; } /** @@ -82,8 +79,8 @@ next( $this->queryResults ); - $cachekey = CacheHelper::getKey( $page ); - $cachedResult = $this->cache->get( $cachekey ); + $cachekey = $this->glossaryCache->getKeyForSubject( $page ); + $cachedResult = $this->glossaryCache->getCache()->get( $cachekey ); // cache hit? if ( $cachedResult !== false && $cachedResult !== null ) { @@ -103,7 +100,7 @@ ); wfDebug( "Cached glossary entry $cachekey.\n" ); - $this->cache->set( $cachekey, $ret ); + $this->glossaryCache->getCache()->set( $cachekey, $ret ); } } @@ -132,49 +129,49 @@ protected function buildQuery() { // build term data item and data value for later use - $this->mDiTerm = new SMWDIProperty( '___glt' ); - $this->mDvTerm = new SMWStringValue( '_str' ); + $this->mDiTerm = new DIProperty( PropertyRegistry::SG_TERM ); + $this->mDvTerm = new StringValue( '_str' ); $this->mDvTerm->setProperty( $this->mDiTerm ); - $pvTerm = new SMWPropertyValue( '__pro' ); + $pvTerm = new PropertyValue( '__pro' ); $pvTerm->setDataItem( $this->mDiTerm ); - $prTerm = new SMWPrintRequest( SMWPrintRequest::PRINT_PROP, null, $pvTerm ); + $prTerm = new PrintRequest( PrintRequest::PRINT_PROP, null, $pvTerm ); // build definition data item and data value for later use - $this->mDiDefinition = new SMWDIProperty( '___gld' ); - $this->mDvDefinition = new SMWStringValue( '_txt' ); + $this->mDiDefinition = new DIProperty( PropertyRegistry::SG_DEFINITION ); + $this->mDvDefinition = new StringValue( '_txt' ); $this->mDvDefinition->setProperty( $this->mDiDefinition ); - $pvDefinition = new SMWPropertyValue( '__pro' ); + $pvDefinition = new PropertyValue( '__pro' ); $pvDefinition->setDataItem( $this->mDiDefinition ); - $prDefinition = new SMWPrintRequest( SMWPrintRequest::PRINT_PROP, null, $pvDefinition ); + $prDefinition = new PrintRequest( PrintRequest::PRINT_PROP, null, $pvDefinition ); // build link data item and data value for later use - $this->mDiLink = new SMWDIProperty( '___gll' ); - $this->mDvLink = new SMWStringValue( '_str' ); + $this->mDiLink = new DIProperty( PropertyRegistry::SG_LINK ); + $this->mDvLink = new StringValue( '_str' ); $this->mDvLink->setProperty( $this->mDiLink ); - $pvLink = new SMWPropertyValue( '__pro' ); + $pvLink = new PropertyValue( '__pro' ); $pvLink->setDataItem( $this->mDiLink ); - $prLink = new SMWPrintRequest( SMWPrintRequest::PRINT_PROP, null, $pvLink ); + $prLink = new PrintRequest( PrintRequest::PRINT_PROP, null, $pvLink ); // build style data item and data value for later use - $this->mDiStyle = new SMWDIProperty( '___gls' ); - $this->mDvStyle = new SMWStringValue( '_txt' ); + $this->mDiStyle = new DIProperty( PropertyRegistry::SG_STYLE ); + $this->mDvStyle = new StringValue( '_txt' ); $this->mDvStyle->setProperty( $this->mDiStyle ); - $pvStyle = new SMWPropertyValue( '__pro' ); + $pvStyle = new PropertyValue( '__pro' ); $pvStyle->setDataItem( $this->mDiStyle ); - $prStyle = new SMWPrintRequest( SMWPrintRequest::PRINT_PROP, null, $pvStyle ); + $prStyle = new PrintRequest( PrintRequest::PRINT_PROP, null, $pvStyle ); // Create query - $desc = new SMWSomeProperty( new SMWDIProperty( '___glt' ), new SMWThingDescription() ); + $desc = new SomeProperty( new DIProperty( '___glt' ), new ThingDescription() ); $desc->addPrintRequest( $prTerm ); $desc->addPrintRequest( $prDefinition ); $desc->addPrintRequest( $prLink ); $desc->addPrintRequest( $prStyle ); - $query = new SMWQuery( $desc, false, false ); + $query = new Query( $desc, false, false ); $query->sort = true; $query->sortkeys['___glt'] = 'ASC'; diff --git a/src/Cache/GlossaryCache.php b/src/Cache/GlossaryCache.php new file mode 100644 index 0000000..bb36cfb --- /dev/null +++ b/src/Cache/GlossaryCache.php @@ -0,0 +1,84 @@ +<?php + +namespace SG\Cache; + +use SMW\DIWikiPage; + +use ObjectCache; +use BagOStuff; + +/** + * @ingroup SG + * @ingroup SemanticGlossary + * + * @license GNU GPL v2+ + * @since 1.0 + * + * @author mwjames + */ +class GlossaryCache { + + /* @var BagOstuff */ + protected $cache = null; + + /** + * @since 1.1 + * + * @param BagOStuff|null $cache + */ + public function __construct( BagOStuff $cache = null ) { + $this->cache = $cache; + } + + /** + * @since 1.0 + * + * @return BagOStuff + */ + public function getCache() { + + if ( $this->cache === null ) { + $this->cache = ObjectCache::getInstance( self::getCacheType() ); + } + + return $this->cache; + } + + /** + * @since 1.0 + * + * @param DIWikiPage $subject + * + * @return string + */ + public static function getKeyForSubject( DIWikiPage $subject ) { + // FIXME Remove wfMemcKey dep. + return wfMemcKey( 'ext', 'semanticglossary', $subject->getSerialization() ); + } + + /** + * @since 1.1 + * + * @return string + */ + public static function getKeyForLingo() { + // FIXME Remove wfMemcKey dep. + // This key should come from something like LingoCache::getKey() + return wfMemcKey( 'ext', 'lingo', 'lingotree' ); + } + + /** + * @since 1.0 + * + * @return string + */ + public static function getCacheType() { + + if ( isset( $GLOBAL['wgexLingoCacheType'] ) && $GLOBAL['wgexLingoCacheType'] !== null ) { + return $GLOBAL['wgexLingoCacheType']; + } + + return $GLOBALS['wgMainCacheType']; + } + +} diff --git a/src/CacheHelper.php b/src/CacheHelper.php deleted file mode 100644 index 8042ba1..0000000 --- a/src/CacheHelper.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -namespace SG; - -use ObjectCache; -use BagOStuff; - -/** - * @ingroup SG - * - * @licence GNU GPL v2+ - * @since 1.0 - * - * @author mwjames - */ -class CacheHelper { - - /** - * @since 1.0 - * - * @return BagOStuff - */ - public static function getCache() { - return ObjectCache::getInstance( self::getCacheType() ); - } - - /** - * @since 1.0 - * - * @param SMWDIWikiPage $subject - * - * @return string - */ - public static function getKey( \SMWDIWikiPage $subject ) { - // FIXME Remove wfMemcKey dep. - - return wfMemcKey( 'ext', 'semanticglossary', $subject->getSerialization() ); - } - - /** - * @since 1.0 - * - * @return string - */ - public static function getCacheType() { - - if ( isset( $GLOBAL['wgexLingoCacheType'] ) && $GLOBAL['wgexLingoCacheType'] !== null ) { - return $GLOBAL['wgexLingoCacheType']; - } - - return $GLOBALS['wgMainCacheType']; - } - -} diff --git a/src/CacheInvalidator.php b/src/CacheInvalidator.php deleted file mode 100644 index 30b8aa7..0000000 --- a/src/CacheInvalidator.php +++ /dev/null @@ -1,165 +0,0 @@ -<?php - -namespace SG; - -use LingoParser; -use BagOStuff; -use Title; - -/** - * @ingroup SG - * - * @licence GNU GPL v2+ - * @since 1.0 - * - * @author Stephan Gambke - * @author mwjames - */ -class CacheInvalidator { - - protected static $instance = null; - protected $cache = null; - - /** - * @since 1.0 - * - * @return CacheInvalidator - */ - public static function getInstance() { - - if ( self::$instance === null ) { - - $instance = new self(); - $instance->setCache( CacheHelper::getCache() ); - - self::$instance = $instance; - } - - return self::$instance; - } - - /** - * @since 1.0 - */ - public static function clear() { - self::$instance = null; - } - - /** - * @since 1.0 - * - * @param BagOStuff $cache - */ - public function setCache( BagOStuff $cache ) { - $this->cache = $cache; - } - - /** - * @since 1.0 - * - * @param Store $store - * @param SemanticData $semanticData - * - * @return boolean - */ - public function invalidateCacheOnStoreUpdate( \SMWStore $store, \SMWSemanticData $semanticData ) { - - wfProfileIn( __METHOD__ ); - - $this->matchAllSubobjects( $store, $semanticData ); - - if ( $this->hasSemanticDataDeviation( $store, $semanticData ) ) { - $this->purgeCache( $semanticData->getSubject() ); - LingoParser::purgeCache(); - } - - wfProfileOut( __METHOD__ ); - return true; - } - - /** - * @since 1.0 - * - * @param SMWStore $store - * @param SMWDIWikiPage $subject - * @param boolean|true $purgeLingo - * - * @return boolean - */ - public function invalidateCacheOnPageDelete( \SMWStore $store, \SMWDIWikiPage $subject, $purgeLingo = true ) { - - wfProfileIn( __METHOD__ ); - - $this->matchSubobjectsToSubject( $store, $subject ); - $this->purgeCache( $subject ); - - if ( $purgeLingo ) { - LingoParser::purgeCache(); - } - - wfProfileOut( __METHOD__ ); - return true; - } - - /** - * @since 1.0 - * - * @param Title $title - * - * @return boolean - */ - public function invalidateCacheOnPageMove( Title $title ) { - $this->purgeCache( \SMWDIWikiPage::newFromTitle( $title ) ); - return true; - } - - protected function matchAllSubobjects( \SMWStore $store, \SMWSemanticData $semanticData ) { - - $properties = $semanticData->getProperties(); - - if ( array_key_exists( '_SOBJ', $properties ) ) { - foreach ( $semanticData->getPropertyValues( $properties['_SOBJ'] ) as $subobject ) { - $this->invalidateCacheOnStoreUpdate( - $store, - $semanticData->findSubSemanticData( $subobject->getSubobjectName() ), - false - ); - } - } - } - - protected function matchSubobjectsToSubject( \SMWStore $store, \SMWDIWikiPage $subject ) { - - $properties = $store->getProperties( $subject ); - - if ( array_key_exists( '_SOBJ', $properties ) ) { - foreach ( $store->getPropertyValues( $subject, $properties['_SOBJ'] ) as $subobject ) { - $this->invalidateCacheOnPageDelete( - $store, - $subobject->getSubject(), - false - ); - } - } - } - - protected function hasSemanticDataDeviation( \SMWStore $store, \SMWSemanticData $semanticData ) { - - $dataComparator = new DataComparator( $store, $semanticData ); - - return $dataComparator->byPropertyId( PropertyRegistry::SG_TERM ) || - $dataComparator->byPropertyId( PropertyRegistry::SG_DEFINITION ) || - $dataComparator->byPropertyId( PropertyRegistry::SG_LINK ) || - $dataComparator->byPropertyId( PropertyRegistry::SG_STYLE ); - } - - protected function purgeCache( \SMWDIWikiPage $subject ) { - wfProfileIn( __METHOD__ ); - - $this->cache->delete( CacheHelper::getKey( $subject ) ); - - wfProfileOut( __METHOD__ ); - return true; - } - -} diff --git a/src/LingoBackendAdapter.php b/src/LingoBackendAdapter.php index ff77715..6fcf764 100644 --- a/src/LingoBackendAdapter.php +++ b/src/LingoBackendAdapter.php @@ -3,6 +3,9 @@ namespace SG; use SG\Cache\ElementsCacheBuilder; +use SG\Cache\GlossaryCache; + +use SMW\StoreFactory; use LingoBackend; use LingoMessageLog; @@ -18,7 +21,7 @@ */ class LingoBackendAdapter extends LingoBackend { - /* ElementsCacheBuilder */ + /* @var ElementsCacheBuilder */ protected $elementsCacheBuilder = null; protected $elements = array(); @@ -34,7 +37,10 @@ $this->elementsCacheBuilder = $elementsCacheBuilder; if ( $this->elementsCacheBuilder === null ) { - $this->elementsCacheBuilder = new ElementsCacheBuilder( smwfGetStore() ); + $this->elementsCacheBuilder = new ElementsCacheBuilder( + StoreFactory::getStore(), + new GlossaryCache() + ); } } diff --git a/src/Maintenance/GlossaryCacheRebuilder.php b/src/Maintenance/GlossaryCacheRebuilder.php index 1e78f24..acee4f6 100644 --- a/src/Maintenance/GlossaryCacheRebuilder.php +++ b/src/Maintenance/GlossaryCacheRebuilder.php @@ -3,7 +3,7 @@ namespace SG\Maintenance; use SG\PropertyRegistry; -use SG\CacheHelper; +use SG\Cache\GlossaryCache; use SMWUpdateJob as UpdateJob; use SMW\Store; @@ -12,8 +12,6 @@ use SMWSomeProperty as SomeProperty; use SMWDIProperty as DIProperty; use SMWThingDescription as ThingDescription; - -use BagOStuff; /** * Part of the `rebuildGlossaryCache.php` maintenance script @@ -30,8 +28,8 @@ /** @var Store */ protected $store; - /** @var BagOStuff */ - protected $cache; + /** @var GlossaryCache */ + protected $glossaryCache; protected $reporter = null; protected $rebuildCount = 0; @@ -41,12 +39,12 @@ * @since 1.1 * * @param Store $store - * @param BagOStuff $cache + * @param GlossaryCache $glossaryCache * @param $reporter */ - public function __construct( Store $store, BagOStuff $cache, $reporter = null ) { + public function __construct( Store $store, GlossaryCache $glossaryCache, $reporter = null ) { $this->store = $store; - $this->cache = $cache; + $this->glossaryCache = $glossaryCache; $this->reporter = $reporter; // Should be a MessageReporter instance } @@ -138,11 +136,12 @@ protected function removeEntitiesFromCache( array $pages ) { - // FIXME Need access to the key from a method, this is a hack - $this->cache->delete( wfMemcKey( 'ext', 'lingo', 'lingotree' ) ); + $cache = $this->glossaryCache->getCache(); + + $cache->delete( $this->glossaryCache->getKeyForLingo() ); foreach ( $pages as $page ) { - $this->cache->delete( CacheHelper::getKey( $page ) ); + $cache->delete( $this->glossaryCache->getKeyForSubject( $page ) ); } $this->reportMessage( "\n" . ( count( $pages ) + 1 ) . " cache entities deleted.\n\n" ); diff --git a/src/PropertyRegistry.php b/src/PropertyRegistry.php index 99181df..977a77f 100644 --- a/src/PropertyRegistry.php +++ b/src/PropertyRegistry.php @@ -6,8 +6,9 @@ /** * @ingroup SG + * @ingroup SemanticGlossary * - * @licence GNU GPL v2+ + * @license GNU GPL v2+ * @since 1.0 * * @author mwjames diff --git a/src/DataComparator.php b/src/SemanticDataComparator.php similarity index 84% rename from src/DataComparator.php rename to src/SemanticDataComparator.php index ed32da7..cc59e84 100644 --- a/src/DataComparator.php +++ b/src/SemanticDataComparator.php @@ -2,26 +2,34 @@ namespace SG; +use SMW\Store; +use SMW\SemanticData; +use SMW\DIProperty; + /** * @ingroup SG + * @ingroup SemanticGlossary * - * @licence GNU GPL v2+ + * @license GNU GPL v2+ * @since 1.0 * * @author Stephan Gambke */ -class DataComparator { +class SemanticDataComparator { + /* @var Store */ protected $store = null; + + /* @var SemanticData */ protected $semanticData = null; /** * @since 1.0 * - * @param SMWStore $store - * @param SMWSemanticData $semanticData + * @param Store $store + * @param SemanticData $semanticData */ - public function __construct( \SMWStore $store, \SMWSemanticData $semanticData ) { + public function __construct( Store $store, SemanticData $semanticData ) { $this->store = $store; $this->semanticData = $semanticData; } @@ -69,7 +77,7 @@ $newEntries = array(); $oldEntries = $this->store->getPropertyValues( $this->semanticData->getSubject(), - new \SMWDIProperty( $propertId ) + new DIProperty( $propertId ) ); return array( diff --git a/tests/bootstrap.php b/tests/bootstrap.php index b5fde31..3c627e7 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -30,6 +30,10 @@ $autoLoader->addPsr4( 'SG\\Tests\\', __DIR__ . '/phpunit' ); + $autoLoader->addClassMap( array( + 'SG\Maintenance\RebuildGlossaryCache' => __DIR__ . '/../maintenance/rebuildGlossaryCache.php', + ) ); + return true; } diff --git a/tests/phpunit/CacheInvalidatorTest.php b/tests/phpunit/Cache/CacheInvalidatorTest.php similarity index 63% rename from tests/phpunit/CacheInvalidatorTest.php rename to tests/phpunit/Cache/CacheInvalidatorTest.php index 199db32..f99f12b 100644 --- a/tests/phpunit/CacheInvalidatorTest.php +++ b/tests/phpunit/Cache/CacheInvalidatorTest.php @@ -1,10 +1,10 @@ <?php -namespace SG\Tests; +namespace SG\Tests\Cache; use SG\PropertyRegistry; -use SG\CacheInvalidator; -use SG\CacheHelper; +use SG\Cache\CacheInvalidator; +use SG\Cache\GlossaryCache; use SMW\Subobject; use SMW\SemanticData; @@ -16,14 +16,15 @@ use Title; /** - * @covers \SG\CacheInvalidator + * @covers \SG\Cache\CacheInvalidator * * @ingroup Test * * @group SG * @group SGExtension + * @group extension-semantic-glossary * - * @licence GNU GPL v2+ + * @license GNU GPL v2+ * @since 1.0 * * @author mwjames @@ -32,21 +33,25 @@ public function testCanConstruct() { CacheInvalidator::clear(); - $this->assertInstanceOf( '\SG\CacheInvalidator', CacheInvalidator::getInstance() ); + + $this->assertInstanceOf( + '\SG\Cache\CacheInvalidator', + CacheInvalidator::getInstance() + ); } public function testInvalidateOnUpdateWithEmptyData() { - $store = $this->getMockBuilder( 'SMWStore' ) + $store = $this->getMockBuilder( '\SMW\Store' ) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $semanticData = $this->getMockBuilder( 'SMWSemanticData' ) + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $instance = new CacheInvalidator; - $instance->setCache( new HashBagOStuff ); + $instance = new CacheInvalidator(); + $instance->setCache( new GlossaryCache( new HashBagOStuff() ) ); $this->assertTrue( $instance->invalidateCacheOnStoreUpdate( $store, $semanticData ) ); } @@ -78,25 +83,28 @@ $subobject->getContainer() ); - $itemId = CacheHelper::getKey( $subobject->getSemanticData()->getSubject() ); + $glossaryCache = new GlossaryCache( new HashBagOStuff() ); - $cache = new HashBagOStuff; - $cache->set( $itemId, 'preset.cacheitem' ); + $itemId = $glossaryCache->getKeyForSubject( + $subobject->getSemanticData()->getSubject() + ); - $instance = new CacheInvalidator; - $instance->setCache( $cache ); + $glossaryCache->getCache()->set( $itemId, 'preset.cacheitem' ); + + $instance = new CacheInvalidator(); + $instance->setCache( $glossaryCache ); $this->assertTrue( $instance->invalidateCacheOnStoreUpdate( $store, $semanticData ) ); $this->assertFalse( - $cache->get( $itemId ), + $glossaryCache->getCache()->get( $itemId ), 'Asserts that the preset item has been removed from cache' ); } public function testInvalidateOnDeleteWithEmptyData() { - $subject = \SMWDIWikiPage::newFromTitle( \Title::newFromText( __METHOD__ ) ); + $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ); $store = $this->getMockBuilder( 'SMWStore' ) ->disableOriginalConstructor() @@ -107,17 +115,17 @@ ->with( $this->equalTo( $subject ) ) ->will( $this->returnValue( array() ) ); - $instance = new CacheInvalidator; - $instance->setCache( new HashBagOStuff ); + $instance = new CacheInvalidator(); + $instance->setCache( new GlossaryCache( new HashBagOStuff() ) ); $this->assertTrue( $instance->invalidateCacheOnPageDelete( $store, $subject ) ); } public function testInvalidateOnDeleteWithSubobject() { - $subobject = new \SMWDIProperty( '_SOBJ' ); - $subject = \SMWDIWikiPage::newFromTitle( \Title::newFromText( __METHOD__ ) ); - $newSubject = \SMWDIWikiPage::newFromTitle( \Title::newFromText( 'Subobject' ) ); + $subobject = new DIProperty( '_SOBJ' ); + $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ); + $newSubject = DIWikiPage::newFromTitle( Title::newFromText( 'Subobject' ) ); $store = $this->getMockBuilder( 'SMWStore' ) ->disableOriginalConstructor() @@ -135,28 +143,29 @@ $this->equalTo( $subobject ) ) ->will( $this->returnValue( $newSubject ) ); - $itemId = CacheHelper::getKey( $subject ); + $glossaryCache = new GlossaryCache( new HashBagOStuff() ); - $cache = new HashBagOStuff; - $cache->set( $itemId, 'preset.cacheitem' ); + $itemId = $glossaryCache->getKeyForSubject( $subject ); - $instance = new CacheInvalidator; - $instance->setCache( $cache ); + $glossaryCache->getCache()->set( $itemId, 'preset.cacheitem' ); + + $instance = new CacheInvalidator(); + $instance->setCache( $glossaryCache ); $this->assertTrue( $instance->invalidateCacheOnPageDelete( $store, $subject ) ); $this->assertFalse( - $cache->get( $itemId ), + $glossaryCache->getCache()->get( $itemId ), 'Asserts that the preset item has been removed from cache' ); } public function testInvalidateOnMove() { - $title = \Title::newFromText( __METHOD__ ); + $title = Title::newFromText( __METHOD__ ); - $instance = new CacheInvalidator; - $instance->setCache( new HashBagOStuff ); + $instance = new CacheInvalidator(); + $instance->setCache( new GlossaryCache( new HashBagOStuff() ) ); $this->assertTrue( $instance->invalidateCacheOnPageMove( $title ) ); } diff --git a/tests/phpunit/Cache/ElementsCacheBuilderTest.php b/tests/phpunit/Cache/ElementsCacheBuilderTest.php index 1eef667..f63f16d 100644 --- a/tests/phpunit/Cache/ElementsCacheBuilderTest.php +++ b/tests/phpunit/Cache/ElementsCacheBuilderTest.php @@ -3,12 +3,13 @@ namespace SG\Tests\Cache; use SG\Cache\ElementsCacheBuilder; -use SG\CacheHelper; +use SG\Cache\GlossaryCache; use LingoElement; use SMWDIWikiPage as DIWikiPage; use SMWDIBlob as DIBlob; + use Title; use HashBagOStuff; @@ -30,13 +31,15 @@ public function testCanConstruct() { - $store = $this->getMockBuilder( 'SMWStore' ) + $store = $this->getMockBuilder( '\SMW\Store' ) ->disableOriginalConstructor() ->getMockForAbstractClass(); + $glossaryCache = $this->getMock( '\SG\Cache\GlossaryCache' ); + $this->assertInstanceOf( '\SG\Cache\ElementsCacheBuilder', - new ElementsCacheBuilder( $store ) + new ElementsCacheBuilder( $store, $glossaryCache ) ); } @@ -71,15 +74,18 @@ ->method( 'getPropertyValues' ) ->will( $this->returnValue( array( new DIBlob( ' some Definition ' ) ) ) ); - $cache = new HashBagOStuff(); + $glossaryCache = new GlossaryCache( new HashBagOStuff() ); - $instance = new ElementsCacheBuilder( $store, $cache ); + $instance = new ElementsCacheBuilder( + $store, + $glossaryCache + ); $results = $instance->getElements(); $this->assertEquals( $results, - $cache->get( CacheHelper::getKey( $page ) ) + $glossaryCache->getCache()->get( $glossaryCache->getKeyForSubject( $page ) ) ); $this->assertLingoElement( diff --git a/tests/phpunit/Cache/GlossaryCacheTest.php b/tests/phpunit/Cache/GlossaryCacheTest.php new file mode 100644 index 0000000..ab5d75d --- /dev/null +++ b/tests/phpunit/Cache/GlossaryCacheTest.php @@ -0,0 +1,58 @@ +<?php + +namespace SG\Tests\Cache; + +use SG\Cache\GlossaryCache; + +/** + * @covers \SG\Cache\GlossaryCache + * + * @ingroup Test + * + * @group SG + * @group SGExtension + * @group extension-semantic-glossary + * + * @license GNU GPL v2+ + * @since 1.0 + * + * @author mwjames + */ +class GlossaryCacheTest extends \PHPUnit_Framework_TestCase { + + public function testGetDefaultCache() { + + $glossaryCache = new GlossaryCache(); + + $this->assertInstanceOf( + 'BagOStuff', + $glossaryCache->getCache() + ); + } + + public function testGetCacheType() { + $this->assertInternalType( 'integer', GlossaryCache::getCacheType() ); + } + + public function testGetKeys() { + + $subject = $this->getMockBuilder( '\SMW\DIWikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $subject->expects( $this->once() ) + ->method( 'getSerialization' ) + ->will( $this->returnValue( 'Foo' ) ); + + $this->assertInternalType( + 'string', + GlossaryCache::getKeyForSubject( $subject ) + ); + + $this->assertInternalType( + 'string', + GlossaryCache::getKeyForLingo() + ); + } + +} diff --git a/tests/phpunit/CacheHelperTest.php b/tests/phpunit/CacheHelperTest.php deleted file mode 100644 index c305431..0000000 --- a/tests/phpunit/CacheHelperTest.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace SG\Tests; - -use SG\CacheHelper; - -/** - * @covers \SG\CacheHelper - * - * @ingroup Test - * - * @group SG - * @group SGExtension - * - * @licence GNU GPL v2+ - * @since 1.0 - * - * @author mwjames - */ -class CacheHelperTest extends \PHPUnit_Framework_TestCase { - - public function testGetCache() { - $this->assertInstanceOf( 'BagOStuff', CacheHelper::getCache() ); - } - - public function testGetCacheType() { - $this->assertInternalType( 'integer', CacheHelper::getCacheType() ); - } - - public function testGetKey() { - - $subject = $this->getMockBuilder( 'SMWDIWikiPage' ) - ->disableOriginalConstructor() - ->getMock(); - - $subject->expects( $this->once() ) - ->method( 'getSerialization' ) - ->will( $this->returnValue( 'Foo' ) ); - - $this->assertInternalType( 'string', CacheHelper::getKey( $subject ) ); - } - -} diff --git a/tests/phpunit/ConfigurationIntegrityTest.php b/tests/phpunit/ConfigurationIntegrityTest.php index ae6ae10..f365238 100644 --- a/tests/phpunit/ConfigurationIntegrityTest.php +++ b/tests/phpunit/ConfigurationIntegrityTest.php @@ -2,7 +2,7 @@ namespace SG\Tests; -use SG\CacheHelper; +use SG\Cache\GlossaryCache; /** * @ingroup Test @@ -23,7 +23,7 @@ $this->assertCacheType( $GLOBAL['wgexLingoCacheType'] ); } - $this->assertCacheType( CacheHelper::getCacheType() ); + $this->assertCacheType( GlossaryCache::getCacheType() ); } protected function assertCacheType( $cacheType ) { diff --git a/tests/phpunit/Maintenance/GlossaryCacheRebuilderTest.php b/tests/phpunit/Maintenance/GlossaryCacheRebuilderTest.php index 0939f27..27f5393 100644 --- a/tests/phpunit/Maintenance/GlossaryCacheRebuilderTest.php +++ b/tests/phpunit/Maintenance/GlossaryCacheRebuilderTest.php @@ -3,6 +3,7 @@ namespace SG\Tests\Maintenance; use SG\Maintenance\GlossaryCacheRebuilder; +use SG\Cache\GlossaryCache; use Title; @@ -24,11 +25,14 @@ public function testCanConstruct() { $store = $this->getMockForAbstractClass( '\SMW\Store' ); - $cache = $this->getMockForAbstractClass( 'BagOStuff' ); + + $glossaryCache = $this->getMockBuilder( '\SG\Cache\GlossaryCache' ) + ->disableOriginalConstructor() + ->getMock(); $this->assertInstanceOf( '\SG\Maintenance\GlossaryCacheRebuilder', - new GlossaryCacheRebuilder( $store, $cache ) + new GlossaryCacheRebuilder( $store, $glossaryCache ) ); } @@ -58,23 +62,27 @@ ->method( 'getQueryResult' ) ->will( $this->returnValue( $queryResult ) ); - $cache = $this->getMockBuilder( 'BagOStuff' ) + $bagOStuff = $this->getMockBuilder( 'BagOStuff' ) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $cache->expects( $this->at( 0 ) ) + $bagOStuff->expects( $this->at( 0 ) ) ->method( 'delete' ) ->with( $this->stringContains( 'lingotree' ) ); - $cache->expects( $this->at( 1 ) ) + $bagOStuff->expects( $this->at( 1 ) ) ->method( 'delete' ) ->with( $this->stringContains( 'semanticglossary' ) ); - $cache->expects( $this->at( 2 ) ) + $bagOStuff->expects( $this->at( 2 ) ) ->method( 'delete' ) ->with( $this->stringContains( 'semanticglossary' ) ); - $instance = new GlossaryCacheRebuilder( $store, $cache ); + $instance = new GlossaryCacheRebuilder( + $store, + new GlossaryCache( $bagOStuff ) + ); + $instance->setParameters( array() ); $this->assertTrue( $instance->rebuild() ); diff --git a/tests/phpunit/MwDBSQLStoreIntegrationTest.php b/tests/phpunit/MwDBSQLStoreIntegrationTest.php new file mode 100644 index 0000000..e90c3b6 --- /dev/null +++ b/tests/phpunit/MwDBSQLStoreIntegrationTest.php @@ -0,0 +1,77 @@ +<?php + +namespace SG\Tests; + +use SG\PropertyRegistry; + +use SMW\Tests\MwDBaseUnitTestCase; +use SMW\Tests\Util\PageCreator; +use SMW\Tests\Util\PageDeleter; +use SMW\Tests\Util\MaintenanceRunner; + +use SMW\StoreFactory; +use SMW\DIProperty; +use SMW\DIWikiPage; + +use Title; + +/** + * @ingroup Test + * + * @group SG + * @group SGExtension + * @group mediawiki-database + * @group medium + * + * @license GNU GPL v2+ + * @since 1.1 + * + * @author mwjames + */ +class MwDBSQLStoreIntegrationTest extends MwDBaseUnitTestCase { + + public function testPageCreateDeleteIntegration() { + + $store = StoreFactory::getStore(); + + $title = Title::newFromText( __METHOD__ ); + + $pageCreator = new PageCreator(); + $pageCreator + ->createPage( $title ) + ->doEdit( "[[Glossary-Term::testTerm]] [[Glossary-Definition::testDefinition]]" ); + + $values = $store->getPropertyValues( + DIWikiPage::newFromTitle( $title ), + new DIProperty( PropertyRegistry::SG_TERM ) + ); + + $this->assertNotEmpty( $values ); + + $pageDeleter = new PageDeleter(); + $pageDeleter + ->deletePage( $title ); + + $values = $store->getPropertyValues( + DIWikiPage::newFromTitle( $title ), + new DIProperty( PropertyRegistry::SG_TERM ) + ); + + $this->assertEmpty( $values ); + } + + public function testRebuildGlossaryCacheMaintenancRun() { + + $pageCreator = new PageCreator(); + $pageCreator + ->createPage( Title::newFromText( __METHOD__ ) ) + ->doEdit( "[[Glossary-Term::testTerm]] [[Glossary-Definition::testDefinition]]" ); + + $maintenanceRunner = new MaintenanceRunner( 'SG\Maintenance\RebuildGlossaryCache' ); + + $this->assertTrue( + $maintenanceRunner->setQuiet()->run() + ); + } + +} diff --git a/tests/phpunit/DataComparatorTest.php b/tests/phpunit/SemanticDataComparatorTest.php similarity index 65% rename from tests/phpunit/DataComparatorTest.php rename to tests/phpunit/SemanticDataComparatorTest.php index 27a87d8..377f2c7 100644 --- a/tests/phpunit/DataComparatorTest.php +++ b/tests/phpunit/SemanticDataComparatorTest.php @@ -2,22 +2,23 @@ namespace SG\Tests; -use SG\DataComparator; +use SG\SemanticDataComparator; /** - * @covers \SG\DataComparator + * @covers \SG\SemanticDataComparator * * @ingroup Test * * @group SG * @group SGExtension + * @group extension-semantic-glossary * - * @licence GNU GPL v2+ + * @license GNU GPL v2+ * @since 1.0 * * @author mwjames */ -class DataComparatorTest extends \PHPUnit_Framework_TestCase { +class SemanticDataComparatorTest extends \PHPUnit_Framework_TestCase { public function testCanConstruct() { @@ -29,9 +30,9 @@ ->disableOriginalConstructor() ->getMockForAbstractClass(); - $instance = new DataComparator( $store, $semanticData ); + $instance = new SemanticDataComparator( $store, $semanticData ); - $this->assertInstanceOf( '\SG\DataComparator', $instance ); + $this->assertInstanceOf( '\SG\SemanticDataComparator', $instance ); } public function testInspectWithoutData() { @@ -44,7 +45,7 @@ ->disableOriginalConstructor() ->getMockForAbstractClass(); - $instance = new DataComparator( $store, $semanticData ); + $instance = new SemanticDataComparator( $store, $semanticData ); $this->assertFalse( $instance->byPropertyId( 'foo' ) ); } -- To view, visit https://gerrit.wikimedia.org/r/133949 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id0e0e1c19afc3aceb06fe75f2d5892cd2a065f34 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/SemanticGlossary Gerrit-Branch: master Gerrit-Owner: Mwjames <jamesin.hongkon...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits