MediaWiki  master
DBSiteStore.php
Go to the documentation of this file.
1 <?php
2 
4 
33 class DBSiteStore implements SiteStore {
34 
38  protected $sites = null;
39 
43  private $dbLoadBalancer;
44 
54  $this->dbLoadBalancer = $dbLoadBalancer;
55  }
56 
64  public function getSites() {
65  $this->loadSites();
66 
67  return $this->sites;
68  }
69 
75  protected function loadSites() {
76  $this->sites = new SiteList();
77 
78  $dbr = $this->dbLoadBalancer->getConnectionRef( DB_REPLICA );
79 
80  $res = $dbr->select(
81  'sites',
82  [
83  'site_id',
84  'site_global_key',
85  'site_type',
86  'site_group',
87  'site_source',
88  'site_language',
89  'site_protocol',
90  'site_domain',
91  'site_data',
92  'site_forward',
93  'site_config',
94  ],
95  '',
96  __METHOD__,
97  [ 'ORDER BY' => 'site_global_key' ]
98  );
99 
100  foreach ( $res as $row ) {
101  $site = Site::newForType( $row->site_type );
102  $site->setGlobalId( $row->site_global_key );
103  $site->setInternalId( (int)$row->site_id );
104  $site->setForward( (bool)$row->site_forward );
105  $site->setGroup( $row->site_group );
106  $site->setLanguageCode( $row->site_language === ''
107  ? null
108  : $row->site_language
109  );
110  $site->setSource( $row->site_source );
111  $site->setExtraData( unserialize( $row->site_data ) );
112  $site->setExtraConfig( unserialize( $row->site_config ) );
113  $this->sites[] = $site;
114  }
115 
116  // Batch load the local site identifiers.
117  $ids = $dbr->select(
118  'site_identifiers',
119  [
120  'si_site',
121  'si_type',
122  'si_key',
123  ],
124  [],
125  __METHOD__
126  );
127 
128  foreach ( $ids as $id ) {
129  if ( $this->sites->hasInternalId( $id->si_site ) ) {
130  $site = $this->sites->getSiteByInternalId( $id->si_site );
131  $site->addLocalId( $id->si_type, $id->si_key );
132  $this->sites->setSite( $site );
133  }
134  }
135  }
136 
146  public function getSite( $globalId ) {
147  if ( $this->sites === null ) {
148  $this->sites = $this->getSites();
149  }
150 
151  return $this->sites->hasSite( $globalId ) ? $this->sites->getSite( $globalId ) : null;
152  }
153 
163  public function saveSite( Site $site ) {
164  return $this->saveSites( [ $site ] );
165  }
166 
176  public function saveSites( array $sites ) {
177  if ( empty( $sites ) ) {
178  return true;
179  }
180 
181  $dbw = $this->dbLoadBalancer->getConnectionRef( DB_MASTER );
182 
183  $dbw->startAtomic( __METHOD__ );
184 
185  $success = true;
186 
187  $internalIds = [];
188  $localIds = [];
189 
190  foreach ( $sites as $site ) {
191  if ( $site->getInternalId() !== null ) {
192  $internalIds[] = $site->getInternalId();
193  }
194 
195  $fields = [
196  // Site data
197  'site_global_key' => $site->getGlobalId(), // TODO: check not null
198  'site_type' => $site->getType(),
199  'site_group' => $site->getGroup(),
200  'site_source' => $site->getSource(),
201  'site_language' => $site->getLanguageCode() ?? '',
202  'site_protocol' => $site->getProtocol(),
203  'site_domain' => strrev( $site->getDomain() ) . '.',
204  'site_data' => serialize( $site->getExtraData() ),
205 
206  // Site config
207  'site_forward' => $site->shouldForward() ? 1 : 0,
208  'site_config' => serialize( $site->getExtraConfig() ),
209  ];
210 
211  $rowId = $site->getInternalId();
212  if ( $rowId !== null ) {
213  $success = $dbw->update(
214  'sites', $fields, [ 'site_id' => $rowId ], __METHOD__
215  ) && $success;
216  } else {
217  $success = $dbw->insert( 'sites', $fields, __METHOD__ ) && $success;
218  $rowId = $dbw->insertId();
219  }
220 
221  foreach ( $site->getLocalIds() as $idType => $ids ) {
222  foreach ( $ids as $id ) {
223  $localIds[] = [ $rowId, $idType, $id ];
224  }
225  }
226  }
227 
228  if ( $internalIds !== [] ) {
229  $dbw->delete(
230  'site_identifiers',
231  [ 'si_site' => $internalIds ],
232  __METHOD__
233  );
234  }
235 
236  foreach ( $localIds as $localId ) {
237  $dbw->insert(
238  'site_identifiers',
239  [
240  'si_site' => $localId[0],
241  'si_type' => $localId[1],
242  'si_key' => $localId[2],
243  ],
244  __METHOD__
245  );
246  }
247 
248  $dbw->endAtomic( __METHOD__ );
249 
250  $this->reset();
251 
252  return $success;
253  }
254 
260  public function reset() {
261  $this->sites = null;
262  }
263 
271  public function clear() {
272  $dbw = $this->dbLoadBalancer->getConnectionRef( DB_MASTER );
273 
274  $dbw->startAtomic( __METHOD__ );
275  $ok = $dbw->delete( 'sites', '*', __METHOD__ );
276  $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
277  $dbw->endAtomic( __METHOD__ );
278 
279  $this->reset();
280 
281  return $ok;
282  }
283 
284 }
$success
serialize()
clear()
Clears the list of sites stored in the database.
getSite( $globalId)
const DB_MASTER
Definition: defines.php:26
ILoadBalancer $dbLoadBalancer
Definition: DBSiteStore.php:43
saveSite(Site $site)
static newForType( $siteType)
Definition: Site.php:646
reset()
Resets the SiteList.
unserialize( $serialized)
__construct(ILoadBalancer $dbLoadBalancer)
Definition: DBSiteStore.php:53
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: Site.php:29
loadSites()
Fetches the site from the database and loads them into the sites field.
Definition: DBSiteStore.php:75
const DB_REPLICA
Definition: defines.php:25
saveSites(array $sites)
SiteList null $sites
Definition: DBSiteStore.php:38