]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/LinksUpdate.php
MediaWiki 1.5.8 (initial commit)
[autoinstallsdev/mediawiki.git] / includes / LinksUpdate.php
1 <?php
2 /**
3  * See deferred.txt
4  * @package MediaWiki
5  */
6
7 /**
8  * @todo document
9  * @package MediaWiki
10  */
11 class LinksUpdate {
12
13         /**#@+
14          * @access private
15          */
16         var $mId, $mTitle;
17         /**#@-*/
18
19         /**
20          * Constructor
21          * Initialize private variables
22          * @param integer $id
23          * @param string $title
24          */
25         function LinksUpdate( $id, $title ) {
26                 $this->mId = $id;
27                 $this->mTitle = $title;
28         }
29
30         /**
31          * Update link tables with outgoing links from an updated article
32          * Relies on the 'link cache' to be filled out.
33          */
34         
35         function doUpdate() {
36                 global $wgUseDumbLinkUpdate, $wgLinkCache, $wgDBtransactions;
37                 global $wgUseCategoryMagic;
38
39                 if ( $wgUseDumbLinkUpdate ) {
40                         $this->doDumbUpdate();
41                         return;
42                 }
43
44                 $fname = 'LinksUpdate::doUpdate';
45                 wfProfileIn( $fname );
46
47                 $del = array();
48                 $add = array();
49
50                 $dbw =& wfGetDB( DB_MASTER );
51                 $pagelinks = $dbw->tableName( 'pagelinks' );
52                 $imagelinks = $dbw->tableName( 'imagelinks' );
53                 $categorylinks = $dbw->tableName( 'categorylinks' );
54                 
55                 #------------------------------------------------------------------------------
56                 # Good links
57
58                 if ( $wgLinkCache->incrementalSetup( LINKCACHE_PAGE, $del, $add ) ) {
59                         # Delete where necessary
60                         if ( count( $del ) ) {
61                                 $batch = new LinkBatch( $del );
62                                 $set = $batch->constructSet( 'pl', $dbw );
63                                 if ( $set ) {
64                                         $sql = "DELETE FROM $pagelinks WHERE pl_from={$this->mId} AND ($set)";
65                                         $dbw->query( $sql, $fname );
66                                 }
67                         }
68                 } else {
69                         # Delete everything
70                         $dbw->delete( 'pagelinks', array( 'pl_from' => $this->mId ), $fname );
71                                                 
72                         # Get the addition list
73                         $add = $wgLinkCache->getPageLinks();
74                 }
75
76                 # Do the insertion
77                 if( 0 != count( $add ) ) {
78                         $arr = array();
79                         foreach( $add as $lt => $target ) {
80                                 array_push( $arr, array(
81                                                         'pl_from' => $this->mId,
82                                                         'pl_namespace' => $target->getNamespace(),
83                                                         'pl_title'     => $target->getDbKey() ) );
84                         }
85                         
86                         # The link cache was constructed without FOR UPDATE, so there may be collisions
87                         # Ignoring for now, I'm not sure if that causes problems or not, but I'm fairly
88                         # sure it's better than without IGNORE
89                         $dbw->insert( 'pagelinks', $arr, $fname, array( 'IGNORE' ) );
90                 }
91
92                 #------------------------------------------------------------------------------
93                 # Image links
94                 $dbw->delete('imagelinks',array('il_from'=>$this->mId),$fname);
95                 
96                 # Get addition list
97                 $add = $wgLinkCache->getImageLinks();
98                 
99                 # Do the insertion
100                 $sql = '';
101                 $image = NS_IMAGE;
102                 if ( 0 != count ( $add ) ) {
103                         $arr = array();
104                         foreach ($add as $iname => $val ) {
105                                 $nt = Title::makeTitle( $image, $iname );
106                                 if( !$nt ) continue;
107                                 $nt->invalidateCache();
108                                 array_push( $arr, array(
109                                         'il_from' => $this->mId,
110                                         'il_to'   => $iname ) );
111                         }
112                         $dbw->insert('imagelinks', $arr, $fname, array('IGNORE'));
113                 }
114
115                 #------------------------------------------------------------------------------
116                 # Category links
117                 if( $wgUseCategoryMagic ) {
118                         global $messageMemc, $wgDBname;
119                         
120                         # Get addition list
121                         $add = $wgLinkCache->getCategoryLinks();
122                         
123                         # select existing catlinks for this page
124                         $res = $dbw->select( 'categorylinks',
125                                 array( 'cl_to', 'cl_sortkey' ),
126                                 array( 'cl_from' => $this->mId ), 
127                                 $fname,
128                                 'FOR UPDATE' );
129
130                         $del = array();
131                         if( 0 != $dbw->numRows( $res ) ) {
132                                 while( $row = $dbw->fetchObject( $res ) ) {
133                                         if( !isset( $add[$row->cl_to] ) || $add[$row->cl_to] != $row->cl_sortkey ) {
134                                                 // in the db, but no longer in the page
135                                                 // or sortkey has changed -> delete
136                                                 $del[] = $row->cl_to;
137                                         } else {
138                                                 // remove already existing category memberships
139                                                 // from the add array
140                                                 unset( $add[$row->cl_to] );
141                                         }
142                                 }
143                         }
144                         
145                         // delete any removed categorylinks
146                         if( count( $del ) > 0) {
147                                 // delete old ones
148                                 $dbw->delete( 'categorylinks',
149                                         array(
150                                                 'cl_from' => $this->mId,
151                                                 'cl_to'   => $del ),
152                                         $fname );
153                                 foreach( $del as $cname ){
154                                         $nt = Title::makeTitle( NS_CATEGORY, $cname );
155                                         $nt->invalidateCache();
156                                         // update the timestamp which indicates when the last article
157                                         // was added or removed to/from this article
158                                         $key = $wgDBname . ':Category:' . md5( $nt->getDBkey() ) . ':adddeltimestamp';
159                                         $messageMemc->set( $key , wfTimestamp( TS_MW ), 24*3600 );
160                                 }
161                         }
162                         
163                         // add any new category memberships
164                         if( count( $add ) > 0 ) {
165                                 $arr = array();
166                                 foreach( $add as $cname => $sortkey ) {
167                                         $nt = Title::makeTitle( NS_CATEGORY, $cname );
168                                         $nt->invalidateCache();
169                                         // update the timestamp which indicates when the last article
170                                         // was added or removed to/from this article
171                                         $key = $wgDBname . ':Category:' . md5( $nt->getDBkey() ) . ':adddeltimestamp';
172                                         $messageMemc->set( $key , wfTimestamp( TS_MW ), 24*3600 );
173                                         array_push( $arr, array(
174                                                 'cl_from'    => $this->mId,
175                                                 'cl_to'      => $cname,
176                                                 'cl_sortkey' => $sortkey ) );
177                                 }
178                                 // do the actual sql insertion
179                                 $dbw->insert( 'categorylinks', $arr, $fname, array( 'IGNORE' ) );
180                         }
181                 }
182                 
183                 wfProfileOut( $fname );
184         }
185
186         /**
187           * Link update which clears the previous entries and inserts new ones
188           * May be slower or faster depending on level of lock contention and write speed of DB
189           * Also useful where link table corruption needs to be repaired, e.g. in refreshLinks.php
190          */
191         function doDumbUpdate() {
192                 global $wgLinkCache, $wgDBtransactions, $wgUseCategoryMagic;
193                 $fname = 'LinksUpdate::doDumbUpdate';
194                 wfProfileIn( $fname );
195                 
196                 
197                 $dbw =& wfGetDB( DB_MASTER );
198                 $pagelinks = $dbw->tableName( 'pagelinks' );
199                 $imagelinks = $dbw->tableName( 'imagelinks' );
200                 $categorylinks = $dbw->tableName( 'categorylinks' );
201                 
202                 $dbw->delete('pagelinks', array('pl_from'=>$this->mId),$fname);
203
204                 $a = $wgLinkCache->getPageLinks();
205                 if ( 0 != count( $a ) ) {
206                         $arr = array();
207                         foreach( $a as $lt => $target ) {
208                                 array_push( $arr, array(
209                                         'pl_from'      => $this->mId,
210                                         'pl_namespace' => $target->getNamespace(),
211                                         'pl_title'     => $target->getDBkey() ) );
212                         }
213                         $dbw->insert( 'pagelinks', $arr, $fname, array( 'IGNORE' ) );
214                 }
215
216                 $dbw->delete('imagelinks', array('il_from'=>$this->mId),$fname);
217
218                 $a = $wgLinkCache->getImageLinks();
219                 $sql = '';
220                 if ( 0 != count ( $a ) ) {
221                         $arr = array();
222                         foreach( $a as $iname => $val )
223                                 array_push( $arr, array(
224                                         'il_from' => $this->mId,
225                                         'il_to'   => $iname ) );
226                         $dbw->insert( 'imagelinks', $arr, $fname, array( 'IGNORE' ) );
227                 }
228
229                 if( $wgUseCategoryMagic ) {
230                         $dbw->delete('categorylinks', array('cl_from'=>$this->mId),$fname);
231                         
232                         # Get addition list
233                         $add = $wgLinkCache->getCategoryLinks();
234                         
235                         # Do the insertion
236                         $sql = '';
237                         if ( 0 != count ( $add ) ) {
238                                 $arr = array();
239                                 foreach( $add as $cname => $sortkey ) {
240                                         # FIXME: Change all this to avoid unnecessary duplication
241                                         $nt = Title::makeTitle( NS_CATEGORY, $cname );
242                                         if( !$nt ) continue;
243                                         $nt->invalidateCache();
244                                         array_push( $arr, array(
245                                                 'cl_from'    => $this->mId,
246                                                 'cl_to'      => $cname,
247                                                 'cl_sortkey' => $sortkey ) );
248                                 }
249                                 $dbw->insert( 'categorylinks', $arr, $fname, array( 'IGNORE' ) );
250                         }
251                 }
252                 wfProfileOut( $fname );
253         }
254 }
255 ?>