00001 <?php
00002
00020 abstract class SMWSparqlCondition {
00021
00029 public $orderByVariable = '';
00030
00037 public $orderVariables = array();
00038
00049 public $weakConditions = array();
00050
00056 public $namespaces = array();
00057
00065 abstract public function getCondition();
00066
00075 abstract public function isSafe();
00076
00077 public function getWeakConditionString() {
00078 return implode( '', $this->weakConditions );
00079 }
00080
00081 }
00082
00089 class SMWSparqlFalseCondition extends SMWSparqlCondition {
00090
00091 public function getCondition() {
00092 return "<http://www.example.org> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#nothing> .\n";
00093 }
00094
00095 public function isSafe() {
00096 return true;
00097 }
00098 }
00099
00107 class SMWSparqlTrueCondition extends SMWSparqlCondition {
00108
00109 public function getCondition() {
00110 return '';
00111 }
00112
00113 public function isSafe() {
00114 return false;
00115 }
00116 }
00117
00124 class SMWSparqlWhereCondition extends SMWSparqlCondition {
00125
00131 public $condition;
00132
00138 public $isSafe;
00139
00140 public function __construct( $condition, $isSafe, $namespaces ) {
00141 $this->condition = $condition;
00142 $this->isSafe = $isSafe;
00143 $this->namespaces = $namespaces;
00144 }
00145
00146 public function getCondition() {
00147 return $this->condition;
00148 }
00149
00150 public function isSafe() {
00151 return $this->isSafe;
00152 }
00153 }
00154
00160 class SMWSparqlSingletonCondition extends SMWSparqlCondition {
00161
00168 public $condition;
00169
00174 public $matchElement;
00175
00181 public $isSafe;
00182
00183 public function __construct( SMWExpElement $matchElement, $condition = '', $isSafe = false, $namespaces = array() ) {
00184 $this->matchElement = $matchElement;
00185 $this->condition = $condition;
00186 $this->isSafe = $isSafe;
00187 $this->namespaces = $namespaces;
00188 }
00189
00190 public function getCondition() {
00191 return $this->condition;
00192 }
00193
00194 public function isSafe() {
00195 return $this->isSafe;
00196 }
00197
00198 }
00199
00206 class SMWSparqlFilterCondition extends SMWSparqlCondition {
00207
00213 public $filter;
00214
00215 public function __construct( $filter, $namespaces ) {
00216 $this->filter = $filter;
00217 $this->namespaces = $namespaces;
00218 }
00219
00220 public function getCondition() {
00221 return "FILTER( {$this->filter} )\n";
00222 }
00223
00224 public function isSafe() {
00225 return false;
00226 }
00227
00228 }
00229
00230
00237 class SMWSparqlStoreQueryEngine {
00238
00240 const RESULT_VARIABLE = 'result';
00241
00246 protected $m_variableCounter = 0;
00247
00253 protected $m_sortkeys;
00254
00259 protected $m_store;
00260
00266 public function __construct( SMWStore $store ) {
00267 $this->m_store = $store;
00268 }
00269
00276 public function getCountQueryResult( SMWQuery $query ) {
00277 $this->m_sortkeys = array();
00278 $sparqlCondition = $this->getSparqlCondition( $query->getDescription() );
00279
00280 if ( $sparqlCondition instanceof SMWSparqlSingletonCondition ) {
00281 if ( $sparqlCondition->condition === '' ) {
00282 return 1;
00283 } else {
00284 $condition = $this->getSparqlConditionString( $sparqlCondition );
00285 $namespaces = $sparqlCondition->namespaces;
00286 $askQueryResult = smwfGetSparqlDatabase()->ask( $condition, $namespaces );
00287 return $askQueryResult->isBooleanTrue() ? 1 : 0;
00288 }
00289 } elseif ( $sparqlCondition instanceof SMWSparqlFalseCondition ) {
00290 return 0;
00291 } else {
00292
00293 $condition = $this->getSparqlConditionString( $sparqlCondition );
00294 $namespaces = $sparqlCondition->namespaces;
00295 $options = $this->getSparqlOptions( $query, $sparqlCondition );
00296 $options['DISTINCT'] = true;
00297 $sparqlResultWrapper = smwfGetSparqlDatabase()->selectCount( '?' . self::RESULT_VARIABLE,
00298 $condition, $options, $namespaces );
00299
00300 if ( $sparqlResultWrapper->getErrorCode() == SMWSparqlResultWrapper::ERROR_NOERROR ) {
00301 return (int)$sparqlResultWrapper->getNumericValue();
00302 } else {
00304
00305 }
00306 }
00307 }
00308
00315 public function getInstanceQueryResult( SMWQuery $query ) {
00316 $this->m_sortkeys = $query->sortkeys;
00317 $sparqlCondition = $this->getSparqlCondition( $query->getDescription() );
00318
00319
00320 if ( $sparqlCondition instanceof SMWSparqlSingletonCondition ) {
00321 $matchElement = $sparqlCondition->matchElement;
00322 if ( $sparqlCondition->condition === '' ) {
00323 $results = array( array ( $matchElement ) );
00324 } else {
00325 $condition = $this->getSparqlConditionString( $sparqlCondition );
00326 $namespaces = $sparqlCondition->namespaces;
00327 $askQueryResult = smwfGetSparqlDatabase()->ask( $condition, $namespaces );
00328 $results = $askQueryResult->isBooleanTrue() ? array( array ( $matchElement ) ) : array();
00329 }
00330 $sparqlResultWrapper = new SMWSparqlResultWrapper( array( self::RESULT_VARIABLE => 0 ), $results );
00331 } elseif ( $sparqlCondition instanceof SMWSparqlFalseCondition ) {
00332 $sparqlResultWrapper = new SMWSparqlResultWrapper( array( self::RESULT_VARIABLE => 0 ), array() );
00333 } else {
00334
00335 $condition = $this->getSparqlConditionString( $sparqlCondition );
00336 $namespaces = $sparqlCondition->namespaces;
00337 $options = $this->getSparqlOptions( $query, $sparqlCondition );
00338 $options['DISTINCT'] = true;
00339 $sparqlResultWrapper = smwfGetSparqlDatabase()->select( '?' . self::RESULT_VARIABLE,
00340 $condition, $options, $namespaces );
00341 }
00342
00343
00344 return $this->getQueryResultFromSparqlResult( $sparqlResultWrapper, $query );
00345 }
00346
00353 public function getDebugQueryResult( SMWQuery $query ) {
00354 $this->m_sortkeys = $query->sortkeys;
00355 $sparqlCondition = $this->getSparqlCondition( $query->getDescription() );
00356
00357 $entries = array();
00358
00359 if ( $sparqlCondition instanceof SMWSparqlSingletonCondition ) {
00360 if ( $sparqlCondition->condition === '' ) {
00361 $sparql = 'None (no conditions).';
00362 } else {
00363 $condition = $this->getSparqlConditionString( $sparqlCondition );
00364 $namespaces = $sparqlCondition->namespaces;
00365 $sparql = smwfGetSparqlDatabase()->getSparqlForAsk( $condition, $namespaces );
00366 }
00367 } elseif ( $sparqlCondition instanceof SMWSparqlFalseCondition ) {
00368 $sparql = 'None (conditions can not be satisfied by anything).';
00369 } else {
00370 $condition = $this->getSparqlConditionString( $sparqlCondition );
00371 $namespaces = $sparqlCondition->namespaces;
00372 $options = $this->getSparqlOptions( $query, $sparqlCondition );
00373 $options['DISTINCT'] = true;
00374 $sparql = smwfGetSparqlDatabase()->getSparqlForSelect( '?' . self::RESULT_VARIABLE,
00375 $condition, $options, $namespaces );
00376 }
00377 $sparql = str_replace( array( '[',':',' ' ), array( '[', ':', ' ' ), $sparql );
00378 $entries['SPARQL Query'] = "<pre>$sparql</pre>";
00379
00380 return SMWStore::formatDebugOutput( 'SMWSparqlStore', $entries, $query );
00381 }
00382
00392 protected function getSparqlConditionString( SMWSparqlCondition &$sparqlCondition ) {
00393 $condition = $sparqlCondition->getWeakConditionString();
00394 if ( ( $condition === '' ) && !$sparqlCondition->isSafe() ) {
00395 $swivtPageResource = SMWExporter::getSpecialNsResource( 'swivt', 'page' );
00396 $condition = '?' . self::RESULT_VARIABLE . ' ' . $swivtPageResource->getQName() . " ?url .\n";
00397 }
00398 $condition .= $sparqlCondition->getCondition();
00399
00400 if ( $sparqlCondition instanceof SMWSparqlSingletonCondition ) {
00401 $matchElement = $sparqlCondition->matchElement;
00402 $matchElementName = SMWTurtleSerializer::getTurtleNameForExpElement( $matchElement );
00403 if ( $matchElement instanceof SMWExpNsResource ) {
00404 $sparqlCondition->namespaces[$matchElement->getNamespaceId()] = $matchElement->getNamespace();
00405 }
00406 $condition = str_replace( '?' . self::RESULT_VARIABLE . ' ', "$matchElementName ", $condition );
00407 }
00408
00409 return $condition;
00410 }
00411
00422 protected function getQueryResultFromSparqlResult( SMWSparqlResultWrapper $sparqlResultWrapper, SMWQuery $query ) {
00423 $resultDataItems = array();
00424
00425 foreach ( $sparqlResultWrapper as $resultRow ) {
00426 if ( count( $resultRow ) > 0 ) {
00427 $dataItem = SMWExporter::findDataItemForExpElement( $resultRow[0] );
00428
00429 if ( !is_null( $dataItem ) ) {
00430 $resultDataItems[] = $dataItem;
00431 }
00432 }
00433 }
00434
00435 if ( $sparqlResultWrapper->numRows() > $query->getLimit() ) {
00436 array_pop( $resultDataItems );
00437 $hasFurtherResults = true;
00438 } else {
00439 $hasFurtherResults = false;
00440 }
00441
00442 $result = new SMWQueryResult( $query->getDescription()->getPrintrequests(), $query, $resultDataItems, $this->m_store, $hasFurtherResults );
00443
00444 switch ( $sparqlResultWrapper->getErrorCode() ) {
00445 case SMWSparqlResultWrapper::ERROR_NOERROR: break;
00446 case SMWSparqlResultWrapper::ERROR_INCOMPLETE:
00447 $result->addErrors( array( wfMsgForContent( 'smw_db_sparqlqueryincomplete' ) ) );
00448 break;
00449 default:
00450 $result->addErrors( array( wfMsgForContent( 'smw_db_sparqlqueryproblem' ) ) );
00451 break;
00452 }
00453
00454 return $result;
00455 }
00456
00470 protected function getSparqlCondition( SMWDescription $description ) {
00471 $this->m_variableCounter = 0;
00472 $sparqlCondition = $this->buildSparqlCondition( $description, self::RESULT_VARIABLE, null );
00473 $this->addMissingOrderByConditions( $sparqlCondition );
00474 return $sparqlCondition;
00475 }
00476
00488 protected function buildSparqlCondition( SMWDescription $description, $joinVariable, $orderByProperty ) {
00489 if ( $description instanceof SMWSomeProperty ) {
00490 return $this->buildPropertyCondition( $description, $joinVariable, $orderByProperty );
00491 } elseif ( $description instanceof SMWNamespaceDescription ) {
00492 return $this->buildNamespaceCondition( $description, $joinVariable, $orderByProperty );
00493 } elseif ( $description instanceof SMWConjunction ) {
00494 return $this->buildConjunctionCondition( $description, $joinVariable, $orderByProperty );
00495 } elseif ( $description instanceof SMWDisjunction ) {
00496 return $this->buildDisjunctionCondition( $description, $joinVariable, $orderByProperty );
00497 } elseif ( $description instanceof SMWClassDescription ) {
00498 return $this->buildClassCondition( $description, $joinVariable, $orderByProperty );
00499 } elseif ( $description instanceof SMWValueDescription ) {
00500 return $this->buildValueCondition( $description, $joinVariable, $orderByProperty );
00501 } elseif ( $description instanceof SMWConceptDescription ) {
00502 return new SMWSparqlTrueCondition();
00503 } else {
00504 return $this->buildTrueCondition( $joinVariable, $orderByProperty );
00505 }
00506 }
00507
00516 protected function buildConjunctionCondition( SMWConjunction $description, $joinVariable, $orderByProperty ) {
00517 $subDescriptions = $description->getDescriptions();
00518 if ( count( $subDescriptions ) == 0 ) {
00519 return $this->buildTrueCondition( $joinVariable, $orderByProperty );
00520 } elseif ( count( $subDescriptions ) == 1 ) {
00521 return $this->buildSparqlCondition( reset( $subDescriptions ), $joinVariable, $orderByProperty );
00522 }
00523
00524 $condition = '';
00525 $filter = '';
00526 $namespaces = $weakConditions = $orderVariables = array();
00527 $singletonMatchElement = null;
00528 $singletonMatchElementName = '';
00529 $hasSafeSubconditions = false;
00530 foreach ( $subDescriptions as $subDescription ) {
00531 $subCondition = $this->buildSparqlCondition( $subDescription, $joinVariable, null );
00532 if ( $subCondition instanceof SMWSparqlFalseCondition ) {
00533 return new SMWSparqlFalseCondition();
00534 } elseif ( $subCondition instanceof SMWSparqlTrueCondition ) {
00535
00536 } elseif ( $subCondition instanceof SMWSparqlWhereCondition ) {
00537 $condition .= $subCondition->condition;
00538 } elseif ( $subCondition instanceof SMWSparqlFilterCondition ) {
00539 $filter .= ( $filter ? ' && ' : '' ) . $subCondition->filter;
00540 } elseif ( $subCondition instanceof SMWSparqlSingletonCondition ) {
00541 $matchElement = $subCondition->matchElement;
00542 $matchElementName = SMWTurtleSerializer::getTurtleNameForExpElement( $matchElement );
00543 if ( $matchElement instanceof SMWExpNsResource ) {
00544 $namespaces[$matchElement->getNamespaceId()] = $matchElement->getNamespace();
00545 }
00546
00547 if ( ( !is_null( $singletonMatchElement ) ) &&
00548 ( $singletonMatchElementName !== $matchElementName ) ) {
00549 return new SMWSparqlFalseCondition();
00550 }
00551
00552 $condition .= $subCondition->condition;
00553 $singletonMatchElement = $subCondition->matchElement;
00554 $singletonMatchElementName = $matchElementName;
00555 }
00556 $hasSafeSubconditions = $hasSafeSubconditions || $subCondition->isSafe();
00557 $namespaces = array_merge( $namespaces, $subCondition->namespaces );
00558 $weakConditions = array_merge( $weakConditions, $subCondition->weakConditions );
00559 $orderVariables = array_merge( $orderVariables, $subCondition->orderVariables );
00560 }
00561
00562 if ( !is_null( $singletonMatchElement ) ) {
00563 if ( $filter !== '' ) {
00564 $condition .= "FILTER( $filter )";
00565 }
00566 $result = new SMWSparqlSingletonCondition( $singletonMatchElement, $condition,
00567 $hasSafeSubconditions, $namespaces );
00568 } elseif ( $condition === '' ) {
00569 $result = new SMWSparqlFilterCondition( $filter, $namespaces );
00570 } else {
00571 if ( $filter !== '' ) {
00572 $condition .= "FILTER( $filter )";
00573 }
00574 $result = new SMWSparqlWhereCondition( $condition, $hasSafeSubconditions, $namespaces );
00575 }
00576
00577 $result->weakConditions = $weakConditions;
00578 $result->orderVariables = $orderVariables;
00579
00580 $this->addOrderByDataForProperty( $result, $joinVariable, $orderByProperty );
00581
00582 return $result;
00583 }
00584
00593 protected function buildDisjunctionCondition( SMWDisjunction $description, $joinVariable, $orderByProperty ) {
00594 $subDescriptions = $description->getDescriptions();
00595 if ( count( $subDescriptions ) == 0 ) {
00596 return new SMWSparqlFalseCondition();
00597 } elseif ( count( $subDescriptions ) == 1 ) {
00598 return $this->buildSparqlCondition( reset( $subDescriptions ), $joinVariable, $orderByProperty );
00599 }
00600
00601 $unionCondition = '';
00602 $filter = '';
00603 $namespaces = $weakConditions = array();
00604 $hasSafeSubconditions = false;
00605 foreach ( $subDescriptions as $subDescription ) {
00606 $subCondition = $this->buildSparqlCondition( $subDescription, $joinVariable, null );
00607 if ( $subCondition instanceof SMWSparqlFalseCondition ) {
00608
00609 } elseif ( $subCondition instanceof SMWSparqlTrueCondition ) {
00610 return $this->buildTrueCondition( $joinVariable, $orderByProperty );
00611 } elseif ( $subCondition instanceof SMWSparqlWhereCondition ) {
00612 $hasSafeSubconditions = $hasSafeSubconditions || $subCondition->isSafe();
00613 $unionCondition .= ( $unionCondition ? ' UNION ' : '' ) .
00614 "{\n" . $subCondition->condition . "}";
00615 } elseif ( $subCondition instanceof SMWSparqlFilterCondition ) {
00616 $filter .= ( $filter ? ' || ' : '' ) . $subCondition->filter;
00617 } elseif ( $subCondition instanceof SMWSparqlSingletonCondition ) {
00618 $hasSafeSubconditions = $hasSafeSubconditions || $subCondition->isSafe();
00619 $matchElement = $subCondition->matchElement;
00620 $matchElementName = SMWTurtleSerializer::getTurtleNameForExpElement( $matchElement );
00621 if ( $matchElement instanceof SMWExpNsResource ) {
00622 $namespaces[$matchElement->getNamespaceId()] = $matchElement->getNamespace();
00623 }
00624 if ( $subCondition->condition === '' ) {
00625 $filter .= ( $filter ? ' || ' : '' ) . "?$joinVariable = $matchElementName";
00626 } else {
00627 $unionCondition .= ( $unionCondition ? ' UNION ' : '' ) .
00628 "{\n" . $subCondition->condition . " FILTER( ?$joinVariable = $matchElementName ) }";
00629 }
00630 }
00631 $namespaces = array_merge( $namespaces, $subCondition->namespaces );
00632 $weakConditions = array_merge( $weakConditions, $subCondition->weakConditions );
00633 }
00634
00635 if ( ( $unionCondition === '' ) && ( $filter === '' ) ) {
00636 return new SMWSparqlFalseCondition();
00637 } elseif ( $unionCondition === '' ) {
00638 $result = new SMWSparqlFilterCondition( $filter, $namespaces );
00639 } elseif ( $filter === '' ) {
00640 $result = new SMWSparqlWhereCondition( $unionCondition, $hasSafeSubconditions, $namespaces );
00641 } else {
00642 $subJoinVariable = $this->getNextVariable();
00643 $unionCondition = str_replace( "?$joinVariable ", "?$subJoinVariable ", $unionCondition );
00644 $filter .= " || ?$joinVariable = ?$subJoinVariable";
00645 $result = new SMWSparqlWhereCondition( "OPTIONAL { $unionCondition }\n FILTER( $filter )\n", false, $namespaces );
00646 }
00647
00648 $result->weakConditions = $weakConditions;
00649
00650 $this->addOrderByDataForProperty( $result, $joinVariable, $orderByProperty );
00651
00652 return $result;
00653
00654 }
00655
00664 protected function buildPropertyCondition( SMWSomeProperty $description, $joinVariable, $orderByProperty ) {
00665 $diProperty = $description->getProperty();
00666
00667
00668 if ( array_key_exists( $diProperty->getKey(), $this->m_sortkeys ) ) {
00669 $innerOrderByProperty = $diProperty;
00670 } else {
00671 $innerOrderByProperty = null;
00672 }
00673
00674
00675 $innerJoinVariable = $this->getNextVariable();
00676 $innerCondition = $this->buildSparqlCondition( $description->getDescription(), $innerJoinVariable, $innerOrderByProperty );
00677 $namespaces = $innerCondition->namespaces;
00678
00679 if ( $innerCondition instanceof SMWSparqlFalseCondition ) {
00680 return new SMWSparqlFalseCondition();
00681 } elseif ( $innerCondition instanceof SMWSparqlSingletonCondition ) {
00682 $matchElement = $innerCondition->matchElement;
00683 $objectName = SMWTurtleSerializer::getTurtleNameForExpElement( $matchElement );
00684 if ( $matchElement instanceof SMWExpNsResource ) {
00685 $namespaces[$matchElement->getNamespaceId()] = $matchElement->getNamespace();
00686 }
00687 } else {
00688 $objectName = '?' . $innerJoinVariable;
00689 }
00690
00691
00692 if ( $diProperty->isInverse() ) {
00693 $subjectName = $objectName;
00694 $objectName = '?' . $joinVariable;
00695 $diNonInverseProperty = new SMWDIProperty( $diProperty->getKey(), false );
00696 } else {
00697 $subjectName = '?' . $joinVariable;
00698 $diNonInverseProperty = $diProperty;
00699 }
00700
00701
00702 $typeId = $diProperty->findPropertyTypeID();
00703 $diType = SMWDataValueFactory::getDataItemId( $typeId );
00704
00705 if ( SMWExporter::hasHelperExpElement( $diType ) ) {
00706 $propertyExpElement = SMWExporter::getResourceElementForProperty( $diNonInverseProperty, true );
00707 } else {
00708 $propertyExpElement = SMWExporter::getResourceElementForProperty( $diNonInverseProperty );
00709 }
00710 $propertyName = SMWTurtleSerializer::getTurtleNameForExpElement( $propertyExpElement );
00711 if ( $propertyExpElement instanceof SMWExpNsResource ) {
00712 $namespaces[$propertyExpElement->getNamespaceId()] = $propertyExpElement->getNamespace();
00713 }
00714 $condition = "$subjectName $propertyName $objectName .\n";
00715 $innerConditionString = $innerCondition->getCondition() . $innerCondition->getWeakConditionString();
00716 if ( $innerConditionString !== '' ) {
00717 if ( $innerCondition instanceof SMWSparqlFilterCondition ) {
00718 $condition .= $innerConditionString;
00719 } else {
00720 $condition .= "{ $innerConditionString}\n";
00721 }
00722 }
00723 $result = new SMWSparqlWhereCondition( $condition, true, $namespaces );
00724
00725
00726 $result->orderVariables = $innerCondition->orderVariables;
00727 if ( !is_null( $innerOrderByProperty ) && ( $innerCondition->orderByVariable !== '' ) ) {
00728 $result->orderVariables[$diProperty->getKey()] = $innerCondition->orderByVariable;
00729 }
00730
00731 $this->addOrderByDataForProperty( $result, $joinVariable, $orderByProperty, SMWDataItem::TYPE_WIKIPAGE );
00732
00733 return $result;
00734 }
00735
00744 protected function buildClassCondition( SMWClassDescription $description, $joinVariable, $orderByProperty ) {
00745 $condition = '';
00746 $namespaces = array();
00747 $instExpElement = SMWExporter::getSpecialPropertyResource( '_INST' );
00748 foreach( $description->getCategories() as $diWikiPage ) {
00749 $categoryExpElement = SMWExporter::getResourceElementForWikiPage( $diWikiPage );
00750 $categoryName = SMWTurtleSerializer::getTurtleNameForExpElement( $categoryExpElement );
00751 $namespaces[$categoryExpElement->getNamespaceId()] = $categoryExpElement->getNamespace();
00752 $newcondition = "{ ?$joinVariable " . $instExpElement->getQName() . " $categoryName . }\n";
00753 if ( $condition === '' ) {
00754 $condition = $newcondition;
00755 } else {
00756 $condition .= "UNION\n$newcondition";
00757 }
00758 }
00759
00760 if ( $condition === '' ) {
00761 return new SMWSparqlFalseCondition();
00762 }
00763
00764 $result = new SMWSparqlWhereCondition( $condition, true, $namespaces );
00765
00766 $this->addOrderByDataForProperty( $result, $joinVariable, $orderByProperty, SMWDataItem::TYPE_WIKIPAGE );
00767
00768 return $result;
00769 }
00770
00779 protected function buildNamespaceCondition( SMWNamespaceDescription $description, $joinVariable, $orderByProperty ) {
00780 $nspropExpElement = SMWExporter::getSpecialNsResource( 'swivt', 'wikiNamespace' );
00781 $nsExpElement = new SMWExpLiteral( $description->getNamespace(), 'http://www.w3.org/2001/XMLSchema#integer' );
00782 $nsName = SMWTurtleSerializer::getTurtleNameForExpElement( $nsExpElement );
00783 $condition = "{ ?$joinVariable " . $nspropExpElement->getQName() . " $nsName . }\n";
00784
00785 $result = new SMWSparqlWhereCondition( $condition, true, array() );
00786
00787 $this->addOrderByDataForProperty( $result, $joinVariable, $orderByProperty, SMWDataItem::TYPE_WIKIPAGE );
00788
00789 return $result;
00790 }
00791
00800 protected function buildValueCondition( SMWValueDescription $description, $joinVariable, $orderByProperty ) {
00801 $dataItem = $description->getDataItem();
00802
00803 switch ( $description->getComparator() ) {
00804 case SMW_CMP_EQ: $comparator = '='; break;
00805 case SMW_CMP_LESS: $comparator = '<'; break;
00806 case SMW_CMP_GRTR: $comparator = '>'; break;
00807 case SMW_CMP_LEQ: $comparator = '<='; break;
00808 case SMW_CMP_GEQ: $comparator = '>='; break;
00809 case SMW_CMP_NEQ: $comparator = '!='; break;
00810 case SMW_CMP_LIKE: $comparator = 'regex'; break;
00811 case SMW_CMP_NLKE: $comparator = '!regex'; break;
00812 default: $comparator = '';
00813 }
00814
00815 if ( $comparator === '' ) {
00816 $result = $this->buildTrueCondition( $joinVariable, $orderByProperty );
00817 } elseif ( $comparator == '=' ) {
00818 $expElement = SMWExporter::getDataItemHelperExpElement( $dataItem );
00819 if ( is_null( $expElement ) ) {
00820 $expElement = SMWExporter::getDataItemExpElement( $dataItem );
00821 }
00822 $result = new SMWSparqlSingletonCondition( $expElement );
00823 $this->addOrderByDataForProperty( $result, $joinVariable, $orderByProperty, $dataItem->getDIType() );
00824 } elseif ( $comparator == 'regex' || $comparator == '!regex' ) {
00825 if ( $dataItem instanceof SMWDIBlob ) {
00826 $pattern = '^' . str_replace( array( '^', '.', '\\', '+', '{', '}', '(', ')', '|', '^', '$', '[', ']', '*', '?' ),
00827 array( '\^', '\.', '\\\\', '\+', '\{', '\}', '\(', '\)', '\|', '\^', '\$', '\[', '\]', '.*', '.' ),
00828 $dataItem->getString() ) . '$';
00829 $result = new SMWSparqlFilterCondition( "$comparator( ?$joinVariable, \"$pattern\", \"s\")", array() );
00830 $this->addOrderByDataForProperty( $result, $joinVariable, $orderByProperty, $dataItem->getDIType() );
00831 } else {
00832 $result = $this->buildTrueCondition( $joinVariable, $orderByProperty );
00833 }
00834 } else {
00835 $result = new SMWSparqlFilterCondition( '', array() );
00836 $this->addOrderByData( $result, $joinVariable, $dataItem->getDIType() );
00837 $orderByVariable = $result->orderByVariable;
00838
00839 if ( $dataItem instanceof SMWDIWikiPage ) {
00840 $expElement = SMWExporter::getDataItemExpElement( $dataItem->getSortKeyDataItem() );
00841 } else {
00842 $expElement = SMWExporter::getDataItemHelperExpElement( $dataItem );
00843 if ( is_null( $expElement ) ) {
00844 $expElement = SMWExporter::getDataItemExpElement( $dataItem );
00845 }
00846 }
00847
00848 $valueName = SMWTurtleSerializer::getTurtleNameForExpElement( $expElement );
00849 if ( $expElement instanceof SMWExpNsResource ) {
00850 $result->namespaces[$expElement->getNamespaceId()] = $expElement->getNamespace();
00851 }
00852 $result->filter = "?$orderByVariable $comparator $valueName";
00853 }
00854
00855 return $result;
00856 }
00857
00866 protected function buildTrueCondition( $joinVariable, $orderByProperty ) {
00867 $result = new SMWSparqlTrueCondition();
00868 $this->addOrderByDataForProperty( $result, $joinVariable, $orderByProperty );
00869 return $result;
00870 }
00871
00877 protected function getNextVariable() {
00878 return 'v' . ( ++$this->m_variableCounter );
00879 }
00880
00890 protected function addOrderByDataForProperty( SMWSparqlCondition &$sparqlCondition, $mainVariable, $orderByProperty, $diType = SMWDataItem::TYPE_NOTYPE ) {
00891 if ( is_null( $orderByProperty ) ) {
00892 return;
00893 }
00894
00895 if ( $diType == SMWDataItem::TYPE_NOTYPE ) {
00896 $typeId = $orderByProperty->findPropertyTypeID();
00897 $diType = SMWDataValueFactory::getDataItemId( $typeId );
00898 }
00899
00900 $this->addOrderByData( $sparqlCondition, $mainVariable, $diType );
00901 }
00902
00911 protected function addOrderByData( SMWSparqlCondition &$sparqlCondition, $mainVariable, $diType ) {
00912 if ( $diType == SMWDataItem::TYPE_WIKIPAGE ) {
00913 $sparqlCondition->orderByVariable = $mainVariable . 'sk';
00914 $skeyExpElement = SMWExporter::getSpecialPropertyResource( '_SKEY' );
00915 $sparqlCondition->weakConditions = array( $sparqlCondition->orderByVariable =>
00916 "?$mainVariable " . $skeyExpElement->getQName() . " ?{$sparqlCondition->orderByVariable} .\n" );
00917 } else {
00918 $sparqlCondition->orderByVariable = $mainVariable;
00919 }
00920 }
00921
00930 protected function addMissingOrderByConditions( SMWSparqlCondition &$sparqlCondition ) {
00931 foreach ( $this->m_sortkeys as $propkey => $order ) {
00932 if ( !array_key_exists( $propkey, $sparqlCondition->orderVariables ) ) {
00933 if ( $propkey === '' ) {
00934 $this->addOrderByData( $sparqlCondition, self::RESULT_VARIABLE, SMWDataItem::TYPE_WIKIPAGE );
00935 $sparqlCondition->orderVariables[$propkey] = $sparqlCondition->orderByVariable;
00936 } else {
00937 $diProperty = new SMWDIProperty( $propkey );
00938 $auxDescription = new SMWSomeProperty( $diProperty, new SMWThingDescription() );
00939 $auxSparqlCondition = $this->buildSparqlCondition( $auxDescription, self::RESULT_VARIABLE, null );
00940
00941 $sparqlCondition->orderVariables[$propkey] = $auxSparqlCondition->orderVariables[$propkey];
00942 $sparqlCondition->weakConditions[$sparqlCondition->orderVariables[$propkey]] = $auxSparqlCondition->getWeakConditionString() . $auxSparqlCondition->getCondition();
00943 }
00944 }
00945 }
00946 }
00947
00955 protected function getSparqlOptions( SMWQuery $query, SMWSparqlCondition $sparqlCondition ) {
00956 global $smwgQSortingSupport, $smwgQRandSortingSupport;
00957
00958 $result = array( 'LIMIT' => $query->getLimit() + 1, 'OFFSET' => $query->getOffset() );
00959
00960
00961 if ( $smwgQSortingSupport ) {
00962 $orderByString = '';
00963 foreach ( $this->m_sortkeys as $propkey => $order ) {
00964 if ( ( $order != 'RANDOM' ) && array_key_exists( $propkey, $sparqlCondition->orderVariables ) ) {
00965 $orderByString .= "$order(?" . $sparqlCondition->orderVariables[$propkey] . ") ";
00966 } elseif ( ( $order == 'RANDOM' ) && $smwgQRandSortingSupport ) {
00967
00968 }
00969 }
00970 if ( $orderByString !== '' ) {
00971 $result['ORDER BY'] = $orderByString;
00972 }
00973 }
00974 return $result;
00975 }
00976
00977 }