MediaWiki  master
DBSiteStore.php
Go to the documentation of this file.
1 <?php
22 
31 class DBSiteStore implements SiteStore {
33  protected $sites = null;
35  private $dbLoadBalancer;
36 
41  public function __construct( ILoadBalancer $dbLoadBalancer ) {
42  $this->dbLoadBalancer = $dbLoadBalancer;
43  }
44 
51  public function getSites() {
52  $this->loadSites();
53 
54  return $this->sites;
55  }
56 
62  protected function loadSites() {
63  $this->sites = new SiteList();
64 
65  $dbr = $this->dbLoadBalancer->getConnectionRef( DB_REPLICA );
66 
67  $res = $dbr->select(
68  'sites',
69  [
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  '',
83  __METHOD__,
84  [ 'ORDER BY' => 'site_global_key' ]
85  );
86 
87  foreach ( $res as $row ) {
88  $site = Site::newForType( $row->site_type );
89  $site->setGlobalId( $row->site_global_key );
90  $site->setInternalId( (int)$row->site_id );
91  $site->setForward( (bool)$row->site_forward );
92  $site->setGroup( $row->site_group );
93  $site->setLanguageCode( $row->site_language === ''
94  ? null
95  : $row->site_language
96  );
97  $site->setSource( $row->site_source );
98  $site->setExtraData( unserialize( $row->site_data ) );
99  $site->setExtraConfig( unserialize( $row->site_config ) );
100  $this->sites[] = $site;
101  }
102 
103  // Batch load the local site identifiers.
104  $ids = $dbr->select(
105  'site_identifiers',
106  [
107  'si_site',
108  'si_type',
109  'si_key',
110  ],
111  [],
112  __METHOD__
113  );
114 
115  foreach ( $ids as $id ) {
116  if ( $this->sites->hasInternalId( $id->si_site ) ) {
117  $site = $this->sites->getSiteByInternalId( $id->si_site );
118  $site->addLocalId( $id->si_type, $id->si_key );
119  $this->sites->setSite( $site );
120  }
121  }
122  }
123 
131  public function getSite( $globalId ) {
132  if ( $this->sites === null ) {
133  $this->sites = $this->getSites();
134  }
135 
136  return $this->sites->hasSite( $globalId ) ? $this->sites->getSite( $globalId ) : null;
137  }
138 
146  public function saveSite( Site $site ) {
147  return $this->saveSites( [ $site ] );
148  }
149 
157  public function saveSites( array $sites ) {
158  if ( empty( $sites ) ) {
159  return true;
160  }
161 
162  $dbw = $this->dbLoadBalancer->getConnectionRef( DB_PRIMARY );
163 
164  $dbw->startAtomic( __METHOD__ );
165 
166  $success = true;
167 
168  $internalIds = [];
169  $localIds = [];
170 
171  foreach ( $sites as $site ) {
172  if ( $site->getInternalId() !== null ) {
173  $internalIds[] = $site->getInternalId();
174  }
175 
176  $fields = [
177  // Site data
178  'site_global_key' => $site->getGlobalId(), // TODO: check not null
179  'site_type' => $site->getType(),
180  'site_group' => $site->getGroup(),
181  'site_source' => $site->getSource(),
182  'site_language' => $site->getLanguageCode() ?? '',
183  'site_protocol' => $site->getProtocol(),
184  'site_domain' => strrev( $site->getDomain() ?? '' ) . '.',
185  'site_data' => serialize( $site->getExtraData() ),
186 
187  // Site config
188  'site_forward' => $site->shouldForward() ? 1 : 0,
189  'site_config' => serialize( $site->getExtraConfig() ),
190  ];
191 
192  $rowId = $site->getInternalId();
193  if ( $rowId !== null ) {
194  $success = $dbw->update(
195  'sites', $fields, [ 'site_id' => $rowId ], __METHOD__
196  ) && $success;
197  } else {
198  $success = $dbw->insert( 'sites', $fields, __METHOD__ ) && $success;
199  $rowId = $dbw->insertId();
200  }
201 
202  foreach ( $site->getLocalIds() as $idType => $ids ) {
203  foreach ( $ids as $id ) {
204  $localIds[] = [ $rowId, $idType, $id ];
205  }
206  }
207  }
208 
209  if ( $internalIds !== [] ) {
210  $dbw->delete(
211  'site_identifiers',
212  [ 'si_site' => $internalIds ],
213  __METHOD__
214  );
215  }
216 
217  foreach ( $localIds as $localId ) {
218  $dbw->insert(
219  'site_identifiers',
220  [
221  'si_site' => $localId[0],
222  'si_type' => $localId[1],
223  'si_key' => $localId[2],
224  ],
225  __METHOD__
226  );
227  }
228 
229  $dbw->endAtomic( __METHOD__ );
230 
231  $this->reset();
232 
233  return $success;
234  }
235 
241  public function reset() {
242  $this->sites = null;
243  }
244 
252  public function clear() {
253  $dbw = $this->dbLoadBalancer->getConnectionRef( DB_PRIMARY );
254 
255  $dbw->startAtomic( __METHOD__ );
256  $ok = $dbw->delete( 'sites', '*', __METHOD__ );
257  $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
258  $dbw->endAtomic( __METHOD__ );
259 
260  $this->reset();
261 
262  return $ok;
263  }
264 
265 }
$success
Holds a list of sites stored in the database.
Definition: DBSiteStore.php:31
__construct(ILoadBalancer $dbLoadBalancer)
Definition: DBSiteStore.php:41
getSite( $globalId)
SiteList null $sites
Definition: DBSiteStore.php:33
reset()
Resets the SiteList.
loadSites()
Fetches the site from the database and loads them into the sites field.
Definition: DBSiteStore.php:62
saveSites(array $sites)
clear()
Clears the list of sites stored in the database.
saveSite(Site $site)
Collection of Site objects.
Definition: SiteList.php:28
Represents a single site.
Definition: Site.php:32
static newForType( $siteType)
Definition: Site.php:623
Interface for storing and retreiving Site objects.
Definition: SiteStore.php:30
This class is a delegate to ILBFactory for a given database cluster.
const DB_REPLICA
Definition: defines.php:26
const DB_PRIMARY
Definition: defines.php:28