21 * Initialize private variables
23 * @param string $title
25 function LinksUpdate( $id, $title ) {
27 $this->mTitle
= $title;
31 * Update link tables with outgoing links from an updated article
32 * Relies on the 'link cache' to be filled out.
36 global $wgUseBetterLinksUpdate, $wgLinkCache, $wgDBtransactions;
37 global $wgEnablePersistentLC, $wgUseCategoryMagic;
39 $fname = 'LinksUpdate::doUpdate';
40 wfProfileIn( $fname );
45 $dbw =& wfGetDB( DB_MASTER
);
46 $pagelinks = $dbw->tableName( 'pagelinks' );
47 $imagelinks = $dbw->tableName( 'imagelinks' );
48 $categorylinks = $dbw->tableName( 'categorylinks' );
50 #------------------------------------------------------------------------------
53 if ( $wgLinkCache->incrementalSetup( LINKCACHE_PAGE
, $del, $add ) ) {
54 # Delete where necessary
55 if ( count( $del ) ) {
56 $batch = new LinkBatch( $del );
57 $set = $batch->constructSet( 'pl', $dbw );
59 $sql = "DELETE FROM $pagelinks WHERE pl_from={$this->mId} AND ($set)";
60 $dbw->query( $sql, $fname );
65 $dbw->delete( 'pagelinks', array( 'pl_from' => $this->mId
), $fname );
67 # Get the addition list
68 $add = $wgLinkCache->getGoodLinks();
72 if( 0 != count( $add ) ) {
74 foreach( $add as $lt => $target ) {
75 array_push( $arr, array(
76 'pl_from' => $this->mId
,
77 'pl_namespace' => $target->getNamespace(),
78 'pl_title' => $target->getDbKey() ) );
81 # The link cache was constructed without FOR UPDATE, so there may be collisions
82 # Ignoring for now, I'm not sure if that causes problems or not, but I'm fairly
83 # sure it's better than without IGNORE
84 $dbw->insert( 'pagelinks', $arr, $fname, array( 'IGNORE' ) );
87 #------------------------------------------------------------------------------
89 $dbw->delete('imagelinks',array('il_from'=>$this->mId
),$fname);
92 $add = $wgLinkCache->getImageLinks();
97 if ( 0 != count ( $add ) ) {
99 foreach ($add as $iname => $val ) {
100 $nt = Title
::makeTitle( $image, $iname );
102 $nt->invalidateCache();
103 array_push( $arr, array(
104 'il_from' => $this->mId
,
105 'il_to' => $iname ) );
107 $dbw->insert('imagelinks', $arr, $fname, array('IGNORE'));
110 #------------------------------------------------------------------------------
112 if( $wgUseCategoryMagic ) {
113 global $messageMemc, $wgDBname;
116 $add = $wgLinkCache->getCategoryLinks();
118 # select existing catlinks for this page
119 $res = $dbw->select( 'categorylinks',
120 array( 'cl_to', 'cl_sortkey' ),
121 array( 'cl_from' => $this->mId
),
126 if( 0 != $dbw->numRows( $res ) ) {
127 while( $row = $dbw->fetchObject( $res ) ) {
128 if( !isset( $add[$row->cl_to
] ) ||
$add[$row->cl_to
] != $row->cl_sortkey
) {
129 // in the db, but no longer in the page
130 // or sortkey has changed -> delete
131 $del[] = $row->cl_to
;
133 // remove already existing category memberships
134 // from the add array
135 unset( $add[$row->cl_to
] );
140 // delete any removed categorylinks
141 if( count( $del ) > 0) {
143 $dbw->delete( 'categorylinks',
145 'cl_from' => $this->mId
,
148 foreach( $del as $cname ){
149 $nt = Title
::makeTitle( NS_CATEGORY
, $cname );
150 $nt->invalidateCache();
151 // update the timestamp which indicates when the last article
152 // was added or removed to/from this article
153 $key = $wgDBname . ':Category:' . md5( $nt->getDBkey() ) . ':adddeltimestamp';
154 $messageMemc->set( $key , wfTimestamp( TS_MW
), 24*3600 );
158 // add any new category memberships
159 if( count( $add ) > 0 ) {
161 foreach( $add as $cname => $sortkey ) {
162 $nt = Title
::makeTitle( NS_CATEGORY
, $cname );
163 $nt->invalidateCache();
164 // update the timestamp which indicates when the last article
165 // was added or removed to/from this article
166 $key = $wgDBname . ':Category:' . md5( $nt->getDBkey() ) . ':adddeltimestamp';
167 $messageMemc->set( $key , wfTimestamp( TS_MW
), 24*3600 );
168 array_push( $arr, array(
169 'cl_from' => $this->mId
,
171 'cl_sortkey' => $sortkey ) );
173 // do the actual sql insertion
174 $dbw->insert( 'categorylinks', $arr, $fname, array( 'IGNORE' ) );
178 wfProfileOut( $fname );
182 * Link update which clears the previous entries and inserts new ones
183 * May be slower or faster depending on level of lock contention and write speed of DB
184 * Also useful where link table corruption needs to be repaired, e.g. in refreshLinks.php
186 function doDumbUpdate() {
187 global $wgLinkCache, $wgDBtransactions, $wgUseCategoryMagic;
188 $fname = 'LinksUpdate::doDumbUpdate';
189 wfProfileIn( $fname );
192 $dbw =& wfGetDB( DB_MASTER
);
193 $pagelinks = $dbw->tableName( 'pagelinks' );
194 $imagelinks = $dbw->tableName( 'imagelinks' );
195 $categorylinks = $dbw->tableName( 'categorylinks' );
197 $dbw->delete('pagelinks', array('pl_from'=>$this->mId
),$fname);
199 $a = $wgLinkCache->getPageLinks();
200 if ( 0 != count( $a ) ) {
202 foreach( $a as $lt => $target ) {
203 array_push( $arr, array(
204 'pl_from' => $this->mId
,
205 'pl_namespace' => $target->getNamespace(),
206 'pl_title' => $target->getTitle() ) );
208 $dbw->insert( 'pagelinks', $arr, $fname, array( 'IGNORE' ) );
211 $dbw->delete('imagelinks', array('il_from'=>$this->mId
),$fname);
213 $a = $wgLinkCache->getImageLinks();
215 if ( 0 != count ( $a ) ) {
217 foreach( $a as $iname => $val )
218 array_push( $arr, array(
219 'il_from' => $this->mId
,
220 'il_to' => $iname ) );
221 $dbw->insert( 'imagelinks', $arr, $fname, array( 'IGNORE' ) );
224 if( $wgUseCategoryMagic ) {
225 $dbw->delete('categorylinks', array('cl_from'=>$this->mId
),$fname);
228 $add = $wgLinkCache->getCategoryLinks();
232 if ( 0 != count ( $add ) ) {
234 foreach( $add as $cname => $sortkey ) {
235 # FIXME: Change all this to avoid unnecessary duplication
236 $nt = Title
::makeTitle( NS_CATEGORY
, $cname );
238 $nt->invalidateCache();
239 array_push( $arr, array(
240 'cl_from' => $this->mId
,
242 'cl_sortkey' => $sortkey ) );
244 $dbw->insert( 'categorylinks', $arr, $fname, array( 'IGNORE' ) );
247 wfProfileOut( $fname );