/** * @since 2.2 * * @param Description $description * * @return QuerySegment */ public function interpretDescription(Description $description) { $query = new QuerySegment(); $cqid = QuerySegment::$qnum; $cquery = new QuerySegment(); $cquery->type = QuerySegment::Q_CLASS_HIERARCHY; $cquery->joinfield = array(); foreach ($description->getCategories() as $category) { $categoryId = $this->queryBuilder->getStore()->getObjectIds()->getSMWPageID($category->getDBkey(), NS_CATEGORY, $category->getInterwiki(), ''); if ($categoryId != 0) { $cquery->joinfield[] = $categoryId; } } if (count($cquery->joinfield) == 0) { // Empty result. $query->type = QuerySegment::Q_VALUE; $query->joinTable = ''; $query->joinfield = ''; } else { // Instance query with disjunction of classes (categories) $query->joinTable = $this->queryBuilder->getStore()->findPropertyTableID(new DIProperty('_INST')); $query->joinfield = "{$query->alias}.s_id"; $query->components[$cqid] = "{$query->alias}.o_id"; $this->queryBuilder->addQuerySegmentForId($cqid, $cquery); } return $query; }
/** * Create a Condition from a ConceptDescription * * @param ConceptDescription $description * @param string $joinVariable * @param DIProperty|null $orderByProperty * * @return Condition */ public function buildCondition(Description $description, $joinVariable, $orderByProperty = null) { $conceptDescription = $this->getConceptDescription($description->getConcept()); if ($conceptDescription === '') { return new FalseCondition(); } return $this->compoundConditionBuilder->mapDescriptionToCondition($conceptDescription, $joinVariable, $orderByProperty); }
/** * TODO: One instance of the SMW IDs table on s_id always suffices (swm_id is KEY)! Doable in execution ... (PERFORMANCE) * * @since 2.2 * * @param Description $description * * @return QuerySegment */ public function interpretDescription(Description $description) { $query = new QuerySegment(); $query->joinTable = SMWSql3SmwIds::tableName; $query->joinfield = "{$query->alias}.smw_id"; $query->where = "{$query->alias}.smw_namespace=" . $this->queryBuilder->getStore()->getConnection('mw.db')->addQuotes($description->getNamespace()); return $query; }
/** * TODO: One instance of the SMW IDs table on s_id always suffices (swm_id is KEY)! Doable in execution ... (PERFORMANCE) * * @since 2.2 * * @param Description $description * * @return QuerySegment */ public function interpretDescription(Description $description) { $db = $this->querySegmentListBuilder->getStore()->getConnection('mw.db.queryengine'); $query = new QuerySegment(); $query->joinTable = SMWSql3SmwIds::TABLE_NAME; $query->joinfield = "{$query->alias}.smw_id"; $query->where = "{$query->alias}.smw_namespace=" . $db->addQuotes($description->getNamespace()); return $query; }
/** * Create an Condition from a NamespaceDescription * * @param NamespaceDescription $description * @param string $joinVariable * @param DIProperty|null $orderByProperty * * @return Condition */ public function buildCondition(Description $description, $joinVariable, $orderByProperty = null) { $nspropExpElement = $this->exporter->getSpecialNsResource('swivt', 'wikiNamespace'); $nsExpElement = new ExpLiteral(strval($description->getNamespace()), 'http://www.w3.org/2001/XMLSchema#integer'); $nsName = TurtleSerializer::getTurtleNameForExpElement($nsExpElement); $condition = "{ ?{$joinVariable} " . $nspropExpElement->getQName() . " {$nsName} . }\n"; $result = new WhereCondition($condition, true, array()); $this->compoundConditionBuilder->addOrderByDataForProperty($result, $joinVariable, $orderByProperty, DataItem::TYPE_WIKIPAGE); return $result; }
/** * Create an Condition from an ClassDescription. * * @param ClassDescription $description * @param string $joinVariable * @param DIProperty|null $orderByProperty * * @return Condition */ public function buildCondition(Description $description, $joinVariable, $orderByProperty = null) { list($condition, $namespaces) = $this->mapCategoriesToConditionElements($description->getCategories(), $joinVariable); // empty disjunction: always false, no results to order if ($condition === '') { return new FalseCondition(); } $result = new WhereCondition($condition, true, $namespaces); $this->compoundConditionBuilder->addOrderByDataForProperty($result, $joinVariable, $orderByProperty, DataItem::TYPE_WIKIPAGE); return $result; }
/** * Only type '_wpg' objects can appear on query level (essentially as nominal classes) * * @since 2.2 * * @param Description $description * * @return QuerySegment */ public function interpretDescription(Description $description) { $query = new QuerySegment(); if (!$description->getDataItem() instanceof DIWikiPage) { return $query; } $comparator = $description->getComparator(); $value = $description->getDataItem()->getSortKey(); // A simple value match using the `~~Foo` will initiate a fulltext // search without being bound to a property allowing a broad match // search if (($comparator === SMW_CMP_LIKE || $comparator === SMW_CMP_NLKE) && strpos($value, '~') !== false) { $fulltextSearchSupport = $this->addFulltextSearchCondition($query, $comparator, $value); if ($fulltextSearchSupport) { return $query; } } if ($comparator === SMW_CMP_EQ) { $query->type = QuerySegment::Q_VALUE; $oid = $this->querySegmentListBuilder->getStore()->getObjectIds()->getSMWPageID($description->getDataItem()->getDBkey(), $description->getDataItem()->getNamespace(), $description->getDataItem()->getInterwiki(), $description->getDataItem()->getSubobjectName()); $query->joinfield = array($oid); } else { // Join with SMW IDs table needed for other comparators (apply to title string). $query->joinTable = SMWSql3SmwIds::TABLE_NAME; $query->joinfield = "{$query->alias}.smw_id"; $comparator = $this->comparatorMapper->mapComparator($description, $value); $db = $this->querySegmentListBuilder->getStore()->getConnection('mw.db.queryengine'); $query->where = "{$query->alias}.smw_sortkey{$comparator}" . $db->addQuotes($value); } return $query; }
/** * @since 2.2 * * @param Description $description * * @return QuerySegment */ public function interpretDescription(Description $description) { $query = new QuerySegment(); $query->type = $description instanceof Conjunction ? QuerySegment::Q_CONJUNCTION : QuerySegment::Q_DISJUNCTION; foreach ($description->getDescriptions() as $subDescription) { $subQueryId = $this->querySegmentListBuilder->getQuerySegmentFrom($subDescription); if ($subQueryId >= 0) { $query->components[$subQueryId] = true; } } // All subconditions failed, drop this as well. if (count($query->components) == 0) { $query->type = QuerySegment::Q_NOQUERY; } return $query; }
/** * Recursively create an Condition from an Conjunction * * @param Conjunction $description * @param string $joinVariable * @param DIProperty|null $orderByProperty * * @return Condition */ public function buildCondition(Description $description, $joinVariable, $orderByProperty = null) { $subDescriptions = $description->getDescriptions(); $result = $this->doPreliminarySubDescriptionCheck($subDescriptions, $joinVariable, $orderByProperty); if ($result !== null) { return $result; } $subConditionElements = $this->doResolveSubDescriptionsRecursively($subDescriptions, $joinVariable); if ($subConditionElements instanceof FalseCondition) { return $subConditionElements; } $result = $this->createConditionFromSubConditionElements($subConditionElements); $result->weakConditions = $subConditionElements->weakConditions; $result->orderVariables = $subConditionElements->orderVariables; $this->compoundConditionBuilder->addOrderByDataForProperty($result, $joinVariable, $orderByProperty); return $result; }
/** * @since 2.2 * * @param Description $description * * @return QuerySegment */ public function interpretDescription(Description $description) { $query = new QuerySegment(); $conceptId = $this->querySegmentListBuilder->getStore()->getObjectIds()->getSMWPageID($description->getConcept()->getDBkey(), SMW_NS_CONCEPT, '', ''); $hash = 'concept-' . $conceptId; $this->querySegmentListBuilder->getCircularReferenceGuard()->mark($hash); if ($this->querySegmentListBuilder->getCircularReferenceGuard()->isCircularByRecursionFor($hash)) { $this->querySegmentListBuilder->addError(wfMessage('smw-query-condition-circular', $description->getQueryString())->text()); return $query; } $db = $this->querySegmentListBuilder->getStore()->getConnection('mw.db.queryengine'); $row = $this->getConceptForId($db, $conceptId); // No description found, concept does not exist. if ($row === false) { $this->querySegmentListBuilder->getCircularReferenceGuard()->unmark('concept-' . $conceptId); // keep the above query object, it yields an empty result // TODO: announce an error here? (maybe not, since the query processor can check for // non-existing concept pages which is probably the main reason for finding nothing here) return $query; } global $smwgQConceptCaching, $smwgQMaxSize, $smwgQMaxDepth, $smwgQFeatures, $smwgQConceptCacheLifetime; $may_be_computed = $smwgQConceptCaching == CONCEPT_CACHE_NONE || $smwgQConceptCaching == CONCEPT_CACHE_HARD && ~(~($row->concept_features + 0) | $smwgQFeatures) == 0 && $smwgQMaxSize >= $row->concept_size && $smwgQMaxDepth >= $row->concept_depth; if ($row->cache_date && ($row->cache_date > strtotime("now") - $smwgQConceptCacheLifetime * 60 || !$may_be_computed)) { // Cached concept, use cache unless it is dead and can be revived. $query->joinTable = SMWSQLStore3::CONCEPT_CACHE_TABLE; $query->joinfield = "{$query->alias}.s_id"; $query->where = "{$query->alias}.o_id=" . $db->addQuotes($conceptId); } elseif ($row->concept_txt) { // Parse description and process it recursively. if ($may_be_computed) { $qid = $this->querySegmentListBuilder->getQuerySegmentFrom($this->getConceptQueryDescriptionFrom($row->concept_txt)); if ($qid != -1) { $query = $this->querySegmentListBuilder->findQuerySegment($qid); } else { // somehow the concept query is no longer valid; maybe some syntax changed (upgrade) or global settings were modified since storing it $this->querySegmentListBuilder->addError(wfMessage('smw_emptysubquery')->text()); // not the right message, but this case is very rare; let us not make detailed messages for this } } else { $this->querySegmentListBuilder->addError(wfMessage('smw_concept_cache_miss', $description->getConcept()->getTitle()->getText())->text()); } } // else: no cache, no description (this may happen); treat like empty concept $this->querySegmentListBuilder->getCircularReferenceGuard()->unmark($hash); return $query; }
/** * @since 2.2 * * {@inheritDoc} */ public function interpretDescription(Description $description) { $joinVariable = $this->compoundConditionBuilder->getJoinVariable(); $orderByProperty = $this->compoundConditionBuilder->getOrderByProperty(); $dataItem = $description->getDataItem(); $property = $description->getProperty(); switch ($description->getComparator()) { case SMW_CMP_EQ: $comparator = '='; break; case SMW_CMP_LESS: $comparator = '<'; break; case SMW_CMP_GRTR: $comparator = '>'; break; case SMW_CMP_LEQ: $comparator = '<='; break; case SMW_CMP_GEQ: $comparator = '>='; break; case SMW_CMP_NEQ: $comparator = '!='; break; case SMW_CMP_LIKE: $comparator = 'regex'; break; case SMW_CMP_NLKE: $comparator = '!regex'; break; default: $comparator = ''; // unkown, unsupported } if ($comparator === '') { return $this->createConditionForEmptyComparator($joinVariable, $orderByProperty); } elseif ($comparator == '=') { return $this->createConditionForEqualityComparator($dataItem, $property, $joinVariable, $orderByProperty); } elseif ($comparator == 'regex' || $comparator == '!regex') { return $this->createConditionForRegexComparator($dataItem, $joinVariable, $orderByProperty, $comparator); } return $this->createFilterConditionForAnyOtherComparator($dataItem, $joinVariable, $orderByProperty, $comparator); }
/** * @since 2.2 * * {@inheritDoc} */ public function interpretDescription(Description $description) { $joinVariable = $this->compoundConditionBuilder->getJoinVariable(); $orderByProperty = $this->compoundConditionBuilder->getOrderByProperty(); $conceptDescription = $this->getConceptDescription($description->getConcept()); if ($conceptDescription === '') { return new FalseCondition(); } $hash = 'concept-' . $conceptDescription->getQueryString(); $this->compoundConditionBuilder->getCircularReferenceGuard()->mark($hash); if ($this->compoundConditionBuilder->getCircularReferenceGuard()->isCircularByRecursionFor($hash)) { $this->compoundConditionBuilder->addError(wfMessage('smw-query-condition-circular', $conceptDescription->getQueryString())->text()); return new FalseCondition(); } $this->compoundConditionBuilder->setJoinVariable($joinVariable); $this->compoundConditionBuilder->setOrderByProperty($orderByProperty); $condition = $this->compoundConditionBuilder->mapDescriptionToCondition($conceptDescription); $this->compoundConditionBuilder->getCircularReferenceGuard()->unmark($hash); return $condition; }
/** * @since 2.2 * * {@inheritDoc} */ public function interpretDescription(Description $description) { $joinVariable = $this->compoundConditionBuilder->getJoinVariable(); $orderByProperty = $this->compoundConditionBuilder->getOrderByProperty(); $subDescriptions = $description->getDescriptions(); $result = $this->doPreliminarySubDescriptionCheck($subDescriptions, $joinVariable, $orderByProperty); if ($result !== null) { return $result; } $subConditionElements = $this->doResolveSubDescriptionsRecursively($subDescriptions, $joinVariable, $orderByProperty); if ($subConditionElements instanceof TrueCondition) { return $subConditionElements; } if ($subConditionElements->unionCondition === '' && $subConditionElements->filter === '') { return new FalseCondition(); } $result = $this->createConditionFromSubConditionElements($subConditionElements, $joinVariable); $result->weakConditions = $subConditionElements->weakConditions; $this->compoundConditionBuilder->addOrderByDataForProperty($result, $joinVariable, $orderByProperty); return $result; }
/** * Recursively create an Condition from SomeProperty * * @param SomeProperty $description * @param string $joinVariable * @param DIProperty|null $orderByProperty * * @return Condition */ public function buildCondition(Description $description, $joinVariable, $orderByProperty = null) { $property = $description->getProperty(); list($innerOrderByProperty, $innerCondition, $innerJoinVariable) = $this->doResolveInnerConditionRecursively($property, $description->getDescription()); if ($innerCondition instanceof FalseCondition) { return new FalseCondition(); } $namespaces = $innerCondition->namespaces; $objectName = $this->findObjectNameFromInnerCondition($innerCondition, $innerJoinVariable, $namespaces); list($subjectName, $objectName, $nonInverseProperty) = $this->doExchangeForWhenInversePropertyIsUsed($property, $objectName, $joinVariable); $propertyName = $this->getPropertyNameByUsingTurtleSerializer($property, $nonInverseProperty, $namespaces); $condition = $this->concatenateToConditionString($subjectName, $propertyName, $objectName, $innerCondition); $result = new WhereCondition($condition, true, $namespaces); // Record inner ordering variable if found $result->orderVariables = $innerCondition->orderVariables; if ($innerOrderByProperty !== null && $innerCondition->orderByVariable !== '') { $result->orderVariables[$property->getKey()] = $innerCondition->orderByVariable; } $this->compoundConditionBuilder->addOrderByDataForProperty($result, $joinVariable, $orderByProperty, DataItem::TYPE_WIKIPAGE); return $result; }
public function prune(&$maxsize, &$maxdepth, &$log) { if ($maxsize <= 0 || $maxdepth <= 0) { $log[] = $this->getQueryString(); return new ThingDescription(); } $maxsize--; $maxdepth--; $result = new SomeProperty($this->property, $this->description->prune($maxsize, $maxdepth, $log)); $result->setPrintRequests($this->getPrintRequests()); return $result; }
/** * Only type '_wpg' objects can appear on query level (essentially as nominal classes) * * @since 2.2 * * @param Description $description * * @return QuerySegment */ public function interpretDescription(Description $description) { $query = new QuerySegment(); if (!$description->getDataItem() instanceof DIWikiPage) { return $query; } if ($description->getComparator() === SMW_CMP_EQ) { $query->type = QuerySegment::Q_VALUE; $oid = $this->querySegmentListBuilder->getStore()->getObjectIds()->getSMWPageID($description->getDataItem()->getDBkey(), $description->getDataItem()->getNamespace(), $description->getDataItem()->getInterwiki(), $description->getDataItem()->getSubobjectName()); $query->joinfield = array($oid); } else { // Join with SMW IDs table needed for other comparators (apply to title string). $query->joinTable = SMWSql3SmwIds::TABLE_NAME; $query->joinfield = "{$query->alias}.smw_id"; $value = $description->getDataItem()->getSortKey(); $comparator = $this->comparatorMapper->mapComparator($description, $value); $query->where = "{$query->alias}.smw_sortkey{$comparator}" . $this->querySegmentListBuilder->getStore()->getConnection('mw.db')->addQuotes($value); } return $query; }
private function doMapConjunctionDisjunction(Description $description, &$exact) { $result = new ExpData(new ExpResource('')); $result->addPropertyObjectValue($this->exporter->getSpecialNsResource('rdf', 'type'), new ExpData($this->exporter->getSpecialNsResource('owl', 'Class'))); $elements = array(); foreach ($description->getDescriptions() as $subdesc) { $element = $this->getExpDataFromDescription($subdesc, $exact); if ($element === false) { $element = new ExpData($this->exporter->getSpecialNsResource('owl', 'Thing')); } $elements[] = $element; } $prop = $description instanceof Conjunction ? 'intersectionOf' : 'unionOf'; $result->addPropertyObjectValue($this->exporter->getSpecialNsResource('owl', $prop), ExpData::makeCollection($elements)); return $result; }
/** * ProfileAnnotatorDecorator::addPropertyValues */ protected function addPropertyValues() { $this->addQueryString($this->description->getQueryString()); $this->addQuerySize($this->description->getSize()); $this->addQueryDepth($this->description->getDepth()); }
/** * Extend a given description by a new one, either by adding the new description * (if the old one is a container description) or by creating a new container. * The parameter $conjunction determines whether the combination of both descriptions * should be a disjunction or conjunction. * * In the special case that the current description is NULL, the new one will just * replace the current one. * * The return value is the expected combined description. The object $currentDescription will * also be changed (if it was non-NULL). */ private function getCompoundDescription(Description $currentDescription = null, Description $newDescription = null, $compoundType = SMW_CONJUNCTION_QUERY) { $notallowedmessage = 'smw_noqueryfeature'; if ($newDescription instanceof SomeProperty) { $allowed = $this->queryFeatures & SMW_PROPERTY_QUERY; } elseif ($newDescription instanceof ClassDescription) { $allowed = $this->queryFeatures & SMW_CATEGORY_QUERY; } elseif ($newDescription instanceof ConceptDescription) { $allowed = $this->queryFeatures & SMW_CONCEPT_QUERY; } elseif ($newDescription instanceof Conjunction) { $allowed = $this->queryFeatures & SMW_CONJUNCTION_QUERY; $notallowedmessage = 'smw_noconjunctions'; } elseif ($newDescription instanceof Disjunction) { $allowed = $this->queryFeatures & SMW_DISJUNCTION_QUERY; $notallowedmessage = 'smw_nodisjunctions'; } else { $allowed = true; } if (!$allowed) { $this->addErrorWithMsgKey($notallowedmessage, $newDescription->getQueryString()); return $currentDescription; } if ($newDescription === null) { return $currentDescription; } elseif ($currentDescription === null) { return $newDescription; } else { // we already found descriptions return $this->newCompoundDescriptionFor($compoundType, $currentDescription, $newDescription); } }