/**
  * Rebuild the property info entries.
  * Use the rebuildPropertyInfo.php maintenance script to invoke this from the command line.
  *
  * Database updates a batched into multiple transactions. Do not call this
  * method within an (explicit) database transaction.
  *
  * @since 0.4
  */
 public function rebuildPropertyInfo()
 {
     $dbw = $this->propertyInfoTable->getWriteConnection();
     $rowId = $this->fromId - 1;
     $total = 0;
     $join = array();
     $tables = array('wb_entity_per_page');
     if (!$this->shouldUpdateAllEntities) {
         // Find properties in wb_entity_per_page with no corresponding
         // entry in wb_property_info.
         $piTable = $this->propertyInfoTable->getTableName();
         $tables[] = $piTable;
         $join[$piTable] = array('LEFT JOIN', array('pi_property_id = epp_entity_id'));
     }
     while (true) {
         // Make sure we are not running too far ahead of the slaves,
         // as that would cause the site to be rendered read only.
         wfWaitForSlaves();
         if ($this->useTransactions) {
             $dbw->begin();
         }
         //FIXME: use an EntityIdPager from EntityPerPage
         $props = $dbw->select($tables, array('epp_entity_id'), array('epp_entity_type = ' . $dbw->addQuotes(Property::ENTITY_TYPE), 'epp_entity_id > ' . (int) $rowId, 'epp_redirect_target IS NULL', $this->shouldUpdateAllEntities ? '1' : 'pi_property_id IS NULL'), __METHOD__, array('LIMIT' => $this->batchSize, 'ORDER BY' => 'epp_entity_id ASC', 'FOR UPDATE'), $join);
         $c = 0;
         foreach ($props as $row) {
             $id = PropertyId::newFromNumber((int) $row->epp_entity_id);
             $this->updatePropertyInfo($id);
             $rowId = $row->epp_entity_id;
             $c++;
         }
         if ($this->useTransactions) {
             $dbw->commit();
         }
         $this->reportMessage("Updated {$c} properties, up to ID {$rowId}.");
         $total += $c;
         if ($c < $this->batchSize) {
             // we are done.
             break;
         }
     }
     return $total;
 }
 /**
  * Wrapper for invoking PropertyInfoTableBuilder from DatabaseUpdater
  * during a database update.
  *
  * @param DatabaseUpdater $updater
  */
 public static function rebuildPropertyInfo(DatabaseUpdater $updater)
 {
     $reporter = new ObservableMessageReporter();
     $reporter->registerReporterCallback(function ($msg) use($updater) {
         $updater->output("..." . $msg . "\n");
     });
     $table = new PropertyInfoTable(false);
     $wikibaseRepo = WikibaseRepo::getDefaultInstance();
     $contentCodec = $wikibaseRepo->getEntityContentDataCodec();
     $propertyInfoBuilder = $wikibaseRepo->newPropertyInfoBuilder();
     $wikiPageEntityLookup = new WikiPageEntityRevisionLookup($contentCodec, new WikiPageEntityMetaDataLookup($wikibaseRepo->getEntityIdParser()), false);
     $cachingEntityLookup = new CachingEntityRevisionLookup($wikiPageEntityLookup, new HashBagOStuff());
     $entityLookup = new RevisionBasedEntityLookup($cachingEntityLookup);
     $builder = new PropertyInfoTableBuilder($table, $entityLookup, $propertyInfoBuilder);
     $builder->setReporter($reporter);
     $builder->setUseTransactions(false);
     $updater->output('Populating ' . $table->getTableName() . "\n");
     $builder->rebuildPropertyInfo();
 }