public function testDeleteConceptCache()
 {
     $connection = $this->getMockBuilder('\\SMW\\MediaWiki\\Database')->disableOriginalConstructor()->getMock();
     $connection->expects($this->any())->method('selectRow')->will($this->returnValue(false));
     $connection->expects($this->once())->method('delete');
     $connectionManager = $this->getMockBuilder('\\SMW\\ConnectionManager')->disableOriginalConstructor()->getMock();
     $connectionManager->expects($this->atLeastOnce())->method('getConnection')->will($this->returnValue($connection));
     $store = new \SMWSQLStore3();
     $store->setConnectionManager($connectionManager);
     $conceptQueryResolver = $this->getMockBuilder('\\SMW\\SQLStore\\QueryEngine\\ConceptQueryResolver')->disableOriginalConstructor()->getMock();
     $instance = new ConceptCache($store, $conceptQueryResolver);
     $instance->deleteConceptCache(Title::newFromText('Foo', SMW_NS_CONCEPT));
 }
 /**
  * Get a SQL option array for the given query and preprocessed query object at given id.
  *
  * @param Query $query
  * @param integer $rootId
  *
  * @return array
  */
 private function getSQLOptions(Query $query, $rootId)
 {
     $result = array('LIMIT' => $query->getLimit() + 5, 'OFFSET' => $query->getOffset());
     // Build ORDER BY options using discovered sorting fields.
     if ($this->engineOptions->get('smwgQSortingSupport')) {
         $qobj = $this->querySegments[$rootId];
         foreach ($this->sortKeys as $propkey => $order) {
             if (!is_string($propkey)) {
                 throw new RuntimeException("Expected a string value as sortkey");
             }
             // #835
             // SELECT DISTINCT and ORDER BY RANDOM causes an issue for postgres
             // Disable RANDOM support for postgres
             if ($this->store->getConnection()->getType() === 'postgres') {
                 $this->engineOptions->set('smwgQRandSortingSupport', false);
             }
             if ($order != 'RANDOM' && array_key_exists($propkey, $qobj->sortfields)) {
                 // Field was successfully added.
                 $result['ORDER BY'] = (array_key_exists('ORDER BY', $result) ? $result['ORDER BY'] . ', ' : '') . $qobj->sortfields[$propkey] . " {$order} ";
             } elseif ($order == 'RANDOM' && $this->engineOptions->get('smwgQRandSortingSupport')) {
                 $result['ORDER BY'] = (array_key_exists('ORDER BY', $result) ? $result['ORDER BY'] . ', ' : '') . ' RAND() ';
             }
         }
     }
     return $result;
 }
 /**
  * Get the array of all stored values for some property.
  *
  * @since 1.8
  *
  * @param $property SMWDIProperty
  *
  * @return array of SMWDataItem
  */
 public function getPropertyValues(SMWDIProperty $property)
 {
     if ($property->isInverse()) {
         // we never have any data for inverses
         return array();
     }
     if (array_key_exists($property->getKey(), $this->mStubPropVals)) {
         // Not catching exception here; the
         $this->unstubProperty($property->getKey(), $property);
         $propertyTypeId = $property->findPropertyTypeID();
         $propertyDiId = SMWDataValueFactory::getDataItemId($propertyTypeId);
         foreach ($this->mStubPropVals[$property->getKey()] as $dbkeys) {
             try {
                 $diHandler = $this->store->getDataItemHandlerForDIType($propertyDiId);
                 $di = $diHandler->dataItemFromDBKeys($dbkeys);
                 if ($this->mNoDuplicates) {
                     $this->mPropVals[$property->getKey()][$di->getHash()] = $di;
                 } else {
                     $this->mPropVals[$property->getKey()][] = $di;
                 }
             } catch (SMWDataItemException $e) {
                 // ignore data
             }
         }
         unset($this->mStubPropVals[$property->getKey()]);
     }
     return parent::getPropertyValues($property);
 }
 private function addSubSemanticDataToInternalCache(DIProperty $property)
 {
     foreach ($this->getPropertyValues($property) as $value) {
         if ($value instanceof DIWikiPage && $value->getSubobjectName() !== '' && !$this->hasSubSemanticData($value->getSubobjectName())) {
             $this->addSubSemanticData($this->store->getSemanticData($value));
         }
     }
 }
 public function drop($verbose = true)
 {
     global $wgDBtype;
     $this->reportProgress("Deleting all database content and tables generated by SMW ...\n\n", $verbose);
     $dbw = $this->store->getConnection('mw.db');
     $tables = array(SMWSQLStore3::ID_TABLE, SMWSQLStore3::CONCEPT_CACHE_TABLE, SMWSQLStore3::PROPERTY_STATISTICS_TABLE, SMWSQLStore3::QUERY_LINKS_TABLE);
     foreach ($this->store->getPropertyTables() as $proptable) {
         $tables[] = $proptable->getName();
     }
     foreach ($tables as $table) {
         $name = $dbw->tableName($table);
         $dbw->query('DROP TABLE ' . ($wgDBtype == 'postgres' ? '' : 'IF EXISTS ') . $name, 'SMWSQLStore3::drop');
         $this->reportProgress(" ... dropped table {$name}.\n", $verbose);
     }
     $this->reportProgress("All data removed successfully.\n", $verbose);
     return true;
 }
 /**
  * Implementation of SMWStore::getInProperties(). This function is meant to
  * be used for finding properties that link to wiki pages.
  *
  * @since 1.8
  * @see SMWStore::getInProperties
  * @param SMWDataItem $value
  * @param SMWRequestOptions $requestoptions
  *
  * @return array of SMWWikiPageValue
  */
 public function getInProperties(SMWDataItem $value, $requestoptions = null)
 {
     wfProfileIn("SMWSQLStore3::getInProperties (SMW)");
     $db = wfGetDB(DB_SLAVE);
     $result = array();
     // Potentially need to get more results, since options apply to union.
     if ($requestoptions !== null) {
         $suboptions = clone $requestoptions;
         $suboptions->limit = $requestoptions->limit + $requestoptions->offset;
         $suboptions->offset = 0;
     } else {
         $suboptions = null;
     }
     $diType = $value->getDIType();
     foreach (SMWSQLStore3::getPropertyTables() as $proptable) {
         if ($diType != $proptable->diType) {
             continue;
         }
         $where = $from = '';
         if ($proptable->fixedproperty == false) {
             // join smw_ids to get property titles
             $from = $db->tableName('smw_ids') . " INNER JOIN " . $db->tableName($proptable->name) . " AS t1 ON t1.p_id=smw_id";
             $this->prepareValueQuery($from, $where, $proptable, $value, 1);
             $res = $db->select($from, 'DISTINCT smw_title,smw_sortkey', $where . $this->store->getSQLConditions($suboptions, 'smw_sortkey', 'smw_sortkey', $where !== ''), 'SMW::getInProperties', $this->store->getSQLOptions($suboptions, 'smw_sortkey'));
             foreach ($res as $row) {
                 try {
                     $result[] = new SMWDIProperty($row->smw_title);
                 } catch (SMWDataItemException $e) {
                     // has been observed to happen (empty property title); cause unclear; ignore this data
                 }
             }
         } else {
             $from = $db->tableName($proptable->name) . " AS t1";
             $this->prepareValueQuery($from, $where, $proptable, $value, 1);
             $res = $db->select($from, '*', $where, 'SMW::getInProperties', array('LIMIT' => 1));
             if ($db->numRows($res) > 0) {
                 $result[] = new SMWDIProperty($proptable->fixedproperty);
             }
         }
         $db->freeResult($res);
     }
     $result = $this->store->applyRequestOptions($result, $requestoptions);
     // apply options to overall result
     wfProfileOut("SMWSQLStore3::getInProperties (SMW)");
     return $result;
 }
 /**
  * Implementation of SMWStore::getInProperties(). This function is meant to
  * be used for finding properties that link to wiki pages.
  *
  * @since 1.8
  * @see SMWStore::getInProperties
  *
  * @param SMWDataItem $value
  * @param SMWRequestOptions|null $requestOptions
  *
  * @return array of SMWWikiPageValue
  */
 public function getInProperties(SMWDataItem $value, SMWRequestOptions $requestOptions = null)
 {
     $db = $this->store->getConnection();
     $result = array();
     // Potentially need to get more results, since options apply to union.
     if ($requestOptions !== null) {
         $subOptions = clone $requestOptions;
         $subOptions->limit = $requestOptions->limit + $requestOptions->offset;
         $subOptions->offset = 0;
     } else {
         $subOptions = null;
     }
     $diType = $value->getDIType();
     foreach ($this->store->getPropertyTables() as $proptable) {
         if ($diType != $proptable->getDiType()) {
             continue;
         }
         $where = $from = '';
         if (!$proptable->isFixedPropertyTable()) {
             // join ID table to get property titles
             $from = $db->tableName(SMWSql3SmwIds::TABLE_NAME) . " INNER JOIN " . $db->tableName($proptable->getName()) . " AS t1 ON t1.p_id=smw_id";
             $this->prepareValueQuery($from, $where, $proptable, $value, 1);
             $where .= " AND smw_iw!=" . $db->addQuotes(SMW_SQL3_SMWIW_OUTDATED) . " AND smw_iw!=" . $db->addQuotes(SMW_SQL3_SMWDELETEIW);
             $res = $db->select($from, 'DISTINCT smw_title,smw_sortkey,smw_iw', $where . $this->store->getSQLConditions($subOptions, 'smw_sortkey', 'smw_sortkey', $where !== ''), __METHOD__, $this->store->getSQLOptions($subOptions, 'smw_sortkey'));
             foreach ($res as $row) {
                 try {
                     $result[] = new SMW\DIProperty($row->smw_title);
                 } catch (SMWDataItemException $e) {
                     // has been observed to happen (empty property title); cause unclear; ignore this data
                 }
             }
         } else {
             $from = $db->tableName($proptable->getName()) . " AS t1";
             $this->prepareValueQuery($from, $where, $proptable, $value, 1);
             $res = $db->select($from, '*', $where, __METHOD__, array('LIMIT' => 1));
             if ($db->numRows($res) > 0) {
                 $result[] = new SMW\DIProperty($proptable->getFixedProperty());
             }
         }
         $db->freeResult($res);
     }
     $result = $this->store->applyRequestOptions($result, $requestOptions);
     // apply options to overall result
     return $result;
 }
 public function execute()
 {
     $options = array();
     if ($this->hasArg(0)) {
         if ($this->hasArg(1)) {
             $options['LIMIT'] = $this->getArg(0);
             $options['OFFSET'] = $this->getArg(1);
         }
     }
     $dbw = wfGetDB(DB_MASTER);
     $res = $dbw->select('smw_ids', array('smw_id', 'smw_title', 'smw_sortkey'), array('smw_namespace' => SMW_NS_PROPERTY), __METHOD__, $options);
     $proptables = SMWSQLStore3::getPropertyTables();
     foreach ($res as $row) {
         $di = new SMWDIProperty($row->smw_title);
         $tableId = SMWSQLStore3::findPropertyTableID($di);
         $proptable = $proptables[$tableId];
         $propRow = $dbw->selectRow($proptable->name, 'Count(*) as count', $proptable->fixedproperty ? array() : array('p_id' => $row->smw_id), __METHOD__);
         echo 'Usage count for ' . $row->smw_title . ' is ' . $propRow->count . "\n";
         $dbw->replace('smw_stats', 'pid', array('pid' => $row->smw_id, 'usage_count' => $propRow->count), __METHOD__);
     }
     $dbw->freeResult($res);
 }
 /**
  * Update the proptable_hash for a given page.
  *
  * @since 1.8
  * @param integer $sid ID of the page as stored in SMW IDs table
  * @param string[] of hash values with table names as keys
  */
 public function setPropertyTableHashes($sid, array $newTableHashes)
 {
     $db = $this->store->getConnection();
     $propertyTableHash = serialize($newTableHashes);
     $db->update(self::tableName, array('smw_proptable_hash' => $propertyTableHash), array('smw_id' => $sid), __METHOD__);
     if ($sid == $this->hashCacheId) {
         $this->setPropertyTableHashesCache($sid, $propertyTableHash);
     }
 }
 /**
  * Modify the given query object to account for some property condition for
  * the given property. If it is not possible to generate a query for the
  * given data, the query type is changed to SMWSQLStore3Query::Q_NOQUERY. Callers need
  * to check for this and discard the query in this case.
  *
  * @note This method does not support sortkey (_SKEY) property queries,
  * since they do not have a normal property table. This should not be a
  * problem since comparators on sortkeys are supported indirectly when
  * using comparators on wikipages. There is no reason to create any
  * query with _SKEY ad users cannot do so either (no user label).
  *
  * @since 1.8
  */
 protected function compileSomePropertyDescription(SMWSQLStore3Query $query, SMWSomeProperty $description)
 {
     $property = $description->getProperty();
     $tableid = SMWSQLStore3::findPropertyTableID($property);
     if ($tableid === '') {
         // Give up
         $query->type = SMWSQLStore3Query::Q_NOQUERY;
         return;
     }
     $proptables = SMWSQLStore3::getPropertyTables();
     $proptable = $proptables[$tableid];
     if (!$proptable->usesIdSubject()) {
         // no queries with such tables
         // (only redirects are affected in practice)
         $query->type = SMWSQLStore3Query::Q_NOQUERY;
         return;
     }
     $typeid = $property->findPropertyTypeID();
     $diType = SMWDataValueFactory::getDataItemId($typeid);
     if ($property->isInverse() && $diType != SMWDataItem::TYPE_WIKIPAGE) {
         // can only invert properties that point to pages
         $query->type = SMWSQLStore3Query::Q_NOQUERY;
         return;
     }
     $diHandler = $this->m_store->getDataItemHandlerForDIType($diType);
     $indexField = $diHandler->getIndexField();
     $sortkey = $property->getKey();
     // TODO: strictly speaking, the DB key is not what we want here, since sortkey is based on a "wiki value"
     // *** Now construct the query ... ***//
     $query->jointable = $proptable->getName();
     // *** Add conditions for selecting rows for this property ***//
     if (!$proptable->isFixedPropertyTable()) {
         $pid = $this->m_store->smwIds->getSMWPropertyID($property);
         // Construct property hierarchy:
         $pqid = SMWSQLStore3Query::$qnum;
         $pquery = new SMWSQLStore3Query();
         $pquery->type = SMWSQLStore3Query::Q_PROP_HIERARCHY;
         $pquery->joinfield = array($pid);
         $query->components[$pqid] = "{$query->alias}.p_id";
         $this->m_queries[$pqid] = $pquery;
         // Alternative code without property hierarchies:
         // $query->where = "{$query->alias}.p_id=" . $this->m_dbs->addQuotes( $pid );
     }
     // else: no property column, no hierarchy queries
     // *** Add conditions on the value of the property ***//
     if ($diType == SMWDataItem::TYPE_WIKIPAGE) {
         $o_id = $indexField;
         if ($property->isInverse()) {
             $s_id = $o_id;
             $o_id = 's_id';
         } else {
             $s_id = 's_id';
         }
         $query->joinfield = "{$query->alias}.{$s_id}";
         // process page description like main query
         $sub = $this->compileQueries($description->getDescription());
         if ($sub >= 0) {
             $query->components[$sub] = "{$query->alias}.{$o_id}";
         }
         if (array_key_exists($sortkey, $this->m_sortkeys)) {
             // TODO: This SMW IDs table is possibly duplicated in the query.
             // Example: [[has capital::!Berlin]] with sort=has capital
             // Can we prevent that? (PERFORMANCE)
             $query->from = ' INNER JOIN ' . $this->m_dbs->tableName(SMWSql3SmwIds::tableName) . " AS ids{$query->alias} ON ids{$query->alias}.smw_id={$query->alias}.{$o_id}";
             $query->sortfields[$sortkey] = "ids{$query->alias}.smw_sortkey";
         }
     } else {
         // non-page value description
         $query->joinfield = "{$query->alias}.s_id";
         $this->compilePropertyValueDescription($query, $description->getDescription(), $proptable, $diHandler, 'AND');
         if (array_key_exists($sortkey, $this->m_sortkeys)) {
             $query->sortfields[$sortkey] = "{$query->alias}.{$indexField}";
         }
     }
 }
 /**
  * Helper method to write information about some redirect. Various updates
  * can be necessary if redirects are resolved as identities in SMW. The
  * title and namespace of the affected page and of its updated redirect
  * target are given. The target can be empty ('') to delete any redirect.
  * Returns the canonical ID that is now to be used for the subject.
  *
  * This method does not change the ids of the affected pages, and thus it
  * is not concerned with updates of the data that is currently stored for
  * the subject. Normally, a subject that is a redirect will not have other
  * data, but this method does not depend on this.
  *
  * @note Please make sure you fully understand this code before making any
  * changes here. Keeping the redirect structure consistent is important,
  * and errors in this code can go unnoticed for quite some time.
  *
  * @note This method merely handles the addition or deletion of a redirect
  * statement in the wiki. It does not assume that any page contents has
  * been changed (e.g. moved). See changeTitle() for additional handling in
  * this case.
  *
  * @todo Clean up this code.
  *
  * @since 1.8
  * @param string $subject_t
  * @param integer $subject_ns
  * @param string $curtarget_t
  * @param integer $curtarget_ns
  * @return integer the new canonical ID of the subject
  */
 protected function updateRedirects($subject_t, $subject_ns, $curtarget_t = '', $curtarget_ns = -1)
 {
     global $smwgQEqualitySupport, $smwgEnableUpdateJobs;
     $count = 0;
     //track count changes for redi property
     // *** First get id of subject, old redirect target, and current (new) redirect target ***//
     $sid_sort = '';
     $sid = $this->store->smwIds->getSMWPageIDandSort($subject_t, $subject_ns, '', '', $sid_sort, false);
     // find real id of subject, if any
     /// NOTE: $sid can be 0 here; this is useful to know since it means that fewer table updates are needed
     $new_tid = $curtarget_t ? $this->store->smwIds->makeSMWPageID($curtarget_t, $curtarget_ns, '', '', false) : 0;
     // real id of new target, if given
     $db = wfGetDB(DB_SLAVE);
     $row = $db->selectRow(array('smw_fpt_redi'), 'o_id', array('s_title' => $subject_t, 's_namespace' => $subject_ns), __METHOD__);
     $old_tid = $row !== false ? $row->o_id : 0;
     // real id of old target, if any
     /// NOTE: $old_tid and $new_tid both (intentionally) ignore further redirects: no redirect chains
     if ($old_tid == $new_tid) {
         // no change, all happy
         return $new_tid == 0 ? $sid : $new_tid;
     }
     // note that this means $old_tid != $new_tid in all cases below
     // *** Make relevant changes in property tables (don't write the new redirect yet) ***//
     $db = wfGetDB(DB_MASTER);
     // now we need to write something
     if ($old_tid == 0 && $sid != 0 && $smwgQEqualitySupport != SMW_EQ_NONE) {
         // new redirect
         // $smwgQEqualitySupport requires us to change all tables' page references from $sid to $new_tid.
         // Since references must not be 0, we don't have to do this is $sid == 0.
         $this->store->changeSMWPageID($sid, $new_tid, $subject_ns, $curtarget_ns, false, true);
     } elseif ($old_tid != 0) {
         // existing redirect is changed or deleted
         $db->delete('smw_fpt_redi', array('s_title' => $subject_t, 's_namespace' => $subject_ns), __METHOD__);
         $count--;
         if ($smwgEnableUpdateJobs && $smwgQEqualitySupport != SMW_EQ_NONE) {
             // entries that refer to old target may in fact refer to subject,
             // but we don't know which: schedule affected pages for update
             $jobs = array();
             foreach (SMWSQLStore3::getPropertyTables() as $proptable) {
                 if ($proptable->getName() == 'smw_fpt_redi') {
                     continue;
                     // can safely be skipped
                 }
                 if ($proptable->usesIdSubject()) {
                     $from = $db->tableName($proptable->getName()) . ' INNER JOIN ' . $db->tableName(SMWSql3SmwIds::tableName) . ' ON s_id=smw_id';
                     $select = 'DISTINCT smw_title AS t,smw_namespace AS ns';
                 } else {
                     $from = $db->tableName($proptable->getName());
                     $select = 'DISTINCT s_title AS t,s_namespace AS ns';
                 }
                 if ($subject_ns == SMW_NS_PROPERTY && !$proptable->isFixedPropertyTable()) {
                     $res = $db->select($from, $select, array('p_id' => $old_tid), __METHOD__);
                     foreach ($res as $row) {
                         $title = Title::makeTitleSafe($row->ns, $row->t);
                         if (!is_null($title)) {
                             $jobs[] = new SMWUpdateJob($title);
                         }
                     }
                     $db->freeResult($res);
                 }
                 foreach ($proptable->getFields($this->store) as $fieldname => $type) {
                     if ($type == 'p') {
                         $res = $db->select($from, $select, array($fieldname => $old_tid), __METHOD__);
                         foreach ($res as $row) {
                             $title = Title::makeTitleSafe($row->ns, $row->t);
                             if (!is_null($title)) {
                                 $jobs[] = new SMWUpdateJob($title);
                             }
                         }
                         $db->freeResult($res);
                     }
                 }
             }
             /// NOTE: we do not update the concept cache here; this remains an offline task
             /// NOTE: this only happens if $smwgEnableUpdateJobs was true above:
             Job::batchInsert($jobs);
         }
     }
     // *** Finally, write the new redirect data ***//
     if ($new_tid != 0) {
         // record a new redirect
         // Redirecting done right:
         // (1) make a new ID with iw SMW_SQL3_SMWREDIIW or
         //     change iw field of current ID in this way,
         // (2) write smw_fpt_redi table,
         // (3) update canonical cache.
         // This order must be obeyed unless you really understand what you are doing!
         if ($old_tid == 0 && $smwgQEqualitySupport != SMW_EQ_NONE) {
             // mark subject as redirect (if it was no redirect before)
             if ($sid == 0) {
                 // every redirect page must have an ID
                 $sid = $this->store->smwIds->makeSMWPageID($subject_t, $subject_ns, SMW_SQL3_SMWREDIIW, '', false);
             } else {
                 $db->update(SMWSql3SmwIds::tableName, array('smw_iw' => SMW_SQL3_SMWREDIIW), array('smw_id' => $sid), __METHOD__);
                 $this->store->smwIds->setCache($subject_t, $subject_ns, '', '', 0, '');
                 $this->store->smwIds->setCache($subject_t, $subject_ns, SMW_SQL3_SMWREDIIW, '', $sid, $sid_sort);
             }
         }
         $db->insert('smw_fpt_redi', array('s_title' => $subject_t, 's_namespace' => $subject_ns, 'o_id' => $new_tid), __METHOD__);
         $count++;
     } else {
         // delete old redirect
         // This case implies $old_tid != 0 (or we would have new_tid == old_tid above).
         // Therefore $subject had a redirect, and it must also have an ID.
         // This shows that $sid != 0 here.
         if ($smwgQEqualitySupport != SMW_EQ_NONE) {
             // mark subject as non-redirect
             $db->update(SMWSql3SmwIds::tableName, array('smw_iw' => ''), array('smw_id' => $sid), __METHOD__);
             $this->store->smwIds->setCache($subject_t, $subject_ns, SMW_SQL3_SMWREDIIW, '', 0, '');
             $this->store->smwIds->setCache($subject_t, $subject_ns, '', '', $sid, $sid_sort);
         }
     }
     // *** Flush some caches to be safe, though they are not essential in runs with redirect updates ***//
     unset($this->store->m_semdata[$sid]);
     unset($this->store->m_semdata[$new_tid]);
     unset($this->store->m_semdata[$old_tid]);
     unset($this->store->m_sdstate[$sid]);
     unset($this->store->m_sdstate[$new_tid]);
     unset($this->store->m_sdstate[$old_tid]);
     // *** Update reference count for _REDI property ***//
     $this->addToPropertyUsageCount($this->store->smwIds->getSMWPropertyID(new SMWDIProperty('_REDI')), $count, $db);
     return $new_tid == 0 ? $sid : $new_tid;
 }
Beispiel #12
0
 /**
  * Resets internal objects
  *
  * @since 1.9.1.1
  */
 public function clear()
 {
     parent::clear();
     $this->m_semdata = array();
     $this->m_sdstate = array();
     self::$prop_tables = null;
     $this->getObjectIds()->clearCaches();
 }
 public function getStatistics()
 {
     wfProfileIn('SMWSQLStore3::getStatistics (SMW)');
     $dbr = wfGetDB(DB_SLAVE);
     $result = array();
     $proptables = SMWSQLStore3::getPropertyTables();
     // count number of declared properties by counting "has type" annotations
     $typeprop = new SMWDIProperty('_TYPE');
     $typetable = $proptables[SMWSQLStore3::findPropertyTableID($typeprop)];
     $res = $dbr->select($typetable->name, 'COUNT(s_id) AS count', array(), 'SMW::getStatistics');
     $row = $dbr->fetchObject($res);
     $result['DECLPROPS'] = $row->count;
     $dbr->freeResult($res);
     // count property uses by counting rows in property tables,
     // count used properties by counting distinct properties in each table
     $result['PROPUSES'] = 0;
     $result['USEDPROPS'] = 0;
     foreach (SMWSQLStore3::getPropertyTables() as $proptable) {
         /// Note: subproperties that are part of container values are counted individually;
         /// It does not seem to be important to filter them by adding more conditions.
         $res = $dbr->select($proptable->name, 'COUNT(*) AS count', '', 'SMW::getStatistics');
         $row = $dbr->fetchObject($res);
         $result['PROPUSES'] += $row->count;
         $dbr->freeResult($res);
         if ($proptable->fixedproperty == false) {
             $res = $dbr->select($proptable->name, 'COUNT(DISTINCT(p_id)) AS count', '', 'SMW::getStatistics');
             $row = $dbr->fetchObject($res);
             $result['USEDPROPS'] += $row->count;
         } else {
             $res = $dbr->select($proptable->name, '*', '', 'SMW::getStatistics', array('LIMIT' => 1));
             if ($dbr->numRows($res) > 0) {
                 $result['USEDPROPS']++;
             }
         }
         $dbr->freeResult($res);
     }
     wfProfileOut('SMWSQLStore3::getStatistics (SMW)');
     return $result;
 }
Beispiel #14
0
 /**
  * Change an internal id to another value. If no target value is given, the
  * value is changed to become the last id entry (based on the automatic id
  * increment of the database). Whatever currently occupies this id will be
  * moved consistently in all relevant tables. Whatever currently occupies
  * the target id will be ignored (it should be ensured that nothing is
  * moved to an id that is still in use somewhere).
  *
  * @since 1.8
  * @param integer $curid
  * @param integer $targetid
  */
 public function moveSMWPageID($curid, $targetid = 0)
 {
     $db = wfGetDB(DB_MASTER, 'smw');
     $row = $db->selectRow(SMWSql3SmwIds::tableName, '*', array('smw_id' => $curid), __METHOD__);
     if ($row === false) {
         return;
     }
     // no id at current position, ignore
     if ($targetid == 0) {
         // append new id
         $db->insert(SMWSql3SmwIds::tableName, array('smw_id' => $db->nextSequenceValue('smw_ids_smw_id_seq'), 'smw_title' => $row->smw_title, 'smw_namespace' => $row->smw_namespace, 'smw_iw' => $row->smw_iw, 'smw_subobject' => $row->smw_subobject, 'smw_sortkey' => $row->smw_sortkey), __METHOD__);
         $targetid = $db->insertId();
     } else {
         // change to given id
         $db->insert(SMWSql3SmwIds::tableName, array('smw_id' => $targetid, 'smw_title' => $row->smw_title, 'smw_namespace' => $row->smw_namespace, 'smw_iw' => $row->smw_iw, 'smw_subobject' => $row->smw_subobject, 'smw_sortkey' => $row->smw_sortkey), __METHOD__);
     }
     $db->delete(SMWSql3SmwIds::tableName, array('smw_id' => $curid), 'SMWSQLStore3::moveSMWPageID');
     $this->setCache($row->smw_title, $row->smw_namespace, $row->smw_iw, $row->smw_subobject, $targetid, $row->smw_sortkey);
     $this->store->changeSMWPageID($curid, $targetid, $row->smw_namespace, $row->smw_namespace);
 }
Beispiel #15
0
 /**
  * Move/rename page
  * @param $oldtitle
  * @param $newtitle
  * @param $pageid
  * @param $redirid
  */
 public function changeTitle(Title $oldTitle, Title $newTitle, $pageId, $redirectId = 0)
 {
     // Save it in parent store now!
     // We need that so we get all information correctly!
     $result = parent::changeTitle($oldTitle, $newTitle, $pageId, $redirectId);
     // Delete old stuff
     $oldUri = SMWExporter::getInstance()->expandURI($this->getURI($oldTitle));
     $this->removeDataForURI($oldUri);
     $newpage = SMWDataValueFactory::newTypeIDValue('_wpg');
     $newpage->setValues($newTitle->getDBkey(), $newTitle->getNamespace(), $pageId);
     $semdata = $this->getSemanticData($newpage);
     $this->updateData($semdata);
     $oldpage = SMWDataValueFactory::newTypeIDValue('_wpg');
     $oldpage->setValues($oldTitle->getDBkey(), $oldTitle->getNamespace(), $redirectId);
     $semdata = $this->getSemanticData($oldpage);
     $this->updateData($semdata, false);
     return $result;
 }
Beispiel #16
0
 /**
  * Return the array of predefined property table declarations, initialising
  * it if necessary. The result is an array of SMWSQLStore3Table objects
  * indexed by table ids.
  *
  * It is ensured that the keys of the returned array agree with the name of
  * the table that they refer to.
  *
  * @since 1.8
  * @return SMWSQLStore3Table[]
  */
 public static function getPropertyTables()
 {
     if (isset(self::$prop_tables)) {
         return self::$prop_tables;
         // Don't initialise twice.
     }
     /**
      * @var SMWSQLStore3Table[] $propertyTables
      */
     $propertyTables = array();
     //tables for each DI type
     foreach (self::$di_type_tables as $tableDIType => $tableName) {
         $propertyTables[$tableName] = new SMWSQLStore3Table($tableDIType, $tableName);
     }
     //tables for special properties
     foreach (self::$special_tables as $propertyKey) {
         $typeId = SMWDIProperty::getPredefinedPropertyTypeId($propertyKey);
         $diType = SMWDataValueFactory::getDataItemId($typeId);
         $tableName = 'smw_fpt' . strtolower($propertyKey);
         $propertyTables[$tableName] = new SMWSQLStore3Table($diType, $tableName, $propertyKey);
     }
     // Redirect table uses another subject scheme for historic reasons
     // TODO This should be changed if possible
     $propertyTables['smw_fpt_redi']->setUsesIdSubject(false);
     // Get all the tables for the properties that are declared as fixed
     // (overly used and thus having separate tables)
     foreach (self::$fixedProperties as $propertyKey => $tableDIType) {
         $tableName = 'smw_fpt_' . md5($propertyKey);
         $propertyTables[$tableName] = new SMWSQLStore3Table($tableDIType, $tableName, $propertyKey);
     }
     wfRunHooks('SMWPropertyTables', array(&$propertyTables));
     self::$prop_tables = $propertyTables;
     // Build index for finding property tables
     self::$fixedPropertyTableIds = array();
     foreach (self::$prop_tables as $tid => $propTable) {
         if ($propTable->isFixedPropertyTable()) {
             self::$fixedPropertyTableIds[$propTable->getFixedProperty()] = $tid;
         }
     }
     // Specifically set properties that must not be stored in any
     // property table to null here. Any function that hits this
     // null unprepared is doing something wrong anyway.
     self::$fixedPropertyTableIds['_SKEY'] = null;
     return self::$prop_tables;
 }
 /**
  * @see SMWStore::refreshData
  *
  * @todo This method will be overhauled in SMW 1.9 to become cleaner
  * and more robust.
  *
  * @param integer $index
  * @param integer $count
  * @param mixed $namespaces Array or false
  * @param boolean $usejobs
  *
  * @return decimal between 0 and 1 to indicate the overall progress of the refreshing
  */
 public function refreshData(&$index, $count, $namespaces = false, $usejobs = true)
 {
     $updatejobs = array();
     $emptyrange = true;
     // was nothing done in this run?
     // Update by MediaWiki page id --> make sure we get all pages.
     $tids = array();
     // Array of ids
     for ($i = $index; $i < $index + $count; $i++) {
         $tids[] = $i;
     }
     $titles = Title::newFromIDs($tids);
     foreach ($titles as $title) {
         if ($namespaces == false || in_array($title->getNamespace(), $namespaces)) {
             // wikia change start - jobqueue migration
             $task = new \Wikia\Tasks\Tasks\JobWrapperTask();
             $task->call('SMWUpdateJob', $title);
             $updatejobs[] = $task;
             // wikia change end
             $emptyrange = false;
         }
     }
     // update by internal SMW id --> make sure we get all objects in SMW
     $dbr = wfGetDB(DB_SLAVE, 'smw');
     $res = $dbr->select(SMWSql3SmwIds::tableName, array('smw_id', 'smw_title', 'smw_namespace', 'smw_iw', 'smw_subobject'), array("smw_id >= {$index} ", " smw_id < " . $dbr->addQuotes($index + $count)), __METHOD__);
     foreach ($res as $row) {
         $emptyrange = false;
         // note this even if no jobs were created
         if ($namespaces && !in_array($row->smw_namespace, $namespaces)) {
             continue;
         }
         // Find page to refresh, even for special properties:
         if ($row->smw_title != '' && $row->smw_title[0] != '_') {
             $titleKey = $row->smw_title;
         } elseif ($row->smw_namespace == SMW_NS_PROPERTY && $row->smw_iw == '' && $row->smw_subobject == '') {
             $titleKey = str_replace(' ', '_', SMWDIProperty::findPropertyLabel($row->smw_title));
         } else {
             $titleKey = '';
         }
         if ($row->smw_subobject !== '') {
             // leave subobjects alone; they ought to be changed with their pages
         } elseif (($row->smw_iw === '' || $row->smw_iw == SMW_SQL3_SMWREDIIW) && $titleKey != '') {
             // objects representing pages
             // TODO: special treament of redirects needed, since the store will
             // not act on redirects that did not change according to its records
             $title = Title::makeTitleSafe($row->smw_namespace, $titleKey);
             if ($title !== null && !$title->exists()) {
                 // wikia change start - jobqueue migration
                 $task = new \Wikia\Tasks\Tasks\JobWrapperTask();
                 $task->call('SMWUpdateJob', $title);
                 $updatejobs[] = $task;
                 // wikia change end
             }
         } elseif ($row->smw_iw == SMW_SQL3_SMWIW_OUTDATED) {
             // remove outdated internal object references
             $dbw = wfGetDB(DB_MASTER, 'smw');
             foreach (SMWSQLStore3::getPropertyTables() as $proptable) {
                 if ($proptable->usesIdSubject()) {
                     $dbw->delete($proptable->getName(), array('s_id' => $row->smw_id), __METHOD__);
                 }
             }
             $dbw->delete(SMWSql3SmwIds::tableName, array('smw_id' => $row->smw_id), __METHOD__);
         } elseif ($titleKey != '') {
             // "normal" interwiki pages or outdated internal objects -- delete
             $diWikiPage = new SMWDIWikiPage($titleKey, $row->smw_namespace, $row->smw_iw);
             $emptySemanticData = new SMWSemanticData($diWikiPage);
             $this->store->doDataUpdate($emptySemanticData);
         }
     }
     $dbr->freeResult($res);
     wfRunHooks('smwRefreshDataJobs', array(&$updatejobs));
     if ($usejobs) {
         // wikia change start - jobqueue migration
         \Wikia\Tasks\Tasks\BaseTask::batch($updatejobs);
         // wikia change end
     } else {
         foreach ($updatejobs as $job) {
             // wikia change start - jobqueue migration
             /** @var \Wikia\Tasks\Tasks\JobWrapperTask $job */
             try {
                 $job->init();
             } catch (Exception $e) {
                 continue;
             }
             $job->wrap('SMWUpdateJob');
             // wikia change end
         }
     }
     $nextpos = $index + $count;
     // smw+ wikia change, handler to local database
     $dbl = wfGetDB(DB_SLAVE);
     if ($emptyrange) {
         // nothing found, check if there will be more pages later on
         $next1 = $dbl->selectField('page', 'page_id', "page_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "page_id ASC"));
         $next2 = $dbr->selectField(SMWSql3SmwIds::tableName, 'smw_id', "smw_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "smw_id ASC"));
         $nextpos = $next2 != 0 && $next2 < $next1 ? $next2 : $next1;
     }
     $max1 = $dbl->selectField('page', 'MAX(page_id)', '', __METHOD__);
     $max2 = $dbr->selectField(SMWSql3SmwIds::tableName, 'MAX(smw_id)', '', __METHOD__);
     $index = $nextpos ? $nextpos : -1;
     return $index > 0 ? $index / max($max1, $max2) : 1;
 }
Beispiel #18
0
 /**
  * Method to return the fields for this table
  *
  * @since 1.8
  *
  * @param SMWSQLStore3 $store
  *
  * @return array
  */
 public function getFields(\SMWSQLStore3 $store)
 {
     $diHandler = $store->getDataItemHandlerForDIType($this->diType);
     return $diHandler->getTableFields();
 }
 /**
  * @see SMWStore::refreshData
  *
  * @param integer $index
  * @param integer $count
  * @param mixed $namespaces Array or false
  * @param boolean $usejobs
  *
  * @return decimal between 0 and 1 to indicate the overall progress of the refreshing
  */
 public function refreshData(&$index, $count, $namespaces = false, $usejobs = true)
 {
     $updatejobs = array();
     $emptyrange = true;
     // was nothing done in this run?
     // Update by MediaWiki page id --> make sure we get all pages.
     $tids = array();
     // Array of ids
     for ($i = $index; $i < $index + $count; $i++) {
         $tids[] = $i;
     }
     $titles = Title::newFromIDs($tids);
     foreach ($titles as $title) {
         if ($namespaces == false || in_array($title->getNamespace(), $namespaces)) {
             $updatejobs[] = new SMWUpdateJob($title);
             $emptyrange = false;
         }
     }
     // update by internal SMW id --> make sure we get all objects in SMW
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('smw_ids', array('smw_id', 'smw_title', 'smw_namespace', 'smw_iw', 'smw_subobject'), array("smw_id >= {$index} ", " smw_id < " . $dbr->addQuotes($index + $count)), __METHOD__);
     foreach ($res as $row) {
         $emptyrange = false;
         // note this even if no jobs were created
         if ($namespaces && !in_array($row->smw_namespace, $namespaces)) {
             continue;
         }
         if ($row->smw_subobject !== '') {
             // leave subobjects alone; they ought to be changed with their pages
         } elseif ($row->smw_iw === '' || $row->smw_iw == SMW_SQL3_SMWREDIIW) {
             // objects representing pages
             // TODO: special treament of redirects needed, since the store will
             // not act on redirects that did not change according to its records
             $title = Title::makeTitleSafe($row->smw_namespace, $row->smw_title);
             if ($title !== null && !$title->exists()) {
                 $updatejobs[] = new SMWUpdateJob($title);
             }
         } elseif ($row->smw_iw == SMW_SQL3_SMWIW_OUTDATED) {
             // remove outdated internal object references
             foreach (SMWSQLStore3::getPropertyTables() as $proptable) {
                 if ($proptable->idsubject) {
                     $dbr->delete($proptable->name, array('s_id' => $row->smw_id), __METHOD__);
                 }
             }
             $dbr->delete('smw_ids', array('smw_id' => $row->smw_id), __METHOD__);
         } else {
             // "normal" interwiki pages or outdated internal objects
             $diWikiPage = new SMWDIWikiPage($row->smw_title, $row->smw_namespace, $row->smw_iw);
             $this->store->getWriter()->deleteSemanticData($diWikiPage);
         }
     }
     $dbr->freeResult($res);
     wfRunHooks('smwRefreshDataJobs', array(&$updatejobs));
     if ($usejobs) {
         Job::batchInsert($updatejobs);
     } else {
         foreach ($updatejobs as $job) {
             $job->run();
         }
     }
     $nextpos = $index + $count;
     if ($emptyrange) {
         // nothing found, check if there will be more pages later on
         $next1 = $dbr->selectField('page', 'page_id', "page_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "page_id ASC"));
         $next2 = $dbr->selectField('smw_ids', 'smw_id', "smw_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "smw_id ASC"));
         $nextpos = $next2 != 0 && $next2 < $next1 ? $next2 : $next1;
     }
     $max1 = $dbr->selectField('page', 'MAX(page_id)', '', __METHOD__);
     $max2 = $dbr->selectField('smw_ids', 'MAX(smw_id)', '', __METHOD__);
     $index = $nextpos ? $nextpos : -1;
     return $index > 0 ? $index / max($max1, $max2) : 1;
 }
 /**
  * Return the array of predefined property table declarations, initialising
  * it if necessary. The result is an array of SMWSQLStore3Table objects
  * indexed by table ids. Note that the ids are only for accessing the data
  * and should not be assumed to agree with the table name.
  *
  * @return array of SMWSQLStore3Table
  */
 public static function getPropertyTables()
 {
     if (isset(self::$prop_tables)) {
         return self::$prop_tables;
         // Don't initialise twice.
     }
     self::$prop_tables = array();
     //tables for each DI type
     foreach (self::$di_type_tables as $tableDIType => $tableName) {
         self::$prop_tables[$tableName] = new SMWSQLStore3Table($tableDIType, $tableName);
     }
     //tables for special properties
     foreach (self::$special_tables as $propertyKey) {
         $typeId = SMWDIProperty::getPredefinedPropertyTypeId($propertyKey);
         $diType = SMWDataValueFactory::getDataItemId($typeId);
         $tableName = 'smw_fpt' . strtolower($propertyKey);
         self::$prop_tables[$tableName] = new SMWSQLStore3Table($diType, $tableName, $propertyKey);
     }
     // Redirect table uses another subject scheme for historic reasons
     // TODO This should be changed if possible
     self::$prop_tables['smw_fpt_redi']->idsubject = false;
     // Get all the tables for the properties that are declared as fixed
     // (overly used and thus having separate tables)
     foreach (self::$fixedProperties as $propertyKey => $tableDIType) {
         $tableName = 'smw_fpt_' . md5($propertyKey);
         self::$prop_tables[$tableName] = new SMWSQLStore3Table($tableDIType, $tableName, $propertyKey);
     }
     wfRunHooks('SMWPropertyTables', array(&self::$prop_tables));
     // Build index for finding property tables
     self::$fixedPropertyTableIds = array();
     foreach (self::$prop_tables as $tid => $proptable) {
         if ($proptable->fixedproperty) {
             self::$fixedPropertyTableIds[$proptable->fixedproperty] = $tid;
         }
     }
     return self::$prop_tables;
 }
Beispiel #21
0
 public function execute()
 {
     global $wgDBtype;
     if ($this->hasOption('setup')) {
         $store = new SMWSQLStore3();
         // Lets do a drop to ensure the user doesn't has any Store3 tables already (happens when running this script twice)
         $tables = array('smw_stats');
         foreach (SMWSQLStore3::getPropertyTables() as $proptable) {
             $tables[] = $proptable->name;
         }
         $dbw = wfGetDB(DB_MASTER);
         foreach ($tables as $table) {
             $name = $dbw->tableName($table);
             $dbw->query('DROP TABLE ' . ($wgDBtype == 'postgres' ? '' : 'IF EXISTS ') . $name, 'SMWMigrate::drop');
         }
         $store->setup();
         //enter user defined properties into smw_stats (internal ones are handled by setup already )
         $query = 'Replace into ' . $dbw->tableName('smw_stats') . ' (pid,usage_count) Select smw_id,0 from ' . $dbw->tableName('smw_ids') . ' where smw_namespace = ' . SMW_NS_PROPERTY . ' and smw_iw = "" ';
         $dbw->query($query, 'SMWMigrate:commandLine');
     } elseif ($this->hasOption('migrate')) {
         $options = array();
         if ($this->hasArg(0)) {
             if ($this->hasArg(1)) {
                 $options['LIMIT'] = $this->getArg(0);
                 $options['OFFSET'] = $this->getArg(1);
             }
         }
         $dbw = wfGetDB(DB_MASTER);
         $oldStore = new SMWSQLStore2();
         $newStore = new SMWSQLStore3();
         $proptables = SMWSQLStore3::getPropertyTables();
         //get properties
         $res = $dbw->select('smw_ids', array('smw_id', 'smw_title', 'smw_namespace'), array('smw_namespace' => SMW_NS_PROPERTY), __METHOD__, $options);
         foreach ($res as $row) {
             $property = new SMWDIProperty($row->smw_title);
             echo 'Now migrating data for Property ' . $property->getLabel() . " into Store3 \n";
             //get the table
             $tableId = SMWSQLStore3::findPropertyTableID($property);
             $proptable = $proptables[$tableId];
             //get the DIHandler
             $dataItemId = SMWDataValueFactory::getDataItemId($property->findPropertyTypeId());
             $diHandler = $newStore->getDataItemHandlerForDIType($dataItemId);
             $subjects = $oldStore->getPropertySubjects($property, null);
             $insertions = array();
             foreach ($subjects as $subject) {
                 $sid = $newStore->makeSMWPageID($subject->getDBkey(), $subject->getNamespace(), $subject->getInterwiki(), $subject->getSubobjectName(), true, str_replace('_', ' ', $subject->getDBkey()) . $subject->getSubobjectName());
                 //now prepare udpates
                 $propvals = $oldStore->getPropertyValues($subject, $property);
                 $uvals = $proptable->idsubject ? array('s_id' => $sid) : array('s_title' => $subject->getDBkey(), 's_namespace' => $subject->getNamespace());
                 if ($proptable->fixedproperty == false) {
                     $uvals['p_id'] = $newStore->makeSMWPropertyID($property);
                 }
                 foreach ($propvals as $propval) {
                     $uvals = array_merge($uvals, $diHandler->getInsertValues($propval));
                     $insertions[] = $uvals;
                 }
             }
             // now write to the DB for all subjects (is this too much?)
             $dbw->insert($proptable->name, $insertions, "SMW::migrate{$proptable->name}");
         }
         $dbw->freeResult($res);
     } else {
         echo "Sorry I refuse to work without any options currently";
     }
 }
 private function newTemporaryTableBuilder()
 {
     $temporaryTableBuilder = new TemporaryTableBuilder($this->store->getConnection('mw.db.queryengine'));
     $temporaryTableBuilder->withAutoCommit($this->applicationFactory->getSettings()->get('smwgQTemporaryTablesAutoCommitMode'));
     return $temporaryTableBuilder;
 }