/** * Constructs a result graph. * * @param array $arVartable A table containing the result vars and their bindings * @param GraphPattern $constructPattern The CONSTRUCT pattern * @return MemModel The result graph which matches the CONSTRUCT pattern */ function constructGraph($arVartable, $constructPattern) { $resultGraph = new MemModel(); if (!$arVartable) { return $resultGraph; } $tp = $constructPattern->getTriplePatterns(); $bnode = 0; foreach ($arVartable as $value) { foreach ($tp as $triple) { $sub = $triple->getSubject(); $pred = $triple->getPredicate(); $obj = $triple->getObject(); if (is_string($sub) && $sub[1] == '_') { $sub = new BlankNode("_bN" . $bnode); } if (is_string($pred) && $pred[1] == '_') { $pred = new BlankNode("_bN" . $bnode); } if (is_string($obj) && $obj[1] == '_') { $obj = new BlankNode("_bN" . $bnode); } if (is_string($sub)) { $sub = $value[$sub]; } if (is_string($pred)) { $pred = $value[$pred]; } if (is_string($obj)) { $obj = $value[$obj]; } if ($sub !== "" && $pred !== "" && $obj !== "") { $resultGraph->add(new Statement($sub, $pred, $obj)); } } $bnode++; } return $resultGraph; }
/** * Parses a value constraint. * * @param GraphPattern $pattern * @param boolean $outer If the constraint is an outer one. */ protected function _parseConstraint(&$pattern, $outer) { require_once 'Erfurt/Sparql/Constraint.php'; $constraint = new Erfurt_Sparql_Constraint(); $constraint->setOuterFilter($outer); $constraint->setTree($this->_parseConstraintTree()); if (current($this->_tokens) === '}') { prev($this->_tokens); } $pattern->addConstraint($constraint); }
/** * Parses a value constraint. * * @param GraphPattern $pattern * @param boolean $outer If the constraint is an outer one. * @return void */ protected function parseConstraint(&$pattern, $outer) { $constraint = new Constraint(); $constraint->setOuterFilter($outer); $this->_fastForward(); $this->_rewind(); $nBeginKey = key($this->tokens); $constraint->setTree($t = $this->parseConstraintTree()); $nEndKey = key($this->tokens); if (current($this->tokens) == '}') { prev($this->tokens); } //for backwards compatibility with the normal sparql engine // which does not use the tree array currently $expression = trim(implode('', array_slice($this->tokens, $nBeginKey + 1, $nEndKey - $nBeginKey - 1))); if ($expression[0] == '(' && substr($expression, -1) == ')') { $expression = trim(substr($expression, 1, -1)); } $constraint->addExpression($expression); $pattern->addConstraint($constraint); }
/** * Creates some SQL statements from the given triple pattern * array. * * @param QueryTriple $triple Array containing subject, predicate and object * @param GraphPattern $graphPattern Graph pattern object * * @return array Array consisting of on array and two string values: * SELECT, FROM and WHERE part */ function getTripleSql(QueryTriple $triple, GraphPattern $graphPattern, $arResultVars) { $arSelect = array(); $strFrom = null; $strWhere = null; $strWhereEquality = ''; $bWhereEqualitySubject = false; $bWhereEqualityPredicate = false; $bWhereEqualityObject = false; $subject = $triple->getSubject(); $predicate = $triple->getPredicate(); $object = $triple->getObject(); $arRefVars = array(); $strTablePrefix = 't' . $this->nTableId; /** * SELECT part * We do select only the columns we need for variables */ if (SparqlVariable::isVariable($subject)) { if (isset($this->arUnionVarAssignments[$this->nUnionCount][$subject])) { //already selected -> add equality check $bWhereEqualitySubject = true; $this->arUsedVarTypes[$subject]['s'] = true; } else { if (isset($this->arVarAssignments[$subject][0])) { $strTablePrefix = $this->arVarAssignments[$subject][0]; } $this->arVarAssignments[$subject] = array($strTablePrefix, 's'); $this->arUnionVarAssignments[$this->nUnionCount][$subject] = array($strTablePrefix, 's'); $this->arUsedVarTypes[$subject]['s'] = true; if (self::isResultVar($subject, $arResultVars)) { //new variable that needs to be selected $arSelect[$subject] = $this->createVariableSelectArray('s', $subject, $strTablePrefix); if (isset($this->arUsedVarAssignments[$subject])) { $arRefVars[$subject] = $strTablePrefix . '.subject'; } else { $this->arUsedVarAssignments[$subject] = $strTablePrefix . '.subject'; } } } } if (SparqlVariable::isVariable($predicate)) { if (isset($this->arUnionVarAssignments[$this->nUnionCount][$predicate])) { //already selected -> add equality check $bWhereEqualityPredicate = true; $this->arUsedVarTypes[$predicate]['p'] = true; } else { if (isset($this->arVarAssignments[$predicate][0])) { $strTablePrefix = $this->arVarAssignments[$predicate][0]; } $this->arVarAssignments[$predicate] = array($strTablePrefix, 'p'); $this->arUnionVarAssignments[$this->nUnionCount][$predicate] = array($strTablePrefix, 'p'); $this->arUsedVarTypes[$predicate]['p'] = true; if (self::isResultVar($predicate, $arResultVars)) { $arSelect[$predicate] = $this->createVariableSelectArray('p', $predicate, $strTablePrefix); if (isset($this->arUsedVarAssignments[$predicate])) { $arRefVars[$predicate] = $strTablePrefix . '.predicate'; } else { $this->arUsedVarAssignments[$predicate] = $strTablePrefix . '.predicate'; } } } } if (SparqlVariable::isVariable($object)) { if (isset($this->arUnionVarAssignments[$this->nUnionCount][$object])) { //already selected -> add equality check $bWhereEqualityObject = true; $this->arUsedVarTypes[$object]['o'] = true; } else { if (isset($this->arVarAssignments[$object][0])) { $strTablePrefix = $this->arVarAssignments[$object][0]; } $this->arVarAssignments[$object] = array($strTablePrefix, 'o'); $this->arUnionVarAssignments[$this->nUnionCount][$object] = array($strTablePrefix, 'o'); $this->arUsedVarTypes[$object]['o'] = true; if (self::isResultVar($object, $arResultVars)) { $arSelect[$object] = $this->createVariableSelectArray('o', $object, $strTablePrefix); if (isset($this->arUsedVarAssignments[$object])) { $arRefVars[$object] = $strTablePrefix . '.object'; } else { $this->arUsedVarAssignments[$object] = $strTablePrefix . '.object'; } } if (isset($this->query->varLanguages[$object]) && $this->query->varLanguages[$object] !== null) { $strWhereEquality .= ' AND ' . $strTablePrefix . '.l_language = "' . addslashes($this->query->varLanguages[$object]) . '"'; } if (isset($this->query->varDatatypes[$object]) && $this->query->varDatatypes[$object] !== null) { $strWhereEquality .= ' AND ' . $strTablePrefix . '.l_datatype = "' . addslashes($this->query->varDatatypes[$object]) . '"'; } } } /** * WhereEquality - needs to be done now because strTablePrefix may change */ if ($bWhereEqualitySubject) { $strWhereEquality .= ' AND ' . self::getSqlEqualityCondition(array($strTablePrefix, 's'), $this->arVarAssignments[$subject]); } if ($bWhereEqualityPredicate) { $strWhereEquality .= ' AND ' . self::getSqlEqualityCondition(array($strTablePrefix, 'p'), $this->arVarAssignments[$predicate]); } if ($bWhereEqualityObject) { $strWhereEquality .= ' AND ' . self::getSqlEqualityCondition(array($strTablePrefix, 'o'), $this->arVarAssignments[$object]); } /** * FROM part */ if ($this->nUnionTriplePatternCount == 0) { //first FROM $strFrom = $this->tblStatements . ' as ' . $strTablePrefix; } else { //normal join if (count($this->arModelIds) == 1) { $strFrom = 'LEFT JOIN ' . $this->tblStatements . ' as ' . $strTablePrefix . ' ON t0.modelID = ' . $strTablePrefix . '.modelID'; } else { if (count($this->arModelIds) > 1) { $arIDs = array(); foreach ($this->arModelIds as $nId) { $arIDs[] = $strTablePrefix . '.modelID = ' . intval($nId); } $strFrom = 'LEFT JOIN ' . $this->tblStatements . ' as ' . $strTablePrefix . ' ON (' . implode(' OR ', $arIDs) . ')'; } else { $strFrom = 'LEFT JOIN ' . $this->tblStatements . ' as ' . $strTablePrefix . ' ON t0.modelID = ' . $strTablePrefix . '.modelID'; } } foreach ($arRefVars as $strRefVar => $strSqlVar) { $strFrom .= ' AND ' . $this->arUsedVarAssignments[$strRefVar] . ' = ' . $strSqlVar; } if ($graphPattern->getOptional() !== null) { $strFrom .= $this->getSqlCondition($subject, $strTablePrefix, 'subject') . $this->getSqlCondition($predicate, $strTablePrefix, 'predicate') . $this->getSqlCondition($object, $strTablePrefix, 'object') . $strWhereEquality; } } /** * WHERE part */ if ($this->nUnionTriplePatternCount == 0) { if (count($this->arModelIds) == 1) { $strWhere = $strTablePrefix . '.modelID = ' . intval(reset($this->arModelIds)); } else { if (count($this->arModelIds) > 1) { $arIDs = array(); foreach ($this->arModelIds as $nId) { $arIDs[] = $strTablePrefix . '.modelID = ' . intval($nId); } $strWhere = '(' . implode(' OR ', $arIDs) . ')'; } else { //so that we can append an AND $strWhere = '1'; } } } if ($graphPattern->getOptional() === null || $this->nGraphPatternCount == 0) { $strWhere .= $this->getSqlCondition($subject, $strTablePrefix, 'subject') . $this->getSqlCondition($predicate, $strTablePrefix, 'predicate') . $this->getSqlCondition($object, $strTablePrefix, 'object') . $strWhereEquality; } return array($arSelect, $strFrom, $strWhere); }
/** * Adds a graph pattern to the result part. * * @param GraphPattern $pattern * @return void */ public function addGraphPattern($pattern) { $pattern->setId($this->graphPatternCounter); $this->resultPart[] = $pattern; $this->graphPatternCounter++; }
/** * Parses a value constraint. * * @param GraphPattern $pattern * @return void */ protected function parseConstraint($pattern, $outer) { $constraint = new Constraint(); $constraint->setOuterFilter($outer); $this->_fastForward(); if (current($this->tokens) == '(') { $this->parseBrackettedExpression(&$constraint); } else { $this->parseExpression(&$constraint); } $pattern->addConstraint(&$constraint); }
/** * Builds the resultset. * * @param GraphPattern $pattern * @param Array $resmodel * @return Array */ protected function _buildResultSet($pattern, $resmodel) { // determine variables and their corresponding values $result = null; if (is_string($pattern->getSubject())) { $n = 0; foreach ($resmodel['trip'] as $key => $triple) { if (isset($resmodel['graphvar'][$key])) { $result[$n][$resmodel['graphvar'][$key]] = $resmodel['graph'][$key]; } $result[$n++][$pattern->getSubject()] = $triple->subj; } } if (is_string($pattern->getPredicate())) { $n = 0; foreach ($resmodel['trip'] as $key => $triple) { if (isset($resmodel['graphvar'][$key])) { $result[$n][$resmodel['graphvar'][$key]] = $resmodel['graph'][$key]; } $result[$n++][$pattern->getPredicate()] = $triple->pred; } } if (is_string($pattern->getObject())) { $n = 0; foreach ($resmodel['trip'] as $key => $triple) { if (isset($resmodel['graphvar'][$key])) { $result[$n][$resmodel['graphvar'][$key]] = $resmodel['graph'][$key]; } $result[$n++][$pattern->getObject()] = $triple->obj; } } return $result; }