]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/utils/BatchRowUpdate.php
MediaWiki 1.30.2-scripts
[autoinstalls/mediawiki.git] / includes / utils / BatchRowUpdate.php
1 <?php
2 /*
3  * Ties together the batch update components to provide a composable
4  * method of batch updating rows in a database. To use create a class
5  * implementing the RowUpdateGenerator interface and configure the
6  * BatchRowIterator and BatchRowWriter for access to the correct table.
7  * The components will handle reading, writing, and waiting for replica DBs
8  * while the generator implementation handles generating update arrays
9  * for singular rows.
10  *
11  * Instantiate:
12  *   $updater = new BatchRowUpdate(
13  *       new BatchRowIterator( $dbr, 'some_table', 'primary_key_column', 500 ),
14  *       new BatchRowWriter( $dbw, 'some_table', 'clusterName' ),
15  *       new MyImplementationOfRowUpdateGenerator
16  *   );
17  *
18  * Run:
19  *   $updater->execute();
20  *
21  * An example maintenance script utilizing the BatchRowUpdate can be
22  * located in the Echo extension file maintenance/updateSchema.php
23  *
24  * This program is free software; you can redistribute it and/or modify
25  * it under the terms of the GNU General Public License as published by
26  * the Free Software Foundation; either version 2 of the License, or
27  * (at your option) any later version.
28  *
29  * This program is distributed in the hope that it will be useful,
30  * but WITHOUT ANY WARRANTY; without even the implied warranty of
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32  * GNU General Public License for more details.
33  *
34  * You should have received a copy of the GNU General Public License along
35  * with this program; if not, write to the Free Software Foundation, Inc.,
36  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
37  * http://www.gnu.org/copyleft/gpl.html
38  *
39  * @file
40  * @ingroup Maintenance
41  */
42 class BatchRowUpdate {
43         /**
44          * @var BatchRowIterator $reader Iterator that returns an array of
45          *  database rows
46          */
47         protected $reader;
48
49         /**
50          * @var BatchRowWriter $writer Writer capable of pushing row updates
51          *  to the database
52          */
53         protected $writer;
54
55         /**
56          * @var RowUpdateGenerator $generator Generates single row updates
57          *  based on the rows content
58          */
59         protected $generator;
60
61         /**
62          * @var callable $output Output callback
63          */
64         protected $output;
65
66         /**
67          * @param BatchRowIterator $reader Iterator that returns an
68          *  array of database rows
69          * @param BatchRowWriter $writer Writer capable of pushing
70          *  row updates to the database
71          * @param RowUpdateGenerator $generator Generates single row updates
72          *  based on the rows content
73          */
74         public function __construct(
75                 BatchRowIterator $reader, BatchRowWriter $writer, RowUpdateGenerator $generator
76         ) {
77                 $this->reader = $reader;
78                 $this->writer = $writer;
79                 $this->generator = $generator;
80                 $this->output = function () {
81                 }; // nop
82         }
83
84         /**
85          * Runs the batch update process
86          */
87         public function execute() {
88                 foreach ( $this->reader as $rows ) {
89                         $updates = [];
90                         foreach ( $rows as $row ) {
91                                 $update = $this->generator->update( $row );
92                                 if ( $update ) {
93                                         $updates[] = [
94                                                 'primaryKey' => $this->reader->extractPrimaryKeys( $row ),
95                                                 'changes' => $update,
96                                         ];
97                                 }
98                         }
99
100                         if ( $updates ) {
101                                 $this->output( "Processing " . count( $updates ) . " rows\n" );
102                                 $this->writer->write( $updates );
103                         }
104                 }
105
106                 $this->output( "Completed\n" );
107         }
108
109         /**
110          * Accepts a callable which will receive a single parameter
111          * containing string status updates
112          *
113          * @param callable $output A callback taking a single string
114          *  parameter to output
115          */
116         public function setOutput( callable $output ) {
117                 $this->output = $output;
118         }
119
120         /**
121          * Write out a status update
122          *
123          * @param string $text The value to print
124          */
125         protected function output( $text ) {
126                 call_user_func( $this->output, $text );
127         }
128 }