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);
 }