r108216 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r108215‎ | r108216 | r108217 >
Date:11:35, 6 January 2012
Author:maxsem
Status:resolved
Tags:
Comment:
Tweaked schema, implemented smart updates that don't delete and re-insert everything on every save
Modified paths:
  • /trunk/extensions/GeoData/GeoData.body.php (modified) (history)
  • /trunk/extensions/GeoData/GeoData.sql (modified) (history)
  • /trunk/extensions/GeoData/GeoDataHooks.php (modified) (history)

Diff [purge]

Index: trunk/extensions/GeoData/GeoData.sql
@@ -2,6 +2,8 @@
33
44 -- Stores information about geographical coordinates in articles
55 CREATE TABLE /*_*/geo_tags (
 6+ -- Tag id, needed for selective replacement and paging
 7+ gt_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
68 -- page_id
79 gt_page_id int unsigned NOT NULL,
810 -- Name of planet or other astronomic body on which the coordinates reside
Index: trunk/extensions/GeoData/GeoData.body.php
@@ -17,21 +17,36 @@
1818 /**
1919 * Returns primary coordinates of the given page, if any
2020 * @param Title $title
21 - * @return Coord: Coordinates or false
 21+ * @return Coord|false: Coordinates or false
2222 */
2323 public static function getPageCoordinates( Title $title ) {
24 - $dbr = wfGetDB( DB_SLAVE );
25 - $row = $dbr->selectRow( 'geo_tags',
26 - array( 'gt_lat', 'gt_lon' ),
27 - array( 'gt_page_id' => $title->getArticleID(), 'gt_primary' => 1 )
28 - );
29 - if ( !$row ) {
30 - return false;
 24+ $coords = self::getAllCoordinates( $title->getArticleID(), array( 'gt_primary' => 1 ) );
 25+ if ( $coords ) {
 26+ return $coords[0];
3127 }
32 - return Coord::newFromRow( $row );
 28+ return false;
3329 }
3430
3531 /**
 32+ * Retrieves all coordinates for the given page id
 33+ *
 34+ * @param int $pageId: ID of the page
 35+ * @param Array $conds: Conditions for Database::select()
 36+ * @param int $dbType: Database to select from DM_MASTER or DB_SLAVE
 37+ * @return Array: Array of Coord objects
 38+ */
 39+ public static function getAllCoordinates( $pageId, $conds = array(), $dbType = DB_SLAVE ) {
 40+ $db = wfGetDB( $dbType );
 41+ $conds['gt_page_id'] = $pageId;
 42+ $res = $db->select( 'geo_tags', array_values( Coord::$fieldMapping ), $conds, __METHOD__ );
 43+ $coords = array();
 44+ foreach ( $res as $row ) {
 45+ $coords[] = Coord::newFromRow( $row );
 46+ }
 47+ return $coords;
 48+ }
 49+
 50+ /**
3651 * Parses coordinates
3752 * See https://en.wikipedia.org/wiki/Template:Coord for sample inputs
3853 *
@@ -197,6 +212,7 @@
198213 class Coord {
199214 public $lat,
200215 $lon,
 216+ $id,
201217 $globe,
202218 $primary = false,
203219 $dim,
@@ -224,7 +240,7 @@
225241 }
226242
227243 /**
228 - * Compares this coordinate with the given coordinate
 244+ * Compares this coordinates with the given coordinates
229245 *
230246 * @param Coord $coord: Coordinate to compare with
231247 * @param int $precision: Comparison precision
@@ -235,6 +251,25 @@
236252 && round( $this->lon, $precision ) == round( $coord->lon, $precision );
237253 }
238254
 255+ /**
 256+ * Compares all the fields of this object with the given coordinates object
 257+ *
 258+ * @param Coord $coord: Coordinate to compare with
 259+ * @param int $precision: Comparison precision
 260+ * @return Boolean
 261+ */
 262+ public function fullyEqualsTo( Coord $coord, $precision = 6 ) {
 263+ return round( $this->lat, $precision ) == round( $coord->lat, $precision )
 264+ && round( $this->lon, $precision ) == round( $coord->lon, $precision )
 265+ && $this->globe == $coord->globe
 266+ && $this->primary == $coord->primary
 267+ && $this->dim == $coord->dim
 268+ && $this->type == $coord->type
 269+ && $this->name == $coord->name
 270+ && $this->country == $coord->country
 271+ && $this->region == $coord->region;
 272+ }
 273+
239274 public function getRow( $pageId = null ) {
240275 $row = array( 'gt_page_id' => $pageId );
241276 foreach ( self::$fieldMapping as $field => $column ) {
@@ -244,6 +279,7 @@
245280 }
246281
247282 public static $fieldMapping = array(
 283+ 'id' => 'gt_id',
248284 'lat' => 'gt_lat',
249285 'lon' => 'gt_lon',
250286 'globe' => 'gt_globe',
Index: trunk/extensions/GeoData/GeoDataHooks.php
@@ -157,21 +157,60 @@
158158 * @param LinksUpdate $linksUpdate
159159 */
160160 public static function onLinksUpdate( &$linksUpdate ) {
 161+ global $wgUseDumbLinkUpdate;
161162 $out = $linksUpdate->mParserOutput;
162 - //@todo: less dumb update
163 - $dbw = wfGetDB( DB_MASTER );
164 - $dbw->delete( 'geo_tags', array( 'gt_page_id' => $linksUpdate->mId ), __METHOD__ );
 163+ $data = array();
165164 if ( isset( $out->geoData ) ) {
166165 $geoData = $out->geoData;
167 - $data = array();
168166 if ( $geoData['primary'] ) {
169 - $data[] = $geoData['primary']->getRow( $linksUpdate->mId );
 167+ $data[] = $geoData['primary'];
170168 }
171 - foreach ( $geoData['secondary'] as $coord ) {
172 - $data[] = $coord->getRow( $linksUpdate->mId );
173 - }
174 - $dbw->insert( 'geo_tags', $data, __METHOD__ );
 169+ $data = array_merge( $data, $geoData['secondary'] );
175170 }
 171+ if ( $wgUseDumbLinkUpdate || !count( $data ) ) {
 172+ self::doDumbUpdate( $data, $linksUpdate->mId );
 173+ } else {
 174+ self::doSmartUpdate( $data, $linksUpdate->mId );
 175+ }
176176 return true;
177177 }
 178+
 179+ private static function doDumbUpdate( $coords, $pageId ) {
 180+ $dbw = wfGetDB( DB_MASTER );
 181+ $dbw->delete( 'geo_tags', array( 'gt_page_id' => $pageId ), __METHOD__ );
 182+ $rows = array();
 183+ foreach ( $coords as $coord ) {
 184+ $rows[] = $coord->getRow( $pageId );
 185+ }
 186+ $dbw->insert( 'geo_tags', $data, __METHOD__ );
 187+ }
 188+
 189+ private static function doSmartUpdate( $coords, $pageId ) {
 190+ $prevCoords = GeoData::getAllCoordinates( $pageId, array(), DB_MASTER );
 191+ $add = array();
 192+ $delete = array();
 193+ foreach ( $prevCoords as $old ) {
 194+ $delete[$old->id] = $old;
 195+ }
 196+ foreach ( $coords as $new ) {
 197+ $match = false;
 198+ foreach ( $delete as $id => $old ) {
 199+ if ( $new->fullyEqualsTo( $old ) ) {
 200+ unset( $delete[$id] );
 201+ $match = true;
 202+ break;
 203+ }
 204+ }
 205+ if ( !$match ) {
 206+ $add[] = $new->getRow( $pageId );
 207+ }
 208+ }
 209+ $dbw = wfGetDB( DB_MASTER );
 210+ if ( count( $delete) ) {
 211+ $dbw->delete( 'geo_tags', array( 'gt_id' => array_keys( $delete ) ), __METHOD__ );
 212+ }
 213+ if ( count( $add ) ) {
 214+ $dbw->insert( 'geo_tags', $add, __METHOD__ );
 215+ }
 216+ }
178217 }

Follow-up revisions

RevisionCommit summaryAuthorDate
r108278Follow-up r108216: unbreak dumb updatesmaxsem20:21, 6 January 2012

Status & tagging log