MediaWiki  master
SiteStatsInit.php
Go to the documentation of this file.
1 <?php
21 namespace MediaWiki\SiteStats;
22 
25 use SiteStatsUpdate;
27 
33  private $dbr;
35  private $edits;
37  private $articles;
39  private $pages;
41  private $users;
43  private $files;
44 
50  public function __construct( $database = false ) {
51  if ( $database instanceof IDatabase ) {
52  $this->dbr = $database;
53  } elseif ( $database ) {
54  $this->dbr = self::getDB( DB_PRIMARY );
55  } else {
56  $this->dbr = self::getDB( DB_REPLICA, 'vslow' );
57  }
58  }
59 
64  public function edits() {
65  $this->edits = $this->countTableRows( 'revision' );
66  $this->edits += $this->countTableRows( 'archive' );
67 
68  return $this->edits;
69  }
70 
71  private function countTableRows( string $tableName ) {
72  return (int)$this->dbr->newSelectQueryBuilder()
73  ->select( 'COUNT(*)' )
74  ->from( $tableName )
75  ->caller( __METHOD__ )->fetchField();
76  }
77 
82  public function articles() {
83  $services = MediaWikiServices::getInstance();
84  $queryBuilder = $this->dbr->newSelectQueryBuilder()
85  ->select( 'COUNT(DISTINCT page_id)' )
86  ->from( 'page' )
87  ->where( [
88  'page_namespace' => $services->getNamespaceInfo()->getContentNamespaces(),
89  'page_is_redirect' => 0,
90  ] );
91 
92  if ( $services->getMainConfig()->get( MainConfigNames::ArticleCountMethod ) == 'link' ) {
93  $queryBuilder->join( 'pagelinks', null, 'pl_from=page_id' );
94  }
95 
96  $this->articles = $queryBuilder->caller( __METHOD__ )->fetchField();
97 
98  return $this->articles;
99  }
100 
105  public function pages() {
106  $this->pages = $this->countTableRows( 'page' );
107 
108  return $this->pages;
109  }
110 
115  public function users() {
116  $this->users = $this->countTableRows( 'user' );
117 
118  return $this->users;
119  }
120 
125  public function files() {
126  $this->files = $this->countTableRows( 'image' );
127 
128  return $this->files;
129  }
130 
141  public static function doAllAndCommit( $database, array $options = [] ) {
142  $options += [ 'update' => false, 'activeUsers' => false ];
143 
144  // Grab the object and count everything
145  $counter = new self( $database );
146 
147  $counter->edits();
148  $counter->articles();
149  $counter->pages();
150  $counter->users();
151  $counter->files();
152 
153  $counter->refresh();
154 
155  // Count active users if need be
156  if ( $options['activeUsers'] ) {
158  }
159  }
160 
164  public static function doPlaceholderInit() {
165  $dbw = self::getDB( DB_PRIMARY );
166  $exists = (bool)$dbw->newSelectQueryBuilder()
167  ->select( '1' )
168  ->from( 'site_stats' )
169  ->where( [ 'ss_row_id' => 1 ] )
170  ->caller( __METHOD__ )->fetchField();
171  if ( !$exists ) {
172  $dbw->newInsertQueryBuilder()
173  ->insertInto( 'site_stats' )
174  ->ignore()
175  ->row( [ 'ss_row_id' => 1 ] + array_fill_keys( SiteStats::selectFields(), 0 ) )
176  ->caller( __METHOD__ )->execute();
177  }
178  }
179 
180  private function getShardedValue( $value, $noShards, $rowId ) {
181  $remainder = $value % $noShards;
182  $quotient = (int)( ( $value - $remainder ) / $noShards );
183  // Add the reminder to the first row
184  if ( $rowId === 1 ) {
185  return $quotient + $remainder;
186  }
187  return $quotient;
188  }
189 
193  public function refresh() {
194  if ( MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::MultiShardSiteStats ) ) {
195  $shardCnt = SiteStatsUpdate::SHARDS_ON;
196  for ( $i = 1; $i <= $shardCnt; $i++ ) {
197  $set = [
198  'ss_total_edits' => $this->getShardedValue( $this->edits ?? $this->edits(), $shardCnt, $i ),
199  'ss_good_articles' => $this->getShardedValue( $this->articles ?? $this->articles(), $shardCnt, $i ),
200  'ss_total_pages' => $this->getShardedValue( $this->pages ?? $this->pages(), $shardCnt, $i ),
201  'ss_users' => $this->getShardedValue( $this->users ?? $this->users(), $shardCnt, $i ),
202  'ss_images' => $this->getShardedValue( $this->files ?? $this->files(), $shardCnt, $i ),
203  ];
204  $row = [ 'ss_row_id' => $i ] + $set;
205  self::getDB( DB_PRIMARY )->newInsertQueryBuilder()
206  ->insertInto( 'site_stats' )
207  ->row( $row )
208  ->onDuplicateKeyUpdate()
209  ->uniqueIndexFields( [ 'ss_row_id' ] )
210  ->set( $set )
211  ->caller( __METHOD__ )->execute();
212  }
213  } else {
214  $set = [
215  'ss_total_edits' => $this->edits ?? $this->edits(),
216  'ss_good_articles' => $this->articles ?? $this->articles(),
217  'ss_total_pages' => $this->pages ?? $this->pages(),
218  'ss_users' => $this->users ?? $this->users(),
219  'ss_images' => $this->files ?? $this->files(),
220  ];
221  $row = [ 'ss_row_id' => 1 ] + $set;
222 
223  self::getDB( DB_PRIMARY )->newInsertQueryBuilder()
224  ->insertInto( 'site_stats' )
225  ->row( $row )
226  ->onDuplicateKeyUpdate()
227  ->uniqueIndexFields( [ 'ss_row_id' ] )
228  ->set( $set )
229  ->caller( __METHOD__ )->execute();
230  }
231  }
232 
238  private static function getDB( $index, $groups = [] ) {
240  ->getDBLoadBalancer()
241  ->getConnectionRef( $index, $groups );
242  }
243 }
244 
248 class_alias( SiteStatsInit::class, 'SiteStatsInit' );
getDB()
A class containing constants representing the names of configuration variables.
const ArticleCountMethod
Name constant for the ArticleCountMethod setting, for use with Config::get()
const MultiShardSiteStats
Name constant for the MultiShardSiteStats setting, for use with Config::get()
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Class designed for counting of stats.
static doPlaceholderInit()
Insert a dummy row with all zeroes if no row is present.
edits()
Count the total number of edits.
articles()
Count pages in article space(s)
static doAllAndCommit( $database, array $options=[])
Do all updates and commit them.
Class for handling updates to the site_stats table.
static cacheUpdate(IDatabase $dbw)
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:36
const DB_REPLICA
Definition: defines.php:26
const DB_PRIMARY
Definition: defines.php:28