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.
+?>
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
