MediaWiki  master
DBFileJournal.php
Go to the documentation of this file.
1 <?php
27 use Wikimedia\Timestamp\ConvertibleTimestamp;
28 
33 class DBFileJournal extends FileJournal {
35  protected $domain;
36 
43  public function __construct( array $config ) {
44  parent::__construct( $config );
45 
46  $this->domain = $config['domain'] ?? $config['wiki']; // b/c
47  }
48 
55  protected function doLogChangeBatch( array $entries, $batchId ) {
56  $status = StatusValue::newGood();
57 
58  try {
59  $dbw = $this->getPrimaryDB();
60  } catch ( DBError $e ) {
61  return $status->fatal( 'filejournal-fail-dbconnect', $this->backend );
62  }
63 
64  $now = ConvertibleTimestamp::time();
65 
66  $data = [];
67  foreach ( $entries as $entry ) {
68  $data[] = [
69  'fj_batch_uuid' => $batchId,
70  'fj_backend' => $this->backend,
71  'fj_op' => $entry['op'],
72  'fj_path' => $entry['path'],
73  'fj_new_sha1' => $entry['newSha1'],
74  'fj_timestamp' => $dbw->timestamp( $now )
75  ];
76  }
77 
78  try {
79  $dbw->insert( 'filejournal', $data, __METHOD__ );
80  // XXX Should we do this deterministically so it's testable? Maybe look at the last two
81  // digits of a hash of a bunch of the data?
82  if ( mt_rand( 0, 99 ) == 0 ) {
83  // occasionally delete old logs
84  $this->purgeOldLogs(); // @codeCoverageIgnore
85  }
86  } catch ( DBError $e ) {
87  return $status->fatal( 'filejournal-fail-dbquery', $this->backend );
88  }
89 
90  return $status;
91  }
92 
97  protected function doGetCurrentPosition() {
98  $dbw = $this->getPrimaryDB();
99 
100  return $dbw->selectField( 'filejournal', 'MAX(fj_id)',
101  [ 'fj_backend' => $this->backend ],
102  __METHOD__
103  );
104  }
105 
111  protected function doGetPositionAtTime( $time ) {
112  $dbw = $this->getPrimaryDB();
113 
114  $encTimestamp = $dbw->addQuotes( $dbw->timestamp( $time ) );
115 
116  return $dbw->selectField( 'filejournal', 'fj_id',
117  [ 'fj_backend' => $this->backend, "fj_timestamp <= $encTimestamp" ],
118  __METHOD__,
119  [ 'ORDER BY' => 'fj_timestamp DESC' ]
120  );
121  }
122 
129  protected function doGetChangeEntries( $start, $limit ) {
130  $dbw = $this->getPrimaryDB();
131 
132  $res = $dbw->select( 'filejournal', '*',
133  [
134  'fj_backend' => $this->backend,
135  'fj_id >= ' . $dbw->addQuotes( (int)$start ) ], // $start may be 0
136  __METHOD__,
137  array_merge( [ 'ORDER BY' => 'fj_id ASC' ],
138  $limit ? [ 'LIMIT' => $limit ] : [] )
139  );
140 
141  $entries = [];
142  foreach ( $res as $row ) {
143  $item = [];
144  foreach ( (array)$row as $key => $value ) {
145  $item[substr( $key, 3 )] = $value; // "fj_op" => "op"
146  }
147  $entries[] = $item;
148  }
149 
150  return $entries;
151  }
152 
158  protected function doPurgeOldLogs() {
159  $status = StatusValue::newGood();
160  if ( $this->ttlDays <= 0 ) {
161  return $status; // nothing to do
162  }
163 
164  $dbw = $this->getPrimaryDB();
165  $dbCutoff = $dbw->timestamp( ConvertibleTimestamp::time() - 86400 * $this->ttlDays );
166 
167  $dbw->delete( 'filejournal',
168  [ 'fj_timestamp < ' . $dbw->addQuotes( $dbCutoff ) ],
169  __METHOD__
170  );
171 
172  return $status;
173  }
174 
182  protected function getPrimaryDB() {
183  $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
184 
185  return $lb->getConnectionRef( DB_PRIMARY, [], $this->domain, $lb::CONN_TRX_AUTOCOMMIT );
186  }
187 
195  protected function getMasterDB() {
196  wfDeprecated( __METHOD__, '1.37' );
197  return $this->getPrimaryDB();
198  }
199 }
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:193
DBFileJournal\doPurgeOldLogs
doPurgeOldLogs()
Definition: DBFileJournal.php:158
DBFileJournal
Version of FileJournal that logs to a DB table.
Definition: DBFileJournal.php:33
FileJournal\$backend
string $backend
Definition: FileJournal.php:43
DBFileJournal\doLogChangeBatch
doLogChangeBatch(array $entries, $batchId)
Definition: DBFileJournal.php:55
DBFileJournal\getPrimaryDB
getPrimaryDB()
Get a primary connection to the logging DB.
Definition: DBFileJournal.php:182
DBFileJournal\getMasterDB
getMasterDB()
Get a primary connection to the logging DB.
Definition: DBFileJournal.php:195
$res
$res
Definition: testCompression.php:57
Wikimedia\Rdbms\DBError
Database error base class @newable.
Definition: DBError.php:32
DBFileJournal\__construct
__construct(array $config)
Construct a new instance from configuration.
Definition: DBFileJournal.php:43
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
Definition: GlobalFunctions.php:997
FileJournal
Class for handling file operation journaling.
Definition: FileJournal.php:41
DBFileJournal\doGetChangeEntries
doGetChangeEntries( $start, $limit)
Definition: DBFileJournal.php:129
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
DB_PRIMARY
const DB_PRIMARY
Definition: defines.php:27
FileJournal\purgeOldLogs
purgeOldLogs()
Purge any old log entries.
Definition: FileJournal.php:201
DBFileJournal\doGetPositionAtTime
doGetPositionAtTime( $time)
Definition: DBFileJournal.php:111
DBFileJournal\doGetCurrentPosition
doGetCurrentPosition()
Definition: DBFileJournal.php:97
DBFileJournal\$domain
string $domain
Definition: DBFileJournal.php:35