private function doResolveSubDescriptionsRecursively($subDescriptions, $joinVariable, $orderByProperty) { // Using a stdClass as data container for simpler handling in follow-up tasks // and as the class is not exposed publicly we don't need to create // an extra "real" class to manage its elements $subConditionElements = new \stdClass(); $subConditionElements->unionCondition = ''; $subConditionElements->filter = ''; $namespaces = $weakConditions = array(); $hasSafeSubconditions = false; foreach ($subDescriptions as $subDescription) { $this->compoundConditionBuilder->setJoinVariable($joinVariable); $this->compoundConditionBuilder->setOrderByProperty(null); $subCondition = $this->compoundConditionBuilder->mapDescriptionToCondition($subDescription); if ($subCondition instanceof FalseCondition) { // empty parts in a disjunction can be ignored } elseif ($subCondition instanceof TrueCondition) { return $this->compoundConditionBuilder->newTrueCondition($joinVariable, $orderByProperty); } elseif ($subCondition instanceof WhereCondition) { $hasSafeSubconditions = $hasSafeSubconditions || $subCondition->isSafe(); $subConditionElements->unionCondition .= ($subConditionElements->unionCondition ? ' UNION ' : '') . "{\n" . $subCondition->condition . "}"; } elseif ($subCondition instanceof FilterCondition) { $subConditionElements->filter .= ($subConditionElements->filter ? ' || ' : '') . $subCondition->filter; } elseif ($subCondition instanceof SingletonCondition) { $hasSafeSubconditions = $hasSafeSubconditions || $subCondition->isSafe(); $matchElement = $subCondition->matchElement; if ($matchElement instanceof ExpElement) { $matchElementName = TurtleSerializer::getTurtleNameForExpElement($matchElement); } else { $matchElementName = $matchElement; } if ($matchElement instanceof ExpNsResource) { $namespaces[$matchElement->getNamespaceId()] = $matchElement->getNamespace(); } if ($subCondition->condition === '') { $subConditionElements->filter .= ($subConditionElements->filter ? ' || ' : '') . "?{$joinVariable} = {$matchElementName}"; } else { $subConditionElements->unionCondition .= ($subConditionElements->unionCondition ? ' UNION ' : '') . "{\n" . $subCondition->condition . " FILTER( ?{$joinVariable} = {$matchElementName} ) }"; } // Relates to wikipage [[Foo::~*a*||~*A*]] in value regex disjunction // where a singleton is required to search against the sortkey but // replacing the filter with the condition temporary stored in // weakconditions if ($subConditionElements->unionCondition && $subCondition->weakConditions !== array()) { $weakCondition = array_shift($subCondition->weakConditions); $subConditionElements->unionCondition = str_replace("FILTER( ?{$joinVariable} = {$matchElementName} )", $weakCondition, $subConditionElements->unionCondition); } } $namespaces = array_merge($namespaces, $subCondition->namespaces); $weakConditions = array_merge($weakConditions, $subCondition->weakConditions); } $subConditionElements->namespaces = $namespaces; $subConditionElements->weakConditions = $weakConditions; $subConditionElements->hasSafeSubconditions = $hasSafeSubconditions; return $subConditionElements; }
/** * @dataProvider comparatorProvider */ public function testValueConditionForDifferentComparators($description, $expectedConditionType, $expectedConditionString) { $resultVariable = 'result'; $compoundConditionBuilder = new CompoundConditionBuilder(); $compoundConditionBuilder->setResultVariable($resultVariable); $compoundConditionBuilder->setJoinVariable($resultVariable); $instance = new ValueDescriptionInterpreter($compoundConditionBuilder); $condition = $instance->interpretDescription($description); $this->assertInstanceOf($expectedConditionType, $condition); $this->assertEquals($expectedConditionString, $compoundConditionBuilder->convertConditionToString($condition)); }
/** * @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; }
/** * @dataProvider descriptionProvider */ public function testThingDescriptionInterpreter($description, $orderByProperty, $expectedConditionType, $expectedConditionString) { $resultVariable = 'result'; $compoundConditionBuilder = new CompoundConditionBuilder(); $compoundConditionBuilder->setResultVariable($resultVariable); $compoundConditionBuilder->setJoinVariable($resultVariable); $compoundConditionBuilder->setOrderByProperty($orderByProperty); $instance = new ThingDescriptionInterpreter($compoundConditionBuilder); $condition = $instance->interpretDescription($description); $this->assertInstanceOf($expectedConditionType, $condition); $this->assertEquals($expectedConditionString, $compoundConditionBuilder->convertConditionToString($condition)); }
private function doResolveSubDescriptionsRecursively($subDescriptions, $joinVariable) { // Using a stdClass as data container for simpler handling in follow-up tasks // and as the class is not exposed publicly we don't need to create // an extra "real" class to manage its elements $subConditionElements = new \stdClass(); $subConditionElements->condition = ''; $subConditionElements->filter = ''; $subConditionElements->singletonMatchElement = null; $namespaces = $weakConditions = $orderVariables = array(); $singletonMatchElementName = ''; $hasSafeSubconditions = false; foreach ($subDescriptions as $subDescription) { $this->compoundConditionBuilder->setJoinVariable($joinVariable); $this->compoundConditionBuilder->setOrderByProperty(null); $subCondition = $this->compoundConditionBuilder->mapDescriptionToCondition($subDescription); if ($subCondition instanceof FalseCondition) { return new FalseCondition(); } elseif ($subCondition instanceof TrueCondition) { // ignore true conditions in a conjunction } elseif ($subCondition instanceof WhereCondition) { $subConditionElements->condition .= $subCondition->condition; } elseif ($subCondition instanceof FilterCondition) { $subConditionElements->filter .= ($subConditionElements->filter ? ' && ' : '') . $subCondition->filter; } elseif ($subCondition instanceof SingletonCondition) { $matchElement = $subCondition->matchElement; if ($matchElement instanceof ExpElement) { $matchElementName = TurtleSerializer::getTurtleNameForExpElement($matchElement); } else { $matchElementName = $matchElement; } if ($matchElement instanceof ExpNsResource) { $namespaces[$matchElement->getNamespaceId()] = $matchElement->getNamespace(); } if ($subConditionElements->singletonMatchElement !== null && $singletonMatchElementName !== $matchElementName) { return new FalseCondition(); } $subConditionElements->condition .= $subCondition->condition; $subConditionElements->singletonMatchElement = $subCondition->matchElement; $singletonMatchElementName = $matchElementName; } $hasSafeSubconditions = $hasSafeSubconditions || $subCondition->isSafe(); $namespaces = array_merge($namespaces, $subCondition->namespaces); $weakConditions = array_merge($weakConditions, $subCondition->weakConditions); $orderVariables = array_merge($orderVariables, $subCondition->orderVariables); } $subConditionElements->hasSafeSubconditions = $hasSafeSubconditions; $subConditionElements->namespaces = $namespaces; $subConditionElements->weakConditions = $weakConditions; $subConditionElements->orderVariables = $orderVariables; return $subConditionElements; }
private function doResolveInnerConditionRecursively(DIProperty $property, Description $description) { $innerOrderByProperty = null; // Find out if we should order by the values of this property if (array_key_exists($property->getKey(), $this->compoundConditionBuilder->getSortKeys())) { $innerOrderByProperty = $property; } // Prepare inner condition $innerJoinVariable = $this->compoundConditionBuilder->getNextVariable(); $this->compoundConditionBuilder->setJoinVariable($innerJoinVariable); $this->compoundConditionBuilder->setOrderByProperty($innerOrderByProperty); $innerCondition = $this->compoundConditionBuilder->mapDescriptionToCondition($description); return array($innerOrderByProperty, $innerCondition, $innerJoinVariable); }
public function testHierarchyPattern() { $property = new DIProperty('Foo'); $propertyHierarchyExaminer = $this->getMockBuilder('\\SMW\\PropertyHierarchyExaminer')->disableOriginalConstructor()->getMock(); $propertyHierarchyExaminer->expects($this->once())->method('hasSubpropertyFor')->with($this->equalTo($property))->will($this->returnValue(true)); $resultVariable = 'result'; $compoundConditionBuilder = new CompoundConditionBuilder(); $compoundConditionBuilder->setPropertyHierarchyExaminer($propertyHierarchyExaminer); $compoundConditionBuilder->setResultVariable($resultVariable); $compoundConditionBuilder->setJoinVariable($resultVariable); $instance = new SomePropertyInterpreter($compoundConditionBuilder); $description = new SomeProperty($property, new ThingDescription()); $condition = $instance->interpretDescription($description); $expected = UtilityFactory::getInstance()->newStringBuilder()->addString('?result ?sp2 ?v1 .')->addNewLine()->addString('{ ')->addNewLine()->addString('?sp2 rdfs:subPropertyOf* property:Foo .')->addNewLine()->addString('}')->addNewLine()->getString(); $this->assertEquals($expected, $compoundConditionBuilder->convertConditionToString($condition)); }
public function testHierarchyPattern() { $category = new DIWikiPage('Foo', NS_CATEGORY); $categoryName = \SMWTurtleSerializer::getTurtleNameForExpElement(\SMWExporter::getInstance()->getResourceElementForWikiPage($category)); $propertyHierarchyLookup = $this->getMockBuilder('\\SMW\\PropertyHierarchyLookup')->disableOriginalConstructor()->getMock(); $propertyHierarchyLookup->expects($this->once())->method('hasSubcategoryFor')->with($this->equalTo($category))->will($this->returnValue(true)); $resultVariable = 'result'; $compoundConditionBuilder = new CompoundConditionBuilder($this->descriptionInterpreterFactory); $compoundConditionBuilder->setPropertyHierarchyLookup($propertyHierarchyLookup); $compoundConditionBuilder->setResultVariable($resultVariable); $compoundConditionBuilder->setJoinVariable($resultVariable); $instance = new ClassDescriptionInterpreter($compoundConditionBuilder); $condition = $instance->interpretDescription(new ClassDescription($category)); $expected = UtilityFactory::getInstance()->newStringBuilder()->addString('{')->addNewLine()->addString("?sc1 rdfs:subClassOf* {$categoryName} .")->addNewLine()->addString('?result rdf:type ?sc1 . }')->addNewLine()->getString(); $this->assertEquals($expected, $compoundConditionBuilder->convertConditionToString($condition)); }
public function testConceptDescriptionInterpreterForAnyValueConceptUsingMockedStore() { $circularReferenceGuard = $this->getMockBuilder('\\SMW\\CircularReferenceGuard')->disableOriginalConstructor()->getMock(); $semanticData = $this->getMockBuilder('\\SMW\\SemanticData')->disableOriginalConstructor()->getMock(); $semanticData->expects($this->once())->method('getPropertyValues')->with($this->equalTo(new DIProperty('_CONC')))->will($this->returnValue(array(new DIConcept('[[Foo::+]]', 'Bar', 1, 0, 0)))); $store = $this->getMockBuilder('\\SMW\\Store')->disableOriginalConstructor()->getMockForAbstractClass(); $store->expects($this->any())->method('getSemanticData')->with($this->equalTo(new DIWikiPage('Foo', SMW_NS_CONCEPT)))->will($this->returnValue($semanticData)); $this->applicationFactory = ApplicationFactory::getInstance(); $this->applicationFactory->registerObject('Store', $store); $description = new ConceptDescription(new DIWikiPage('Foo', SMW_NS_CONCEPT)); $orderByProperty = null; $resultVariable = 'result'; $compoundConditionBuilder = new CompoundConditionBuilder(); $compoundConditionBuilder->setResultVariable($resultVariable); $compoundConditionBuilder->setCircularReferenceGuard($circularReferenceGuard); $compoundConditionBuilder->setJoinVariable($resultVariable); $compoundConditionBuilder->setOrderByProperty($orderByProperty); $instance = new ConceptDescriptionInterpreter($compoundConditionBuilder); $condition = $instance->interpretDescription($description); $expectedConditionString = UtilityFactory::getInstance()->newStringBuilder()->addString('?result property:Foo ?v1 .')->addNewLine()->getString(); $this->assertInstanceOf('\\SMW\\SPARQLStore\\QueryEngine\\Condition\\WhereCondition', $condition); $this->assertEquals($expectedConditionString, $compoundConditionBuilder->convertConditionToString($condition)); }