Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
98.04% |
50 / 51 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
| RevisionStoreFactory | |
98.04% |
50 / 51 |
|
80.00% |
4 / 5 |
9 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
1 | |||
| getRevisionStore | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
| getRevisionStoreForImport | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
| getRevisionStoreForUndelete | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
| getStore | |
96.00% |
24 / 25 |
|
0.00% |
0 / 1 |
5 | |||
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * @license GPL-2.0-or-later |
| 5 | * Attribution notice: when this file was created, much of its content was taken |
| 6 | * from the Revision.php file as present in release 1.30. Refer to the history |
| 7 | * of that file for original authorship (that file was removed entirely in 1.37, |
| 8 | * but its history can still be found in prior versions of MediaWiki). |
| 9 | * |
| 10 | * @file |
| 11 | */ |
| 12 | |
| 13 | namespace MediaWiki\Revision; |
| 14 | |
| 15 | use MediaWiki\CommentStore\CommentStore; |
| 16 | use MediaWiki\Content\IContentHandlerFactory; |
| 17 | use MediaWiki\DAO\WikiAwareEntity; |
| 18 | use MediaWiki\HookContainer\HookContainer; |
| 19 | use MediaWiki\Page\PageStoreFactory; |
| 20 | use MediaWiki\RecentChanges\RecentChangeLookup; |
| 21 | use MediaWiki\Storage\BlobStoreFactory; |
| 22 | use MediaWiki\Storage\NameTableStoreFactory; |
| 23 | use MediaWiki\Title\TitleFactory; |
| 24 | use MediaWiki\User\ActorStore; |
| 25 | use MediaWiki\User\ActorStoreFactory; |
| 26 | use MediaWiki\WikiMap\WikiMap; |
| 27 | use Psr\Log\LoggerInterface; |
| 28 | use Wikimedia\Assert\Assert; |
| 29 | use Wikimedia\ObjectCache\BagOStuff; |
| 30 | use Wikimedia\ObjectCache\WANObjectCache; |
| 31 | use Wikimedia\Rdbms\ILBFactory; |
| 32 | |
| 33 | /** |
| 34 | * Factory service for RevisionStore instances. This allows RevisionStores to be created for |
| 35 | * cross-wiki access. |
| 36 | * |
| 37 | * @warning Beware compatibility issues with schema migration in the context of cross-wiki access! |
| 38 | * This class assumes that all wikis are at compatible migration stages for all relevant schemas. |
| 39 | * Relevant schemas are: revision storage (MCR), the revision comment table, and the actor table. |
| 40 | * Migration stages are compatible as long as a) there are no wikis in the cluster that only write |
| 41 | * the old schema or b) there are no wikis that read only the new schema. |
| 42 | * |
| 43 | * @since 1.32 |
| 44 | */ |
| 45 | class RevisionStoreFactory { |
| 46 | |
| 47 | private BlobStoreFactory $blobStoreFactory; |
| 48 | private ILBFactory $dbLoadBalancerFactory; |
| 49 | private WANObjectCache $cache; |
| 50 | private BagOStuff $localCache; |
| 51 | private LoggerInterface $logger; |
| 52 | private CommentStore $commentStore; |
| 53 | private ActorStoreFactory $actorStoreFactory; |
| 54 | private NameTableStoreFactory $nameTables; |
| 55 | private SlotRoleRegistry $slotRoleRegistry; |
| 56 | private IContentHandlerFactory $contentHandlerFactory; |
| 57 | private PageStoreFactory $pageStoreFactory; |
| 58 | private TitleFactory $titleFactory; |
| 59 | private HookContainer $hookContainer; |
| 60 | private RecentChangeLookup $recentChangeLookup; |
| 61 | |
| 62 | public function __construct( |
| 63 | ILBFactory $dbLoadBalancerFactory, |
| 64 | BlobStoreFactory $blobStoreFactory, |
| 65 | NameTableStoreFactory $nameTables, |
| 66 | SlotRoleRegistry $slotRoleRegistry, |
| 67 | WANObjectCache $cache, |
| 68 | BagOStuff $localCache, |
| 69 | CommentStore $commentStore, |
| 70 | ActorStoreFactory $actorStoreFactory, |
| 71 | LoggerInterface $logger, |
| 72 | IContentHandlerFactory $contentHandlerFactory, |
| 73 | PageStoreFactory $pageStoreFactory, |
| 74 | TitleFactory $titleFactory, |
| 75 | HookContainer $hookContainer, |
| 76 | RecentChangeLookup $recentChangeLookup |
| 77 | ) { |
| 78 | $this->dbLoadBalancerFactory = $dbLoadBalancerFactory; |
| 79 | $this->blobStoreFactory = $blobStoreFactory; |
| 80 | $this->slotRoleRegistry = $slotRoleRegistry; |
| 81 | $this->nameTables = $nameTables; |
| 82 | $this->cache = $cache; |
| 83 | $this->localCache = $localCache; |
| 84 | $this->commentStore = $commentStore; |
| 85 | $this->actorStoreFactory = $actorStoreFactory; |
| 86 | $this->logger = $logger; |
| 87 | $this->contentHandlerFactory = $contentHandlerFactory; |
| 88 | $this->pageStoreFactory = $pageStoreFactory; |
| 89 | $this->titleFactory = $titleFactory; |
| 90 | $this->hookContainer = $hookContainer; |
| 91 | $this->recentChangeLookup = $recentChangeLookup; |
| 92 | } |
| 93 | |
| 94 | /** |
| 95 | * @since 1.32 |
| 96 | * |
| 97 | * @param false|string $dbDomain DB domain of the relevant wiki or false for the current one |
| 98 | * |
| 99 | * @return RevisionStore for the given wikiId with all necessary services |
| 100 | */ |
| 101 | public function getRevisionStore( $dbDomain = false ): RevisionStore { |
| 102 | return $this->getStore( |
| 103 | $dbDomain, |
| 104 | $this->actorStoreFactory->getActorStore( $dbDomain ) |
| 105 | ); |
| 106 | } |
| 107 | |
| 108 | /** |
| 109 | * @since 1.42 |
| 110 | * |
| 111 | * @param false|string $dbDomain DB domain of the relevant wiki or false for the current one |
| 112 | * |
| 113 | * @return RevisionStore for the given wikiId with all necessary services |
| 114 | */ |
| 115 | public function getRevisionStoreForImport( $dbDomain = false ): RevisionStore { |
| 116 | return $this->getStore( |
| 117 | $dbDomain, |
| 118 | $this->actorStoreFactory->getActorStoreForImport( $dbDomain ) |
| 119 | ); |
| 120 | } |
| 121 | |
| 122 | /** |
| 123 | * @since 1.43 |
| 124 | * |
| 125 | * @param false|string $dbDomain DB domain of the relevant wiki or false for the current one |
| 126 | * |
| 127 | * @return RevisionStore for the given wikiId with all necessary services |
| 128 | */ |
| 129 | public function getRevisionStoreForUndelete( $dbDomain = false ): RevisionStore { |
| 130 | return $this->getStore( |
| 131 | $dbDomain, |
| 132 | $this->actorStoreFactory->getActorStoreForUndelete( $dbDomain ) |
| 133 | ); |
| 134 | } |
| 135 | |
| 136 | /** |
| 137 | * @param false|string $dbDomain |
| 138 | * @param ActorStore $actorStore |
| 139 | * |
| 140 | * @return RevisionStore |
| 141 | */ |
| 142 | private function getStore( $dbDomain, ActorStore $actorStore ) { |
| 143 | Assert::parameterType( [ 'string', 'false' ], $dbDomain, '$dbDomain' ); |
| 144 | if ( |
| 145 | // FIXME: We can't normalize the domain in tests, as RevisionStoreDbTest relies on this behaviour to test |
| 146 | // cross-wikiness, in absence of a better way (T261848). |
| 147 | !defined( 'MW_PHPUNIT_TEST' ) && |
| 148 | is_string( $dbDomain ) && |
| 149 | ( |
| 150 | $this->dbLoadBalancerFactory->getLocalDomainID() === $dbDomain || |
| 151 | WikiMap::getWikiIdFromDbDomain( $this->dbLoadBalancerFactory->getLocalDomainID() ) === $dbDomain |
| 152 | ) |
| 153 | ) { |
| 154 | $dbDomain = WikiAwareEntity::LOCAL; |
| 155 | } |
| 156 | |
| 157 | $store = new RevisionStore( |
| 158 | $this->dbLoadBalancerFactory->getMainLB( $dbDomain ), |
| 159 | $this->blobStoreFactory->newSqlBlobStore( $dbDomain ), |
| 160 | $this->cache, // Pass cache local to wiki; Leave cache sharing to RevisionStore. |
| 161 | $this->localCache, |
| 162 | $this->commentStore, |
| 163 | $this->nameTables->getContentModels( $dbDomain ), |
| 164 | $this->nameTables->getSlotRoles( $dbDomain ), |
| 165 | $this->slotRoleRegistry, |
| 166 | $actorStore, |
| 167 | $this->contentHandlerFactory, |
| 168 | $this->pageStoreFactory->getPageStore( $dbDomain ), |
| 169 | $this->titleFactory, |
| 170 | $this->hookContainer, |
| 171 | $this->recentChangeLookup, |
| 172 | $dbDomain |
| 173 | ); |
| 174 | |
| 175 | $store->setLogger( $this->logger ); |
| 176 | |
| 177 | return $store; |
| 178 | } |
| 179 | } |