r60749 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r60748‎ | r60749 | r60750 >
Date:21:46, 6 January 2010
Author:mkroetzsch
Status:deferred
Tags:
Comment:
data value objects now parse query conditions related to their datatype, so the query parser needs no more case distinctions to cover different types, and the type system is more modular overall
Modified paths:
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_DV_List.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_DataValue.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_QueryParser.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMediaWiki/includes/SMW_DV_List.php
@@ -18,28 +18,28 @@
1919
2020 /// cache for datavalues of types belonging to this object
2121 private $m_typevalues = null;
22 - /// Should this DV operate on query syntax (special mode for parsing queries in a compatible fashion)
23 - private $m_querysyntax = false;
24 - /// Array of comparators as might be found in query strings (based on inputs like >, <, etc.)
25 - private $m_comparators;
2622
2723 protected function parseUserValue($value) {
2824 $this->m_data->clear();
29 - $this->m_comparators = array(); // only for query mode
 25+ $this->parseUserValueOrQuery($value,false);
 26+ }
 27+
 28+ protected function parseUserValueOrQuery($value,$querymode) {
3029 if ($value == '') { /// TODO internalionalize
3130 $this->addError('No values specified.');
32 - return;
 31+ return $querymode?new SMWThingDescription():$this->m_data;
3332 }
3433
 34+ $subdescriptions = array(); // only used for query mode
3535 $types = $this->getTypeValues();
3636 $values = preg_split('/[\s]*;[\s]*/u', trim($value));
3737 $vi = 0; // index in value array
3838 $empty = true;
3939 for ($i = 0; $i < max(5,count($types)); $i++) { // iterate over slots
4040 // special handling for supporting query parsing
41 - if ($this->m_querysyntax) {
 41+ if ($querymode) {
4242 $comparator = SMW_CMP_EQ;
43 - SMWQueryParser::prepareValue($values[$vi], $comparator);
 43+ SMWDataValue::prepareValue($values[$vi], $comparator);
4444 }
4545 // generating the DVs:
4646 if ( (count($values) > $vi) &&
@@ -48,12 +48,14 @@
4949 } elseif (array_key_exists($vi,$values) && array_key_exists($i,$types)) { // some values left, try next slot
5050 $dv = SMWDataValueFactory::newTypeObjectValue($types[$i], $values[$vi]);
5151 if ($dv->isValid()) { // valid DV: keep
52 - $this->m_data->addPropertyObjectValue(SMWPropertyValue::makeProperty('_' . ($i+1)), $dv);
 52+ $property = SMWPropertyValue::makeProperty('_' . ($i+1));
 53+ if ($querymode) {
 54+ $subdescriptions[] = new SMWSomeProperty($property, new SMWValueDescription($dv,$comparator));
 55+ } else {
 56+ $this->m_data->addPropertyObjectValue($property, $dv);
 57+ }
5358 $vi++;
5459 $empty = false;
55 - if ($this->m_querysyntax) { // keep comparator for later querying
56 - $this->m_comparators[$i] = $comparator;
57 - }
5860 } elseif ( (count($values)-$vi) == (count($types)-$i) ) {
5961 // too many errors: keep this one to have enough slots left
6062 $this->m_data->addPropertyObjectValue(SMWPropertyValue::makeProperty('_' . ($i+1)), $dv);
@@ -65,6 +67,9 @@
6668 if ($empty) { /// TODO internalionalize
6769 $this->addError('No values specified.');
6870 }
 71+ if ($querymode) {
 72+ return $empty?new SMWThingDescription():new SMWConjunction($subdescriptions);
 73+ }
6974 }
7075
7176 /**
@@ -91,6 +96,14 @@
9297 }
9398 }
9499
 100+ /**
 101+ * Overwrite SMWDataValue::getQueryDescription() to be able to process
 102+ * comparators between all values.
 103+ */
 104+ public function getQueryDescription($value) {
 105+ return $this->parseUserValueOrQuery($value,true);
 106+ }
 107+
95108 public function getShortWikiText($linked = null) {
96109 if ($this->m_caption !== false) {
97110 return $this->m_caption;
@@ -178,6 +191,7 @@
179192 $dv = reset($this->m_data->getPropertyValues($property));
180193 $result[$i-1] = ($dv instanceof SMWDataValue)?$dv:null;
181194 }
 195+ return $result;
182196 }
183197
184198 ////// Internal helper functions
@@ -214,13 +228,6 @@
215229 ////// Custom functions for old n-aries; may become obsolete.
216230
217231 /**
218 - * Change to query syntax mode.
219 - */
220 - public function acceptQuerySyntax() {
221 - $this->m_querysyntax = true;
222 - }
223 -
224 - /**
225232 * Return the array (list) of datatypes that the individual entries of this datatype consist of.
226233 * @todo Add some check to account for maximal number of list entries (maybe this should go to a
227234 * variant of the SMWTypesValue).
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_DataValue.php
@@ -256,6 +256,58 @@
257257 */
258258 abstract protected function parseDBkeys($args);
259259
 260+///// Query support /////
 261+
 262+ /**
 263+ * Create an SMWDescription object based on a value string that was entered
 264+ * in a query. Turning inputs that a user enters in place of a value within
 265+ * a query string into query conditions is often a standard procedure. The
 266+ * processing must take comparators like "<" into account, but otherwise
 267+ * the normal parsing function can be used. However, there can be datatypes
 268+ * where processing is more complicated, e.g. if the input string contains
 269+ * more than one value, each of which may have comparators, as in
 270+ * SMWListValue. In this case, it makes sense to overwrite this method.
 271+ * Another reason to do this is to add new forms of comparators or new ways
 272+ * of entering query conditions.
 273+ *
 274+ * The resulting SMWDescription may or may not make use of the datavalue
 275+ * object that this function was called on, so it must be ensured that this
 276+ * value is not used elsewhere when calling this method. The function can
 277+ * return SMWThingDescription to not impose any condition, e.g. if parsing
 278+ * failed. Error messages of this SMWDataValue object are propagated.
 279+ */
 280+ public function getQueryDescription($value) {
 281+ $comparator = SMW_CMP_EQ;
 282+ SMWDataValue::prepareValue($value, $comparator);
 283+ $this->setUserValue($value);
 284+ if (!$this->isValid()) {
 285+ return new SMWThingDescription();
 286+ } else {
 287+ return new SMWValueDescription($this, $comparator);
 288+ }
 289+ }
 290+
 291+ /**
 292+ * Helper function for getQueryDescription() that prepares a single value
 293+ * string, possibly extracting comparators. $value is changed to consist
 294+ * only of the remaining effective value string (without the comparator).
 295+ */
 296+ static protected function prepareValue(&$value, &$comparator) {
 297+ global $smwgQComparators;
 298+ $list = preg_split('/^(' . $smwgQComparators . ')/u',$value, 2, PREG_SPLIT_DELIM_CAPTURE);
 299+ $comparator = SMW_CMP_EQ;
 300+ if (count($list) == 3) { // initial comparator found ($list[0] should be empty)
 301+ $value = $list[2];
 302+ switch ($list[1]) {
 303+ case '<': $comparator = SMW_CMP_LEQ; break;
 304+ case '>': $comparator = SMW_CMP_GEQ; break;
 305+ case '!': $comparator = SMW_CMP_NEQ; break;
 306+ case '~': $comparator = SMW_CMP_LIKE; break;
 307+ //default: not possible
 308+ }
 309+ }
 310+ }
 311+
260312 ///// Get methods /////
261313
262314
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_QueryParser.php
@@ -342,26 +342,10 @@
343343 }
344344 } ///NOTE: at this point, we normally already read one more chunk behind the value
345345
346 - if ( ($typeid == '__nry') && !$inverse ) { // nary value
347 - $dv = SMWDataValueFactory::newPropertyObjectValue($property);
348 - $dv->acceptQuerySyntax();
349 - $dv->setUserValue($value);
350 - $vl = $dv->getValueList();
351 - if ($vl !== null) {
352 - $innerdesc = $this->addDescription($innerdesc, $vl, false);
353 - }
354 - } else { // unary value
355 - $comparator = SMW_CMP_EQ;
356 - SMWQueryParser::prepareValue($value, $comparator);
357 - $dv = SMWDataValueFactory::newPropertyObjectValue($property, $value);
358 - if (!$dv->isValid()) {
359 - $this->m_errors = $this->m_errors + $dv->getErrors();
360 - $vd = new SMWThingDescription();
361 - } else {
362 - $vd = new SMWValueDescription($dv, $comparator);
363 - }
364 - $innerdesc = $this->addDescription($innerdesc, $vd, false);
365 - }
 346+ $dv = SMWDataValueFactory::newPropertyObjectValue($property);
 347+ $vd = $dv->getQueryDescription($value);
 348+ $innerdesc = $this->addDescription($innerdesc, $vd, false);
 349+ $this->m_errors = $this->m_errors + $dv->getErrors();
366350 }
367351 $continue = ($chunk == '||');
368352 }
@@ -380,37 +364,7 @@
381365 return $this->finishLinkDescription($chunk, false, $result, $setNS, $label);
382366 }
383367
384 -
385368 /**
386 - * Prepare a single value string, possibly extracting comparators. $value is
387 - * changed to consist only of the remaining effective value string (without the
388 - * comparator).
389 - */
390 - static public function prepareValue(&$value, &$comparator) {
391 - global $smwgQComparators;
392 - $list = preg_split('/^(' . $smwgQComparators . ')/u',$value, 2, PREG_SPLIT_DELIM_CAPTURE);
393 - $comparator = SMW_CMP_EQ;
394 - if (count($list) == 3) { // initial comparator found ($list[0] should be empty)
395 - $value = $list[2];
396 - switch ($list[1]) {
397 - case '<':
398 - $comparator = SMW_CMP_LEQ;
399 - break;
400 - case '>':
401 - $comparator = SMW_CMP_GEQ;
402 - break;
403 - case '!':
404 - $comparator = SMW_CMP_NEQ;
405 - break;
406 - case '~':
407 - $comparator = SMW_CMP_LIKE;
408 - break;
409 - //default: not possible
410 - }
411 - }
412 - }
413 -
414 - /**
415369 * Parse an article description (the part of an inline query that
416370 * is in between "[[" and the closing "]]" assuming it is not specifying
417371 * a category or property) and create a suitable description.

Status & tagging log