MediaWiki  master
DBFileJournal.php
Go to the documentation of this file.
1 <?php
28 
33 class DBFileJournal extends FileJournal {
35  protected $dbw;
37  protected $domain;
38 
45  public function __construct( array $config ) {
46  parent::__construct( $config );
47 
48  $this->domain = $config['domain'] ?? $config['wiki']; // b/c
49  }
50 
57  protected function doLogChangeBatch( array $entries, $batchId ) {
58  $status = StatusValue::newGood();
59 
60  try {
61  $dbw = $this->getMasterDB();
62  } catch ( DBError $e ) {
63  $status->fatal( 'filejournal-fail-dbconnect', $this->backend );
64 
65  return $status;
66  }
67 
68  $now = ConvertibleTimestamp::time();
69 
70  $data = [];
71  foreach ( $entries as $entry ) {
72  $data[] = [
73  'fj_batch_uuid' => $batchId,
74  'fj_backend' => $this->backend,
75  'fj_op' => $entry['op'],
76  'fj_path' => $entry['path'],
77  'fj_new_sha1' => $entry['newSha1'],
78  'fj_timestamp' => $dbw->timestamp( $now )
79  ];
80  }
81 
82  try {
83  $dbw->insert( 'filejournal', $data, __METHOD__ );
84  // XXX Should we do this deterministically so it's testable? Maybe look at the last two
85  // digits of a hash of a bunch of the data?
86  if ( mt_rand( 0, 99 ) == 0 ) {
87  // occasionally delete old logs
88  $this->purgeOldLogs(); // @codeCoverageIgnore
89  }
90  } catch ( DBError $e ) {
91  $status->fatal( 'filejournal-fail-dbquery', $this->backend );
92 
93  return $status;
94  }
95 
96  return $status;
97  }
98 
103  protected function doGetCurrentPosition() {
104  $dbw = $this->getMasterDB();
105 
106  return $dbw->selectField( 'filejournal', 'MAX(fj_id)',
107  [ 'fj_backend' => $this->backend ],
108  __METHOD__
109  );
110  }
111 
117  protected function doGetPositionAtTime( $time ) {
118  $dbw = $this->getMasterDB();
119 
120  $encTimestamp = $dbw->addQuotes( $dbw->timestamp( $time ) );
121 
122  return $dbw->selectField( 'filejournal', 'fj_id',
123  [ 'fj_backend' => $this->backend, "fj_timestamp <= $encTimestamp" ],
124  __METHOD__,
125  [ 'ORDER BY' => 'fj_timestamp DESC' ]
126  );
127  }
128 
135  protected function doGetChangeEntries( $start, $limit ) {
136  $dbw = $this->getMasterDB();
137 
138  $res = $dbw->select( 'filejournal', '*',
139  [
140  'fj_backend' => $this->backend,
141  'fj_id >= ' . $dbw->addQuotes( (int)$start ) ], // $start may be 0
142  __METHOD__,
143  array_merge( [ 'ORDER BY' => 'fj_id ASC' ],
144  $limit ? [ 'LIMIT' => $limit ] : [] )
145  );
146 
147  $entries = [];
148  foreach ( $res as $row ) {
149  $item = [];
150  foreach ( (array)$row as $key => $value ) {
151  $item[substr( $key, 3 )] = $value; // "fj_op" => "op"
152  }
153  $entries[] = $item;
154  }
155 
156  return $entries;
157  }
158 
164  protected function doPurgeOldLogs() {
165  $status = StatusValue::newGood();
166  if ( $this->ttlDays <= 0 ) {
167  return $status; // nothing to do
168  }
169 
170  $dbw = $this->getMasterDB();
171  $dbCutoff = $dbw->timestamp( ConvertibleTimestamp::time() - 86400 * $this->ttlDays );
172 
173  $dbw->delete( 'filejournal',
174  [ 'fj_timestamp < ' . $dbw->addQuotes( $dbCutoff ) ],
175  __METHOD__
176  );
177 
178  return $status;
179  }
180 
187  protected function getMasterDB() {
188  if ( !$this->dbw ) {
189  // Get a separate connection in autocommit mode
190  $lb = MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->newMainLB();
191  $this->dbw = $lb->getConnection( DB_MASTER, [], $this->domain );
192  $this->dbw->clearFlag( DBO_TRX );
193  }
194 
195  return $this->dbw;
196  }
197 }
string $backend
Definition: FileJournal.php:42
getMasterDB()
Get a master connection to the logging DB.
selectField( $table, $var, $cond='', $fname=__METHOD__, $options=[], $join_conds=[])
A SELECT wrapper which returns a single field from a single result row.
doLogChangeBatch(array $entries, $batchId)
const DB_MASTER
Definition: defines.php:26
timestamp( $ts=0)
Convert a timestamp in one of the formats accepted by ConvertibleTimestamp to the format used for ins...
__construct(array $config)
Construct a new instance from configuration.
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:81
Version of FileJournal that logs to a DB table.
doGetPositionAtTime( $time)
doGetChangeEntries( $start, $limit)
const DBO_TRX
Definition: defines.php:12
insert( $table, $rows, $fname=__METHOD__, $options=[])
INSERT wrapper, inserts an array into a table.
IDatabase $dbw
select( $table, $vars, $conds='', $fname=__METHOD__, $options=[], $join_conds=[])
Execute a SELECT query constructed using the various parameters provided.
purgeOldLogs()
Purge any old log entries.
delete( $table, $conds, $fname=__METHOD__)
DELETE query wrapper.
addQuotes( $s)
Escape and quote a raw value string for use in a SQL query.
Database error base class.
Definition: DBError.php:30
Class for handling file operation journaling.
Definition: FileJournal.php:40