summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/DescriptionInterpreters/ValueDescriptionInterpreter.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/DescriptionInterpreters/ValueDescriptionInterpreter.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/DescriptionInterpreters/ValueDescriptionInterpreter.php169
1 files changed, 169 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/DescriptionInterpreters/ValueDescriptionInterpreter.php b/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/DescriptionInterpreters/ValueDescriptionInterpreter.php
new file mode 100644
index 00000000..0ea4ec12
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/DescriptionInterpreters/ValueDescriptionInterpreter.php
@@ -0,0 +1,169 @@
+<?php
+
+namespace SMW\SQLStore\QueryEngine\DescriptionInterpreters;
+
+use SMW\DIWikiPage;
+use SMW\Query\Language\Description;
+use SMW\Query\Language\ValueDescription;
+use SMW\SQLStore\QueryEngine\DescriptionInterpreter;
+use SMW\SQLStore\QueryEngine\FulltextSearchTableFactory;
+use SMW\SQLStore\QueryEngine\QuerySegment;
+use SMW\SQLStore\QueryEngine\QuerySegmentListBuilder;
+use SMWDIBlob as DIBlob;
+use SMWSql3SmwIds;
+
+/**
+ * @license GNU GPL v2+
+ * @since 2.2
+ *
+ * @author Markus Krötzsch
+ * @author Jeroen De Dauw
+ * @author mwjames
+ */
+class ValueDescriptionInterpreter implements DescriptionInterpreter {
+
+ /**
+ * @var QuerySegmentListBuilder
+ */
+ private $querySegmentListBuilder;
+
+ /**
+ * @var ComparatorMapper
+ */
+ private $comparatorMapper;
+
+ /**
+ * @var FulltextSearchTableFactory
+ */
+ private $fulltextSearchTableFactory;
+
+ /**
+ * @since 2.2
+ *
+ * @param QuerySegmentListBuilder $querySegmentListBuilder
+ */
+ public function __construct( QuerySegmentListBuilder $querySegmentListBuilder ) {
+ $this->querySegmentListBuilder = $querySegmentListBuilder;
+ $this->comparatorMapper = new ComparatorMapper();
+ $this->fulltextSearchTableFactory = new FulltextSearchTableFactory();
+ }
+
+ /**
+ * @since 2.2
+ *
+ * @return boolean
+ */
+ public function canInterpretDescription( Description $description ) {
+ return $description instanceof ValueDescription;
+ }
+
+ /**
+ * 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();
+ $property = $description->getProperty();
+ $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 ) ) {
+
+ $fulltextSearchSupport = $this->addFulltextSearchCondition(
+ $description,
+ $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 = [ $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;
+ }
+
+ private function addFulltextSearchCondition( $description, $query, $comparator, &$value ) {
+
+ // Uses ~~ wide proximity?
+ $usesWidePromixity = false;
+
+ // If a remaining ~ is present then the user searched with a ~~ string
+ // where the Comparator already matched/removed the first one
+ if ( substr( $value, 0, 1 ) === '~' ) {
+ $value = substr( $value, 1 );
+ $usesWidePromixity = true;
+ }
+
+ // If it is not a wide proximity search and it doesn't have a property then
+ // don't try to match using the fulltext index (redirect [[~Foo]] to LIKE)
+ if ( !$usesWidePromixity && $description->getProperty() === null ) {
+ return false;
+ }
+
+ $valueMatchConditionBuilder = $this->fulltextSearchTableFactory->newValueMatchConditionBuilderByType(
+ $this->querySegmentListBuilder->getStore()
+ );
+
+ if ( !$valueMatchConditionBuilder->isEnabled() || !$valueMatchConditionBuilder->hasMinTokenLength( $value ) ) {
+ return false;
+ }
+
+ if ( !$usesWidePromixity && !$valueMatchConditionBuilder->canApplyFulltextSearchMatchCondition( $description ) ) {
+ return false;
+ }
+
+ $query->joinTable = $valueMatchConditionBuilder->getTableName();
+ $query->joinfield = "{$query->alias}.s_id";
+ $query->indexField = 's_id';
+ $query->components = [];
+
+ $query->where = $valueMatchConditionBuilder->getWhereCondition(
+ new ValueDescription( new DIBlob( $value ), null, $comparator ),
+ $query->alias
+ );
+
+ return $query;
+ }
+
+}