public function testAddStringCondition() { $instance = new RequestOptions(); $instance->addStringCondition('Foo', StringCondition::STRCOND_PRE); foreach ($instance->getStringConditions() as $stringCondition) { $this->assertInstanceOf('\\SMW\\StringCondition', $stringCondition); $this->assertFalse($stringCondition->asDisjunctiveCondition); } }
/** * @since 2.4 * * @param DIWikiPage $subject * @param DIProperty $property * @param RequestOptions|null $requestOptions * * @return array */ public function getPropertyValues(DIWikiPage $subject, DIProperty $property, RequestOptions $requestOptions = null) { $key = $property->getKey() . ':' . $subject->getSubobjectName() . ':' . ($requestOptions !== null ? $requestOptions->getHash() : null); $container = $this->blobStore->read($this->getRootHashFrom($subject)); if ($container->has($key)) { return $container->get($key); } $dataItems = $this->store->getPropertyValues($subject, $property, $requestOptions); $container->set($key, $dataItems); $this->blobStore->save($container); return $dataItems; }
/** * @since 2.4 * * @param string $property * * @return boolean */ public function findPropertyListFor($property = '') { $this->meta = array(); $this->propertyList = array(); $this->namespaces = array(); $this->requestOptions->limit++; // increase by one to look ahead $this->continueOffset = 1; if ($property !== '') { $property = str_replace("_", " ", $property); $this->requestOptions->addStringCondition($property, StringCondition::STRCOND_MID); // Disjunctive condition to allow for auto searches of foaf OR Foaf $this->requestOptions->addStringCondition(ucfirst($property), StringCondition::STRCOND_MID, true); } $propertyListLookup = $this->store->getPropertiesSpecial($this->requestOptions); $this->requestOptions->limit--; foreach ($propertyListLookup->fetchList() as $value) { if ($this->continueOffset > $this->requestOptions->limit) { break; } $this->addPropertyToList($value); $this->continueOffset++; } $this->continueOffset = $this->continueOffset > $this->requestOptions->limit ? $this->requestOptions->limit : 0; $this->namespaces = array_keys($this->namespaces); $this->meta = array('limit' => $this->requestOptions->limit, 'count' => count($this->propertyList), 'isCached' => $propertyListLookup->isCached()); return true; }
/** * Returns an introductory text for a predefined property * * @note In order to enable a more detailed description for a specific * predefined property a concatenated message key can be used (e.g * 'smw-pa-property-predefined' + <internal property key> => '_asksi' ) * * @since 1.9 * * @return string */ protected function getTopText() { $propertyName = htmlspecialchars($this->mTitle->getText()); $usageCount = ''; $requestOptions = new RequestOptions(); $requestOptions->limit = 1; $requestOptions->addStringCondition($propertyName, StringCondition::STRCOND_PRE); $cachedLookupList = $this->store->getPropertiesSpecial($requestOptions); $usageList = $cachedLookupList->fetchList(); if ($usageList && $usageList !== array()) { $usage = end($usageList); $usageCount = wfMessage('smw-pa-property-usage', $propertyName, $usage[1], $this->getContext()->getLanguage()->timeanddate($cachedLookupList->getTimestamp()))->parse(); } if (!$this->mProperty->isUserDefined()) { $propertyKey = 'smw-pa-property-predefined' . strtolower($this->mProperty->getKey()); $messageKey = wfMessage($propertyKey)->exists() ? $propertyKey : 'smw-pa-property-predefined-default'; return Html::rawElement('div', array('class' => 'smw-pa-property-predefined-intro'), wfMessage($messageKey, $propertyName)->parse() . ' ' . wfMessage('smw-pa-property-predefined-common')->parse() . ' ' . $usageCount); } return $usageCount; }
/** * Finds a partial list (given limit and offset) of registered subjects that * that represent a dependency on something like a subject in a query list, * a property, or a printrequest. * * `s_id` contains the subject id that links to the query that fulfills one * of the conditions cited above. * * Prefetched Ids are turned into a hash list that can later be split into * chunks to work either in online or batch mode without creating a huge memory * foothold. * * @note Select a list is crucial for performance as any selectRow would / * single Id select would strain the system on large list connected to a * query * * @since 2.3 * * @param array $idlist * @param RequestOptions $requestOptions * * @return array */ public function findEmbeddedQueryTargetLinksHashListFor(array $idlist, RequestOptions $requestOptions) { if ($idlist === array() || !$this->isEnabled()) { return array(); } $options = array('LIMIT' => $requestOptions->getLimit(), 'OFFSET' => $requestOptions->getOffset(), 'GROUP BY' => 's_id', 'ORDER BY' => 's_id', 'DISTINCT' => true); $conditions = array('o_id' => $idlist); foreach ($requestOptions->getExtraConditions() as $extraCondition) { $conditions += $extraCondition; } $rows = $this->connection->select(SQLStore::QUERY_LINKS_TABLE, array('s_id'), $conditions, __METHOD__, $options); $targetLinksIdList = array(); foreach ($rows as $row) { $targetLinksIdList[] = $row->s_id; } if ($targetLinksIdList === array()) { return array(); } return $this->store->getObjectIds()->getDataItemPoolHashListFor($targetLinksIdList); }
public function testOffset() { $instance = new RequestOptions(); $instance->setOffset(42); $this->assertEquals(42, $instance->getOffset()); }
/** * Get the HTML for displaying subproperties of this property. This list * is usually short and we implement no additional navigation. * * @return string */ protected function getSubpropertyList() { $more = false; $requestOptions = new RequestOptions(); $requestOptions->sort = true; $requestOptions->ascending = true; // +1 look-ahead $requestOptions->setLimit($GLOBALS['smwgSubPropertyListLimit'] + 1); $subproperties = $this->store->getPropertySubjects(new DIProperty('_SUBP'), $this->getDataItem(), $requestOptions); // Pop the +1 look-ahead from the list if (count($subproperties) > $GLOBALS['smwgSubPropertyListLimit']) { array_pop($subproperties); $more = true; } $result = ''; $resultCount = count($subproperties); if ($more) { $message = Html::rawElement('span', array('class' => 'plainlinks'), wfMessage('smw-subpropertylist-count-with-restricted-note', $resultCount, $GLOBALS['smwgSubPropertyListLimit'])->parse()); } else { $message = wfMessage('smw-subpropertylist-count', $resultCount)->text(); } if ($resultCount > 0) { $titleText = htmlspecialchars($this->mTitle->getText()); $result .= "<div id=\"mw-subcategories\">\n<h2>" . wfMessage('smw_subproperty_header', $titleText)->text() . "</h2>\n<p>"; if (!$this->mProperty->isUserDefined()) { $result .= wfMessage('smw_isspecprop')->text() . ' '; } $result .= $message . "</p>" . "\n"; if ($resultCount < 6) { $result .= SMWPageLister::getShortList(0, $resultCount, $subproperties, null); } else { $result .= SMWPageLister::getColumnList(0, $resultCount, $subproperties, null); } $result .= "\n</div>"; } return $result; }
public function testFindPartialEmbeddedQueryTargetLinksHashListFor() { $row = new \stdClass(); $row->s_id = 1001; $idTable = $this->getMockBuilder('\\stdClass')->setMethods(array('getDataItemPoolHashListFor'))->getMock(); $idTable->expects($this->once())->method('getDataItemPoolHashListFor'); $connection = $this->getMockBuilder('\\SMW\\MediaWiki\\Database')->disableOriginalConstructor()->getMock(); $connection->expects($this->once())->method('select')->with($this->equalTo(\SMWSQLStore3::QUERY_LINKS_TABLE), $this->anything(), $this->equalTo(array('o_id' => array(42))))->will($this->returnValue(array($row))); $connectionManager = $this->getMockBuilder('\\SMW\\ConnectionManager')->disableOriginalConstructor()->getMock(); $connectionManager->expects($this->any())->method('getConnection')->will($this->returnValue($connection)); $store = $this->getMockBuilder('\\SMW\\SQLStore\\SQLStore')->disableOriginalConstructor()->setMethods(array('getObjectIds'))->getMockForAbstractClass(); $store->setConnectionManager($connectionManager); $store->expects($this->any())->method('getObjectIds')->will($this->returnValue($idTable)); $dependencyLinksTableUpdater = $this->getMockBuilder('\\SMW\\SQLStore\\QueryDependency\\DependencyLinksTableUpdater')->disableOriginalConstructor()->getMock(); $dependencyLinksTableUpdater->expects($this->any())->method('getStore')->will($this->returnValue($store)); $queryResultDependencyListResolver = $this->getMockBuilder('\\SMW\\SQLStore\\QueryDependency\\QueryResultDependencyListResolver')->disableOriginalConstructor()->getMock(); $instance = new QueryDependencyLinksStore($queryResultDependencyListResolver, $dependencyLinksTableUpdater); $requestOptions = new RequestOptions(); $requestOptions->setLimit(1); $requestOptions->setOffset(200); $instance->findEmbeddedQueryTargetLinksHashListFor(array(42), $requestOptions); }
/** * Based on the CHUNK_SIZE, target links are purged in an instant if those * selected entities are < CHUNK_SIZE which should be enough for most * common queries that only share a limited amount of dependencies, yet for * queries that expect a large subject/dependency pool, doing an online update * for all at once is not feasible hence the iterative process of creating * batches that run through the job scheduler. * * @param array|string $idList */ private function findEmbeddedQueryTargetLinksBatches($idList) { if (is_string($idList) && strpos($idList, '|') !== false) { $idList = explode('|', $idList); } if ($idList === array()) { return true; } $queryDependencyLinksStoreFactory = new QueryDependencyLinksStoreFactory(); $queryDependencyLinksStore = $queryDependencyLinksStoreFactory->newQueryDependencyLinksStore($this->store); $requestOptions = new RequestOptions(); // +1 to look ahead $requestOptions->setLimit($this->limit + 1); $requestOptions->setOffset($this->offset); $hashList = $queryDependencyLinksStore->findEmbeddedQueryTargetLinksHashListFor($idList, $requestOptions); if ($hashList === array()) { return true; } $countedHashListEntries = count($hashList); // If more results are available then use an iterative increase to fetch // the remaining updates by creating successive jobs if ($countedHashListEntries > $this->limit) { $job = new self($this->getTitle(), array('idlist' => $idList, 'limit' => $this->limit, 'offset' => $this->offset + self::CHUNK_SIZE)); $job->run(); } wfDebugLog('smw', __METHOD__ . " counted: {$countedHashListEntries} | offset: {$this->offset} for " . $this->getTitle()->getPrefixedDBKey() . "\n"); list($hashList, $queryList) = $this->doBuildUniqueTargetLinksHashList($hashList); $this->applicationFactory->singleton('CachedQueryResultPrefetcher')->resetCacheBy($queryList); $this->addPagesToUpdater($hashList); }