1 | <?php
|
---|
2 |
|
---|
3 | // ----------------------------------------------------------------------------------
|
---|
4 | // Class: RdqlMemEngine
|
---|
5 | // ----------------------------------------------------------------------------------
|
---|
6 |
|
---|
7 | /**
|
---|
8 | * This class performes as RDQL query on a MemModel.
|
---|
9 | *
|
---|
10 | * Provided an rdql query parsed into an array of php variables and constraints
|
---|
11 | * at first the engine searches for tuples matching all patterns from the WHERE clause
|
---|
12 | * of the given RDQL query. Then the query result set is filtered with evaluated
|
---|
13 | * boolean expressions from the AND clause of the given RDQL query.
|
---|
14 | *
|
---|
15 | * @version $Id: RdqlMemEngine.php 268 2006-05-15 05:28:09Z tgauss $
|
---|
16 | * @author Radoslaw Oldakowski <radol@gmx.de>
|
---|
17 | *
|
---|
18 | * @package rdql
|
---|
19 | * @access public
|
---|
20 | */
|
---|
21 |
|
---|
22 | Class RdqlMemEngine extends RdqlEngine {
|
---|
23 |
|
---|
24 |
|
---|
25 | /**
|
---|
26 | * Parsed query variables and constraints.
|
---|
27 | *
|
---|
28 | * @var array ['selectVars'][] = ?VARNAME
|
---|
29 | * ['sources'][] = URI
|
---|
30 | * ['patterns'][]['subject']['value'] = VARorURI
|
---|
31 | * ['predicate']['value'] = VARorURI
|
---|
32 | * ['object']['value'] = VARorURIorLiterl
|
---|
33 | * ['is_literal'] = boolean
|
---|
34 | * ['l_lang'] = string
|
---|
35 | * ['l_dtype'] = string
|
---|
36 | * ['filters'][]['string'] = string
|
---|
37 | * ['evalFilterStr'] = string
|
---|
38 | * ['reqexEqExprs'][]['var'] = ?VARNAME
|
---|
39 | * ['operator'] = (eq | ne)
|
---|
40 | * ['regex'] = string
|
---|
41 | * ['strEqExprs'][]['var'] = ?VARNAME
|
---|
42 | * ['operator'] = (eq | ne)
|
---|
43 | * ['value'] = string
|
---|
44 | * ['value_type'] = ('variable' | 'URI' | 'Literal')
|
---|
45 | * ['value_lang'] = string
|
---|
46 | * ['value_dtype'] = string
|
---|
47 | * ['numExpr']['vars'][] = ?VARNAME
|
---|
48 | * ( [] stands for an integer index - 0..N )
|
---|
49 | * @access private
|
---|
50 | */
|
---|
51 | var $parsedQuery;
|
---|
52 |
|
---|
53 |
|
---|
54 | /**
|
---|
55 | * Perform an RDQL Query on the given MemModel.
|
---|
56 | *
|
---|
57 | * @param object MemModel &$memModel
|
---|
58 | * @param array &$parsedQuery (the same format as $this->parsedQuery)
|
---|
59 | * @param boolean $returnNodes
|
---|
60 | * @return array [][?VARNAME] = object Node (if $returnNodes = TRUE)
|
---|
61 | * OR array [][?VARNAME] = string
|
---|
62 | *
|
---|
63 | * @access public
|
---|
64 | */
|
---|
65 | function & queryModel(&$memModel, &$parsedQuery, $returnNodes = TRUE) {
|
---|
66 |
|
---|
67 | $this->parsedQuery = $parsedQuery;
|
---|
68 |
|
---|
69 | // find tuples matching all patterns
|
---|
70 | $res = $this->findTuplesMatchingAllPatterns($memModel);
|
---|
71 |
|
---|
72 | // filter tuples
|
---|
73 | if (isset($parsedQuery['filters']))
|
---|
74 | $res = $this->filterTuples($res);
|
---|
75 |
|
---|
76 | // select variables to be returned
|
---|
77 | $res = $this->selectVariables($res);
|
---|
78 |
|
---|
79 | if(!$returnNodes)
|
---|
80 | return $this->toString($res);
|
---|
81 |
|
---|
82 | return $res;
|
---|
83 | }
|
---|
84 |
|
---|
85 |
|
---|
86 | /**
|
---|
87 | * Find triples matching all patterns of an RDQL query and return an array
|
---|
88 | * with variables from all patterns and their corresponding values.
|
---|
89 | * The variable values returned are instances of object Node.
|
---|
90 | *
|
---|
91 | * @param object MemModel &$memModel
|
---|
92 | * @return array [][?VARNAME] = object Node
|
---|
93 | *
|
---|
94 | * @access private
|
---|
95 | */
|
---|
96 | function findTuplesMatchingAllPatterns(&$memModel) {
|
---|
97 |
|
---|
98 | $resultSet = $this->findTuplesMatchingOnePattern($memModel, $this->parsedQuery['patterns'][0]);
|
---|
99 | for ($i=1; $i<count($this->parsedQuery['patterns']); $i++) {
|
---|
100 | $rs = $this->findTuplesMatchingOnePattern($memModel, $this->parsedQuery['patterns'][$i]);
|
---|
101 | $resultSet = $this->joinTuples($resultSet, $rs);
|
---|
102 | }
|
---|
103 | return $resultSet;
|
---|
104 | }
|
---|
105 |
|
---|
106 |
|
---|
107 | /**
|
---|
108 | * Find tuples matching one pattern and return an array with pattern
|
---|
109 | * variables and their corresponding values (instances of object Node).
|
---|
110 | *
|
---|
111 | * @param object MemModel &$memModel
|
---|
112 | * @param array &$pattern ['subject']['value'] = VARorURI
|
---|
113 | * ['predicate']['value'] = VARorURI
|
---|
114 | * ['object']['value'] = VARorURIorLiterl
|
---|
115 | * ['is_literal'] = boolean
|
---|
116 | * ['l_lang'] = string
|
---|
117 | * ['l_dtype'] = string
|
---|
118 | * @return array [][?VARNAME] = object Node
|
---|
119 | *
|
---|
120 | * @access private
|
---|
121 | */
|
---|
122 | function findTuplesMatchingOnePattern(&$memModel, &$pattern) {
|
---|
123 |
|
---|
124 | $resultSet = array();
|
---|
125 | $i = 0;
|
---|
126 | // parameters to be passed to the method findTriplesMatchingPattern
|
---|
127 | foreach ($pattern as $key => $v) {
|
---|
128 | if ($v['value'] && $v['value']{0} == '?') {
|
---|
129 | if ($key == 'object') {
|
---|
130 | $param['object']['is_a'] = 'ANY';
|
---|
131 | $param['object']['string'] = 'ANY';
|
---|
132 | $param['object']['lang'] = NULL;
|
---|
133 | $param['object']['dtype'] = NULL;
|
---|
134 | } else
|
---|
135 | $param[$key] = 'ANY';
|
---|
136 | $var[$i]['key'] = $key;
|
---|
137 | $var[$i++]['val'] = $v['value'];
|
---|
138 | }else
|
---|
139 | if (isset($v['is_literal'])) {
|
---|
140 | $param[$key]['is_a'] = 'Literal';
|
---|
141 | $param[$key]['string'] = $v['value'];
|
---|
142 | $param[$key]['lang'] = $v['l_lang'];
|
---|
143 | $param[$key]['dtype'] = $v['l_dtype'];
|
---|
144 | }else{
|
---|
145 | if ($key == 'object') {
|
---|
146 | $param[$key]['is_a'] = 'Resource';
|
---|
147 | $param[$key]['string'] = $v['value'];
|
---|
148 | $param[$key]['lang'] = NULL;
|
---|
149 | $param[$key]['dtype'] = NULL;
|
---|
150 | }else
|
---|
151 | $param[$key] = $v['value'];
|
---|
152 | }
|
---|
153 | }
|
---|
154 |
|
---|
155 | // find pattern internal bindings e.g. (?x, ?z, ?x)
|
---|
156 | $intBindings = NULL;
|
---|
157 | for ($i=0; $i<count($var); $i++)
|
---|
158 | foreach($var as $n => $v)
|
---|
159 | if ($i != $n && $var[$i]['val'] == $v['val'])
|
---|
160 | $intBindings[] = $var[$i]['key'];
|
---|
161 |
|
---|
162 | // find triples of the $memModel matching $pattern
|
---|
163 | $resModel = $this->findTriplesMatchingPattern($memModel, $param['subject'],
|
---|
164 | $param['predicate'],
|
---|
165 | $param['object']['is_a'],
|
---|
166 | $param['object']['string'],
|
---|
167 | $param['object']['lang'],
|
---|
168 | $param['object']['dtype'],
|
---|
169 | $intBindings);
|
---|
170 |
|
---|
171 | // set values of the pattern variables to be returned
|
---|
172 | if ($pattern['subject']['value']{0} == '?') {
|
---|
173 | $n = 0;
|
---|
174 | foreach ($resModel->triples as $triple)
|
---|
175 | $resultSet[$n++][$pattern['subject']['value']] = $triple->subj;
|
---|
176 | }
|
---|
177 | if ($pattern['predicate']['value']{0} == '?') {
|
---|
178 | $n = 0;
|
---|
179 | foreach ($resModel->triples as $triple)
|
---|
180 | $resultSet[$n++][$pattern['predicate']['value']] = $triple->pred;
|
---|
181 | }
|
---|
182 | if ($pattern['object']['value'] && $pattern['object']['value']{0} == '?') {
|
---|
183 | $n = 0;
|
---|
184 | foreach ($resModel->triples as $triple)
|
---|
185 | $resultSet[$n++][$pattern['object']['value']] = $triple->obj;
|
---|
186 | }
|
---|
187 | return $resultSet;
|
---|
188 | }
|
---|
189 |
|
---|
190 |
|
---|
191 | /**
|
---|
192 | * Search in $memModel for triples matching one pattern from the WHERE clause.
|
---|
193 | * 'ANY' input for $subjLabel..$objLabel, $obj_is will match anything.
|
---|
194 | * NULL input for $objDtype will only match obj->dtype = NULL
|
---|
195 | * NULL input for $objLanguage will match obj->lang = NULL or anything if a
|
---|
196 | * literal is datatyped (except for XMLLiterals and plain literals)
|
---|
197 | * This method also checks internal bindings if provided.
|
---|
198 | *
|
---|
199 | * @param object MemModel $memModel
|
---|
200 | * @param string $subjLabel
|
---|
201 | * @param string $predLabel
|
---|
202 | * @param string $objLabel
|
---|
203 | * @param string $obj_is
|
---|
204 | * @param string $objLanguage
|
---|
205 | * @param string $objDtype
|
---|
206 | * @param array $intBindings [] = string
|
---|
207 | * @return object MemModel
|
---|
208 | * @access private
|
---|
209 | */
|
---|
210 | function findTriplesMatchingPattern(&$memModel, $subjLabel, $predLabel, $obj_is,
|
---|
211 | $objLabel, $objLang, $objDtype, &$intBindings) {
|
---|
212 |
|
---|
213 | $res = new MemModel();
|
---|
214 |
|
---|
215 | if($memModel->isEmpty())
|
---|
216 | return $res;
|
---|
217 |
|
---|
218 | if ($subjLabel=='ANY')
|
---|
219 | {
|
---|
220 | $subj=NULL;
|
---|
221 | } else
|
---|
222 | {
|
---|
223 | $subj=new Resource($subjLabel);
|
---|
224 | };
|
---|
225 | if ($predLabel=='ANY')
|
---|
226 | {
|
---|
227 | $pred=NULL;
|
---|
228 | } else
|
---|
229 | {
|
---|
230 | $pred=new Resource($predLabel);
|
---|
231 | };
|
---|
232 |
|
---|
233 | if ($objLabel=='ANY')
|
---|
234 | {
|
---|
235 | $obj=NULL;
|
---|
236 | } else
|
---|
237 | {
|
---|
238 | if ($obj_is == 'Literal')
|
---|
239 | {
|
---|
240 | $obj=new Literal($objLabel);
|
---|
241 | $obj->setDatatype($objDtype);
|
---|
242 | $obj->setLanguage($objLang);
|
---|
243 | } else {
|
---|
244 | $obj=new Resource($objLabel);
|
---|
245 | }
|
---|
246 | };
|
---|
247 |
|
---|
248 | $res=$memModel->find($subj,$pred,$obj);
|
---|
249 |
|
---|
250 | if ($intBindings)
|
---|
251 | foreach ($res->triples as $triple)
|
---|
252 | {
|
---|
253 | if (!$this->_checkIntBindings($triple, $intBindings))
|
---|
254 | {
|
---|
255 | $res->remove($triple);
|
---|
256 | }
|
---|
257 | }
|
---|
258 |
|
---|
259 | return $res;
|
---|
260 | }
|
---|
261 |
|
---|
262 |
|
---|
263 | /**
|
---|
264 | * Perform an SQL-like inner join on two resultSets.
|
---|
265 | *
|
---|
266 | * @param array &$finalRes [][?VARNAME] = object Node
|
---|
267 | * @param array &$res [][?VARNAME] = object Node
|
---|
268 | * @return array [][?VARNAME] = object Node
|
---|
269 | *
|
---|
270 | * @access private
|
---|
271 | */
|
---|
272 | function joinTuples(&$finalRes, &$res) {
|
---|
273 |
|
---|
274 | if (count($finalRes) == 0 || count($res) == 0)
|
---|
275 | return array();
|
---|
276 |
|
---|
277 | // find joint variables and new variables to be added to $finalRes
|
---|
278 | $jointVars = array();
|
---|
279 | $newVars = array();
|
---|
280 | foreach ($res[0] as $varname => $node) {
|
---|
281 | if (array_key_exists($varname, $finalRes[0]))
|
---|
282 | $jointVars[] = $varname;
|
---|
283 | else
|
---|
284 | $newVars[] = $varname;
|
---|
285 | }
|
---|
286 |
|
---|
287 | // eliminate rows of $finalRes in which the values of $jointVars do not have
|
---|
288 | // a corresponding row in $res.
|
---|
289 | foreach ($finalRes as $n => $fRes) {
|
---|
290 | foreach ($res as $i => $r) {
|
---|
291 | $ok = TRUE;
|
---|
292 | foreach ($jointVars as $j_varname)
|
---|
293 | if ($r[$j_varname] != $fRes[$j_varname]) {
|
---|
294 | $ok = FALSE;
|
---|
295 | break;
|
---|
296 | }
|
---|
297 | if ($ok)
|
---|
298 | break;
|
---|
299 | }
|
---|
300 | if (!$ok)
|
---|
301 | unset($finalRes[$n]);
|
---|
302 | }
|
---|
303 |
|
---|
304 | // join $res and $finalRes
|
---|
305 | $joinedRes = array();
|
---|
306 | foreach ($res as $i => $r) {
|
---|
307 | foreach ($finalRes as $n => $fRes) {
|
---|
308 | $ok = TRUE;
|
---|
309 | foreach ($jointVars as $j_varname)
|
---|
310 | if ($r[$j_varname] != $fRes[$j_varname]) {
|
---|
311 | $ok = FALSE;
|
---|
312 | break;
|
---|
313 | }
|
---|
314 | if ($ok) {
|
---|
315 | $joinedRow = $finalRes[$n];
|
---|
316 | foreach($newVars as $n_varname)
|
---|
317 | $joinedRow[$n_varname] = $r[$n_varname];
|
---|
318 | $joinedRes[] = $joinedRow;
|
---|
319 | }
|
---|
320 | }
|
---|
321 | }
|
---|
322 |
|
---|
323 | return $joinedRes;
|
---|
324 | }
|
---|
325 |
|
---|
326 |
|
---|
327 | /**
|
---|
328 | * Filter the result-set of query variables by evaluating each filter from the
|
---|
329 | * AND clause of the RDQL query.
|
---|
330 | *
|
---|
331 | * @param array &$finalRes [][?VARNAME] = object Node
|
---|
332 | * @return array [][?VARNAME] = object Node
|
---|
333 | * @access private
|
---|
334 | */
|
---|
335 | function filterTuples(&$finalRes) {
|
---|
336 |
|
---|
337 | foreach ($this->parsedQuery['filters'] as $filter) {
|
---|
338 |
|
---|
339 | foreach ($finalRes as $n => $fRes) {
|
---|
340 | $evalFilterStr = $filter['evalFilterStr'];
|
---|
341 |
|
---|
342 | // evaluate regex equality expressions of each filter
|
---|
343 | foreach ($filter['regexEqExprs'] as $i => $expr) {
|
---|
344 |
|
---|
345 | preg_match($expr['regex'], $fRes[$expr['var']]->getLabel(), $match);
|
---|
346 | $op = substr($expr['operator'], 0,1);
|
---|
347 | if (($op != '!' && !isset($match[0])) || ($op == '!' && isset($match[0])))
|
---|
348 | $evalFilterStr = str_replace("##RegEx_$i##", 'FALSE', $evalFilterStr);
|
---|
349 | else
|
---|
350 | $evalFilterStr = str_replace("##RegEx_$i##", 'TRUE', $evalFilterStr);
|
---|
351 |
|
---|
352 | }
|
---|
353 |
|
---|
354 | // evaluate string equality expressions
|
---|
355 | foreach ($filter['strEqExprs'] as $i => $expr) {
|
---|
356 |
|
---|
357 | $exprBoolVal = 'FALSE';
|
---|
358 |
|
---|
359 | switch ($expr['value_type']) {
|
---|
360 |
|
---|
361 | case 'variable':
|
---|
362 | if (($fRes[$expr['var']] == $fRes[$expr['value']] && $expr['operator'] == 'eq') ||
|
---|
363 | ($fRes[$expr['var']] != $fRes[$expr['value']] && $expr['operator'] == 'ne'))
|
---|
364 | $exprBoolVal = 'TRUE';
|
---|
365 | break;
|
---|
366 |
|
---|
367 | case 'URI':
|
---|
368 |
|
---|
369 | if (is_a($fRes[$expr['var']], 'Literal')) {
|
---|
370 | if ($expr['operator'] == 'ne')
|
---|
371 | $exprBoolVal = 'TRUE';
|
---|
372 | break;
|
---|
373 | }
|
---|
374 |
|
---|
375 | if (($fRes[$expr['var']]->getLabel() == $expr['value'] && $expr['operator'] == 'eq') ||
|
---|
376 | ($fRes[$expr['var']]->getLabel() != $expr['value'] && $expr['operator'] == 'ne'))
|
---|
377 | $exprBoolVal = 'TRUE';
|
---|
378 | break;
|
---|
379 |
|
---|
380 | case 'Literal':
|
---|
381 |
|
---|
382 | if (!is_a($fRes[$expr['var']], 'Literal')) {
|
---|
383 | if ($expr['operator'] == 'ne')
|
---|
384 | $exprBoolVal = 'TRUE';
|
---|
385 | break;
|
---|
386 | }
|
---|
387 |
|
---|
388 | $filterLiteral= new Literal($expr['value'],$expr['value_lang']);
|
---|
389 | $filterLiteral->setDatatype($expr['value_dtype']);
|
---|
390 |
|
---|
391 | $equal=$fRes[$expr['var']]->equals($filterLiteral);
|
---|
392 | /* if ($fRes[$expr['var']]->getLabel() == $expr['value'] &&
|
---|
393 | $fRes[$expr['var']]->getDatatype() == $expr['value_dtype']) {
|
---|
394 |
|
---|
395 | $equal = TRUE;
|
---|
396 |
|
---|
397 | // Lang tags only differentiate literals in rdf:XMLLiterals and plain literals.
|
---|
398 | // Therefore if a literal is datatyped ignore the language tag.
|
---|
399 | if ((($expr['value_dtype'] == NULL) ||
|
---|
400 | ($expr['value_dtype'] == 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral') ||
|
---|
401 | ($expr['value_dtype'] == 'http://www.w3.org/2001/XMLSchema#string')) &&
|
---|
402 | (($fRes[$expr['var']]->getLanguage() != $expr['value_lang'])))
|
---|
403 |
|
---|
404 | $equal = FALSE;
|
---|
405 | }else
|
---|
406 | $equal = FALSE;
|
---|
407 | */
|
---|
408 | if (($equal && $expr['operator'] == 'eq') ||
|
---|
409 | (!$equal && $expr['operator'] == 'ne'))
|
---|
410 | $exprBoolVal = 'TRUE';
|
---|
411 | else
|
---|
412 | $exprBoolVal = 'FALSE';
|
---|
413 |
|
---|
414 | }
|
---|
415 | $evalFilterStr = str_replace("##strEqExpr_$i##", $exprBoolVal, $evalFilterStr);
|
---|
416 | }
|
---|
417 |
|
---|
418 | // evaluate numerical expressions
|
---|
419 | foreach ($filter['numExprVars'] as $varName) {
|
---|
420 | $varValue = "'" .$fRes[$varName]->getLabel() ."'";
|
---|
421 | $evalFilterStr = str_replace($varName, $varValue, $evalFilterStr);
|
---|
422 | }
|
---|
423 |
|
---|
424 | eval("\$filterBoolVal = $evalFilterStr; \$eval_filter_ok = TRUE;");
|
---|
425 | if (!isset($eval_filter_ok))
|
---|
426 | trigger_error(RDQL_AND_ERR ."'" .htmlspecialchars($filter['string']) ."'", E_USER_ERROR);
|
---|
427 |
|
---|
428 | if (!$filterBoolVal)
|
---|
429 | unset($finalRes[$n]);
|
---|
430 | }
|
---|
431 | }
|
---|
432 |
|
---|
433 | return $finalRes;
|
---|
434 | }
|
---|
435 |
|
---|
436 |
|
---|
437 | /**
|
---|
438 | * Remove all conditional variables from the result-set and leave only variables
|
---|
439 | * specified in the SELECT clause of the RDQL query.
|
---|
440 | *
|
---|
441 | * @param array &$finalRes [][?VARNAME] = object Node
|
---|
442 | * @return array [][?VARNAME] = object Node
|
---|
443 | * @access private
|
---|
444 | */
|
---|
445 | function selectVariables(&$finalRes) {
|
---|
446 |
|
---|
447 | // if nothing has been found return only one row of $finalRes
|
---|
448 | // with select variables having empty values
|
---|
449 | if (count($finalRes) == 0) {
|
---|
450 | foreach ($this->parsedQuery['selectVars'] as $selectVar)
|
---|
451 | $finalRes[0][$selectVar] = NULL;
|
---|
452 | return $finalRes;
|
---|
453 | }
|
---|
454 |
|
---|
455 | // return only selectVars in the same order as given in the RDQL query
|
---|
456 | // and reindex $finalRes.
|
---|
457 | $n = 0;
|
---|
458 | foreach($finalRes as $key => $val) {
|
---|
459 | foreach ($this->parsedQuery['selectVars'] as $selectVar)
|
---|
460 | $resultSet[$n][$selectVar] = $val[$selectVar];
|
---|
461 | unset($finalRes[$key]);
|
---|
462 | ++$n;
|
---|
463 | }
|
---|
464 |
|
---|
465 | return $resultSet;
|
---|
466 | }
|
---|
467 |
|
---|
468 |
|
---|
469 | /**
|
---|
470 | * Convert the variable values of $finalRes from objects to their string serialization.
|
---|
471 | *
|
---|
472 | * @param array &$finalRes [][?VARNAME] = object Node
|
---|
473 | * @return array [][?VARNAME] = string
|
---|
474 | * @access private
|
---|
475 | */
|
---|
476 | function toString(&$finalRes) {
|
---|
477 |
|
---|
478 | foreach ($finalRes as $n => $tuple)
|
---|
479 | foreach ($tuple as $varname => $node) {
|
---|
480 | if (is_a($node, 'Resource'))
|
---|
481 | $res[$n][$varname] = '<' .$node->getLabel() .'>';
|
---|
482 | elseif (is_a($node, 'Literal')) {
|
---|
483 | $res[$n][$varname] = '"' .$node->getLabel() .'"';
|
---|
484 | if ($node->getLanguage())
|
---|
485 | $res[$n][$varname] .= ' (xml:lang="' .$node->getLanguage() .'")';
|
---|
486 | if ($node->getDatatype())
|
---|
487 | $res[$n][$varname] .= ' (rdf:datatype="' .$node->getDatatype() .'")';
|
---|
488 | }else
|
---|
489 | $res[$n][$varname] = $node;
|
---|
490 | }
|
---|
491 | return $res;
|
---|
492 | }
|
---|
493 |
|
---|
494 |
|
---|
495 | /**
|
---|
496 | * Check if the given triple meets pattern internal bindings
|
---|
497 | * e.g. (?x, ?z, ?x) ==> statement subject must be identical with the statement object
|
---|
498 | *
|
---|
499 | * @param object statement &$triple
|
---|
500 | * @param array &$intBindings [] = string
|
---|
501 | * @return boolean
|
---|
502 | * @access private
|
---|
503 | */
|
---|
504 | function _checkIntBindings (&$triple, &$intBindings) {
|
---|
505 |
|
---|
506 | if (in_array('subject', $intBindings)) {
|
---|
507 | if (in_array('predicate', $intBindings))
|
---|
508 | if ($triple->subj != $triple->pred)
|
---|
509 | return FALSE;
|
---|
510 | if (in_array('object', $intBindings)) {
|
---|
511 | if (is_a($triple->obj, 'Literal'))
|
---|
512 | return FALSE;
|
---|
513 | elseif ($triple->subj != $triple->obj)
|
---|
514 | return FALSE;
|
---|
515 | }
|
---|
516 | return TRUE;
|
---|
517 | }
|
---|
518 | if (in_array('predicate', $intBindings)) {
|
---|
519 | if (is_a($triple->obj, 'Literal'))
|
---|
520 | return FALSE;
|
---|
521 | elseif ($triple->pred != $triple->obj)
|
---|
522 | return FALSE;
|
---|
523 | return TRUE;
|
---|
524 | }
|
---|
525 | }
|
---|
526 |
|
---|
527 |
|
---|
528 | /**
|
---|
529 | * Check if the lang and dtype of the passed object Literal are equal $lang and $dtype
|
---|
530 | * !!! Language only differentiates literals in rdf:XMLLiterals and plain literals (xsd:string).
|
---|
531 | * !!! Therefore if a literal is datatyped ignore the language.
|
---|
532 | *
|
---|
533 | * @param object Literal $literal
|
---|
534 | * @param string $dtype1
|
---|
535 | * @param string $dtype2
|
---|
536 | * @return boolean
|
---|
537 | * @access private
|
---|
538 | */
|
---|
539 | function _equalsLangDtype ($literal, $lang, $dtype) {
|
---|
540 |
|
---|
541 | if ($dtype == $literal->getDatatype()) {
|
---|
542 | if (($dtype == NULL ||
|
---|
543 | $dtype == 'http://www.w3.org/2001/XMLSchema#string' ||
|
---|
544 | $dtype == 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral') &&
|
---|
545 | ($lang != $literal->getLanguage()))
|
---|
546 | return FALSE;
|
---|
547 | return TRUE;
|
---|
548 | }
|
---|
549 | return FALSE;
|
---|
550 | }
|
---|
551 |
|
---|
552 |
|
---|
553 | } // end: Class RdqlMemEngine
|
---|
554 |
|
---|
555 | ?> |
---|