Greetings!

Today I was in need of category negations in queries, so I hacked
something up.

Using this patch, you can now say:
[[Category:!Not this one]]
[[Category:!Neither this||Nor that]]
[[Some Attribute:=>!3]]

It should work with relations too (haven't tested as I don't use those
on my wiki; I also haven't tried subqueries).

This started as a quick hack, but it was surprisingly easy and the code
doesn't look too ugly so I thought I'd share it.

Any comments appreciated!

Thomas

PS: I used "NOT EXISTS (SELECT ...)" to implement negation; I'm no SQL
expert, so I don't know if this is the best/most efficient solution.

--- orig/extensions/SemanticMediaWiki/includes/SMW_InlineQueries.php
+++ mod/extensions/SemanticMediaWiki/includes/SMW_InlineQueries.php
@@ -609,12 +609,19 @@
                                }
                        } elseif ( ($this->mConditionCount < 
$smwgIQMaxConditions) && ($this->mTableCount < $smwgIQMaxTables) ) { // 
conjunct is a real condition
                                $sq_title = '';
+                               $negated = false;
+                               $table = '';
+                               if (mb_substr($qparts[2],0,1) == '!') {
+                                       $negated = true;
+                                       $qparts[2] = mb_substr($qparts[2],1);
+                               }
+
                                if (mb_substr($qparts[2],0,1) == '+') { // 
sub-query or wildcard search
                                        $subq_id = mb_substr($qparts[2],1);
                                        if ( ('' != $subq_id) && 
(array_key_exists($subq_id,$this->mSubQueries)) ) {
                                                $sq = 
$this->parseQuery($this->mSubQueries[$subq_id]);
                                                if ( ('' != $sq->mConditions) 
&& ($this->mConditionCount < $smwgIQMaxConditions) && ($this->mTableCount < 
$smwgIQMaxTables) ) {
-                                                       $result->mTables .= ',' 
. $sq->mTables;
+                                                       $table = $sq->mTables;
                                                        if ( '' != 
$result->mConditions ) $result->mConditions .= ' AND ';
                                                        $result->mConditions .= 
'(' . $sq->mConditions . ')';
                                                        $sq_title = 
$sq->mSelect[1];
@@ -634,7 +641,7 @@
                                $curtable = 't' . $this->mRename++; // alias 
for the current table
 
                                if ($cat_sep == $op ) { // condition on 
category membership
-                                       $result->mTables .= ',' . 
$this->dbr->tableName('categorylinks') . " AS $curtable";
+                                       $table = 
$this->dbr->tableName('categorylinks') . " AS $curtable";
                                        $condition = 
"$pagetable.page_id=$curtable.cl_from";
                                        // TODO: make subcat-inclusion more 
efficient
                                        foreach ($values as $idx => $v) {
@@ -646,7 +653,7 @@
                                        }
                                } elseif ('::' == $op ) { // condition on 
relations
                                        $relation = 
smwfNormalTitleDBKey($qparts[0]);
-                                       $result->mTables .= ',' . 
$this->dbr->tableName('smw_relations') . " AS $curtable";
+                                       $table = 
$this->dbr->tableName('smw_relations') . " AS $curtable";
                                        $condition = 
"$pagetable.page_id=$curtable.subject_id AND $curtable.relation_title=" . 
$this->dbr->addQuotes($relation);
                                        if ('' != $sq_title) { // objects 
supplied by subquery
                                                $condition .= " AND 
$curtable.object_title=$sq_title AND $curtable.object_namespace=$sq_namespace";
@@ -719,7 +726,7 @@
                                                        }
                                                }
                                        }
-                                       $result->mTables .= ',' . 
$this->dbr->tableName('smw_attributes') . " AS $curtable";
+                                       $table = 
$this->dbr->tableName('smw_attributes') . " AS $curtable";
                                        $condition = 
"$pagetable.page_id=$curtable.subject_id AND $curtable.attribute_title=" . 
$this->dbr->addQuotes($attribute);
                                        if ($attribute == $this->mSortkey) {
                                                if ($av->isNumeric()) 
$result->mOrderBy = $curtable . '.value_num';
@@ -746,7 +753,12 @@
                                        if ('' != $result->mConditions) 
$result->mConditions .= ' AND ';
                                        $this->mConditionCount++;
                                        $this->mTableCount++;
-                                       $result->mConditions .= $condition;
+                                       if ($negated) {
+                                               $result->mConditions .= " NOT 
EXISTS (SELECT * FROM $table WHERE $condition)";
+                                       } else {
+                                               $result->mConditions .= 
$condition;
+                                               if ('' != $table) 
$result->mTables .= ','. $table;
+                                       }
                                }
                        }
                }
@@ -1031,4 +1043,4 @@
        }
 }
 
-?>
\ Kein Zeilenumbruch am Dateiende.
+?>

Attachment: signature.asc
Description: Digital signature

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Semediawiki-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/semediawiki-devel

Reply via email to