MediaWiki  master
DBSiteStore.php
Go to the documentation of this file.
1 <?php
23 
32 class DBSiteStore implements SiteStore {
34  protected $sites = null;
36  private $dbProvider;
37 
42  public function __construct( IConnectionProvider $dbProvider ) {
43  $this->dbProvider = $dbProvider;
44  }
45 
52  public function getSites() {
53  $this->loadSites();
54 
55  return $this->sites;
56  }
57 
63  protected function loadSites() {
64  $this->sites = new SiteList();
65 
66  $dbr = $this->dbProvider->getReplicaDatabase();
67 
68  $res = $dbr->newSelectQueryBuilder()
69  ->select( [
70  'site_id',
71  'site_global_key',
72  'site_type',
73  'site_group',
74  'site_source',
75  'site_language',
76  'site_protocol',
77  'site_domain',
78  'site_data',
79  'site_forward',
80  'site_config',
81  ] )
82  ->from( 'sites' )
83  ->orderBy( 'site_global_key' )
84  ->caller( __METHOD__ )->fetchResultSet();
85 
86  foreach ( $res as $row ) {
87  $site = Site::newForType( $row->site_type );
88  $site->setGlobalId( $row->site_global_key );
89  $site->setInternalId( (int)$row->site_id );
90  $site->setForward( (bool)$row->site_forward );
91  $site->setGroup( $row->site_group );
92  $site->setLanguageCode( $row->site_language === ''
93  ? null
94  : $row->site_language
95  );
96  $site->setSource( $row->site_source );
97  $site->setExtraData( unserialize( $row->site_data ) );
98  $site->setExtraConfig( unserialize( $row->site_config ) );
99  $this->sites[] = $site;
100  }
101 
102  // Batch load the local site identifiers.
103  $ids = $dbr->newSelectQueryBuilder()
104  ->select( [ 'si_site', 'si_type', 'si_key', ] )
105  ->from( 'site_identifiers' )
106  ->caller( __METHOD__ )->fetchResultSet();
107 
108  foreach ( $ids as $id ) {
109  if ( $this->sites->hasInternalId( $id->si_site ) ) {
110  $site = $this->sites->getSiteByInternalId( $id->si_site );
111  $site->addLocalId( $id->si_type, $id->si_key );
112  $this->sites->setSite( $site );
113  }
114  }
115  }
116 
124  public function getSite( $globalId ) {
125  if ( $this->sites === null ) {
126  $this->sites = $this->getSites();
127  }
128 
129  return $this->sites->hasSite( $globalId ) ? $this->sites->getSite( $globalId ) : null;
130  }
131 
139  public function saveSite( Site $site ) {
140  return $this->saveSites( [ $site ] );
141  }
142 
150  public function saveSites( array $sites ) {
151  if ( !$sites ) {
152  return true;
153  }
154 
155  $dbw = $this->dbProvider->getPrimaryDatabase();
156 
157  $dbw->startAtomic( __METHOD__ );
158 
159  $internalIds = [];
160  $localIds = [];
161 
162  foreach ( $sites as $site ) {
163  if ( $site->getInternalId() !== null ) {
164  $internalIds[] = $site->getInternalId();
165  }
166 
167  $fields = [
168  // Site data
169  'site_global_key' => $site->getGlobalId(), // TODO: check not null
170  'site_type' => $site->getType(),
171  'site_group' => $site->getGroup(),
172  'site_source' => $site->getSource(),
173  'site_language' => $site->getLanguageCode() ?? '',
174  'site_protocol' => $site->getProtocol(),
175  'site_domain' => strrev( $site->getDomain() ?? '' ) . '.',
176  'site_data' => serialize( $site->getExtraData() ),
177 
178  // Site config
179  'site_forward' => $site->shouldForward() ? 1 : 0,
180  'site_config' => serialize( $site->getExtraConfig() ),
181  ];
182 
183  $rowId = $site->getInternalId();
184  if ( $rowId !== null ) {
185  $dbw->newUpdateQueryBuilder()
186  ->update( 'sites' )
187  ->set( $fields )
188  ->where( [ 'site_id' => $rowId ] )
189  ->caller( __METHOD__ )->execute();
190  } else {
191  $dbw->newInsertQueryBuilder()
192  ->insertInto( 'sites' )
193  ->row( $fields )
194  ->caller( __METHOD__ )->execute();
195  $rowId = $dbw->insertId();
196  }
197 
198  foreach ( $site->getLocalIds() as $idType => $ids ) {
199  foreach ( $ids as $id ) {
200  $localIds[] = [ $rowId, $idType, $id ];
201  }
202  }
203  }
204 
205  if ( $internalIds !== [] ) {
206  $dbw->newDeleteQueryBuilder()
207  ->deleteFrom( 'site_identifiers' )
208  ->where( [ 'si_site' => $internalIds ] )
209  ->caller( __METHOD__ )->execute();
210  }
211 
212  foreach ( $localIds as $localId ) {
213  $dbw->newInsertQueryBuilder()
214  ->insertInto( 'site_identifiers' )
215  ->row( [ 'si_site' => $localId[0], 'si_type' => $localId[1], 'si_key' => $localId[2] ] )
216  ->caller( __METHOD__ )->execute();
217  }
218 
219  $dbw->endAtomic( __METHOD__ );
220 
221  $this->reset();
222 
223  return true;
224  }
225 
231  public function reset() {
232  $this->sites = null;
233  }
234 
240  public function clear() {
241  $dbw = $this->dbProvider->getPrimaryDatabase();
242 
243  $dbw->startAtomic( __METHOD__ );
244  $dbw->newDeleteQueryBuilder()
245  ->deleteFrom( 'sites' )
246  ->where( IDatabase::ALL_ROWS )
247  ->caller( __METHOD__ )->execute();
248  $dbw->newDeleteQueryBuilder()
249  ->deleteFrom( 'site_identifiers' )
250  ->where( IDatabase::ALL_ROWS )
251  ->caller( __METHOD__ )->execute();
252  $dbw->endAtomic( __METHOD__ );
253 
254  $this->reset();
255  }
256 
257 }
Holds a list of sites stored in the database.
Definition: DBSiteStore.php:32
getSite( $globalId)
SiteList null $sites
Definition: DBSiteStore.php:34
reset()
Resets the SiteList.
loadSites()
Fetches the site from the database and loads them into the sites field.
Definition: DBSiteStore.php:63
saveSites(array $sites)
clear()
Clears the list of sites stored in the database.
__construct(IConnectionProvider $dbProvider)
Definition: DBSiteStore.php:42
saveSite(Site $site)
Array-like collection of Site objects.
Definition: SiteList.php:32
Represents a single site.
Definition: Site.php:32
static newForType( $siteType)
Definition: Site.php:623
Interface for storing and retrieving Site objects.
Definition: SiteStore.php:30
Provide primary and replica IDatabase connections.
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:36