r23325 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r23324‎ | r23325 | r23326 >
Date:17:08, 24 June 2007
Author:mkroetzsch
Status:old
Tags:
Comment:
Support for wildcard queries on long text attributes, bugfix in unit formatting (no value shown if no desire
unit given), optimisation in storage functions for accessing datavalues.
Modified paths:
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_DataValueFactory.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_OldDataValue.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_QueryProcessor.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_Description.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMediaWiki/includes/SMW_QueryProcessor.php
@@ -581,7 +581,7 @@
582582 }
583583 break;
584584 case '+': // wildcard
585 - $vd = new SMWValueDescription(NULL, SMW_CMP_ANY);
 585+ $vd = new SMWValueDescription(SMWDataValueFactory::newAttributeObjectValue($att), SMW_CMP_ANY);
586586 break;
587587 default: // fixed value, possibly with comparator addons
588588 // for now, treat comparators only if placed before whole value:
@@ -601,7 +601,7 @@
602602 }
603603 }
604604 // TODO: needs extension for n-ary values
605 - $dv = SMWDataValueFactory::newAttributeValue($att->getText(), $value);
 605+ $dv = SMWDataValueFactory::newAttributeObjectValue($att, $value);
606606 if (!$dv->isValid()) {
607607 $this->m_error = $dv->getError();
608608 $vd = new SMWValueDescription(NULL, SMW_CMP_ANY);
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_OldDataValue.php
@@ -302,7 +302,11 @@
303303
304304 public function setOutputFormat($formatstring) {
305305 // interpret new output format as the desired unit for united quantities
306 - $this->setDesiredUnits(array($formatstring));
 306+ if ($formatstring != '') {
 307+ $this->setDesiredUnits(array($formatstring));
 308+ } else {
 309+ $this->setDesiredUnits(array());
 310+ }
307311 }
308312
309313
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_Description.php
@@ -98,7 +98,7 @@
9999
100100 public function getTypeID() {
101101 if ($this->m_typeid === false) {
102 - $dv = SMWDataValueFactory::newAttributeValue($this->m_title->getText());
 102+ $dv = SMWDataValueFactory::newAttributeObjectValue($this->m_title);
103103 $this->m_typeid = $dv->getTypeID();
104104 }
105105 return $this->m_typeid;
@@ -277,7 +277,7 @@
278278 protected $m_datavalue;
279279 protected $m_comparator;
280280
281 - public function SMWValueDescription($datavalue, $comparator = SMW_CMP_EQ) {
 281+ public function SMWValueDescription(SMWDataValue $datavalue, $comparator = SMW_CMP_EQ) {
282282 $this->m_datavalue = $datavalue; // might be NULL for SMW_CMP_ANY
283283 $this->m_comparator = $comparator;
284284 }
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php
@@ -172,45 +172,47 @@
173173 $db =& wfGetDB( DB_MASTER ); // TODO: can we use SLAVE here? Is '=&' needed in PHP5?
174174 $result = array();
175175
176 - // take care of "normal" attributes first
177 - $value_column = 'value_xsd';
178 - if ( ($requestoptions !== NULL) && ($requestoptions->boundary !== NULL) && ($requestoptions->boundary->isNumeric()) ) {
179 - $value_column = 'value_num';
 176+ $id = SMWDataValueFactory::getAttributeObjectTypeID($attribute);
 177+ switch ($id) {
 178+ case 'text': // long text attribute
 179+ $res = $db->select( $db->tableName('smw_longstrings'),
 180+ 'value_blob',
 181+ 'subject_id=' . $db->addQuotes($subject->getArticleID()) .
 182+ ' AND attribute_title=' . $db->addQuotes($attribute->getDBkey()),
 183+ 'SMW::getAttributeValues', $this->getSQLOptions($requestoptions) );
 184+ if($db->numRows( $res ) > 0) {
 185+ while($row = $db->fetchObject($res)) {
 186+ $dv = SMWDataValueFactory::newAttributeObjectValue($attribute);
 187+ $dv->setOutputFormat($outputformat);
 188+ $dv->setXSDValue($row->value_blob, '');
 189+ $result[] = $dv;
 190+ }
 191+ }
 192+ $db->freeResult($res);
 193+ break;
 194+ default: // all others
 195+ if ( ($requestoptions !== NULL) && ($requestoptions->boundary !== NULL) &&
 196+ ($requestoptions->boundary->isNumeric()) ) {
 197+ $value_column = 'value_num';
 198+ } else {
 199+ $value_column = 'value_xsd';
 200+ }
 201+ $sql = 'subject_id=' . $db->addQuotes($subject->getArticleID()) .
 202+ ' AND attribute_title=' . $db->addQuotes($attribute->getDBkey()) .
 203+ $this->getSQLConditions($requestoptions,$value_column,'value_xsd');
 204+ $res = $db->select( $db->tableName('smw_attributes'),
 205+ 'value_unit, value_xsd',
 206+ $sql, 'SMW::getAttributeValues', $this->getSQLOptions($requestoptions,$value_column) );
 207+ if($db->numRows( $res ) > 0) {
 208+ while($row = $db->fetchObject($res)) {
 209+ $dv = SMWDataValueFactory::newAttributeObjectValue($attribute);
 210+ $dv->setOutputFormat($outputformat);
 211+ $dv->setXSDValue($row->value_xsd, $row->value_unit);
 212+ $result[] = $dv;
 213+ }
 214+ }
 215+ $db->freeResult($res);
180216 }
181 - $sql = 'subject_id=' . $db->addQuotes($subject->getArticleID()) .
182 - ' AND attribute_title=' . $db->addQuotes($attribute->getDBkey()) .
183 - $this->getSQLConditions($requestoptions,$value_column,'value_xsd');
184 - $res = $db->select( $db->tableName('smw_attributes'),
185 - 'value_unit, value_datatype, value_xsd',
186 - $sql, 'SMW::getAttributeValues', $this->getSQLOptions($requestoptions,$value_column) );
187 - if($db->numRows( $res ) > 0) {
188 - while($row = $db->fetchObject($res)) {
189 - $dv = SMWDataValueFactory::newTypehandlerValue(SMWTypeHandlerFactory::getTypeHandlerByID($row->value_datatype));
190 - $dv->setAttribute($attribute->getText());
191 - $dv->setOutputFormat($outputformat);
192 - $dv->setXSDValue($row->value_xsd, $row->value_unit);
193 - $result[] = $dv;
194 - }
195 - }
196 - $db->freeResult($res);
197 -
198 - // finally, look for long strings
199 - $res = $db->select( $db->tableName('smw_longstrings'),
200 - 'value_blob',
201 - 'subject_id=' . $db->addQuotes($subject->getArticleID()) .
202 - ' AND attribute_title=' . $db->addQuotes($attribute->getDBkey()),
203 - 'SMW::getAttributeValues', $this->getSQLOptions($requestoptions,$value_column) );
204 - if($db->numRows( $res ) > 0) {
205 - while($row = $db->fetchObject($res)) {
206 - $dv = SMWDataValueFactory::newTypehandlerValue(SMWTypeHandlerFactory::getTypeHandlerByID('text'));
207 - $dv->setAttribute($attribute->getText());
208 - $dv->setOutputFormat($outputformat);
209 - $dv->setXSDValue($row->value_blob, '');
210 - $result[] = $dv;
211 - }
212 - }
213 - $db->freeResult($res);
214 -
215217 return $result;
216218 }
217219
@@ -246,25 +248,32 @@
247249 $this->getSQLConditions($requestoptions,'subject_title','subject_title');
248250
249251 $result = array();
250 - $res = $db->select( $db->tableName('smw_attributes'),
251 - 'DISTINCT subject_id',
252 - $sql, 'SMW::getAllAttributeSubjects', $this->getSQLOptions($requestoptions,'subject_title') );
253 - if($db->numRows( $res ) > 0) {
254 - while($row = $db->fetchObject($res)) {
255 - $result[] = Title::newFromId($row->subject_id);
256 - }
 252+ $id = SMWDataValueFactory::getAttributeObjectTypeID($attribute);
 253+ switch ($id) {
 254+ case 'text':
 255+ $res = $db->select( $db->tableName('smw_longstrings'),
 256+ 'DISTINCT subject_id',
 257+ $sql, 'SMW::getAllAttributeSubjects',
 258+ $this->getSQLOptions($requestoptions,'subject_title') );
 259+ if($db->numRows( $res ) > 0) {
 260+ while($row = $db->fetchObject($res)) {
 261+ $result[] = Title::newFromId($row->subject_id);
 262+ }
 263+ }
 264+ $db->freeResult($res);
 265+ break;
 266+ default:
 267+ $res = $db->select( $db->tableName('smw_attributes'),
 268+ 'DISTINCT subject_id',
 269+ $sql, 'SMW::getAllAttributeSubjects',
 270+ $this->getSQLOptions($requestoptions,'subject_title') );
 271+ if($db->numRows( $res ) > 0) {
 272+ while($row = $db->fetchObject($res)) {
 273+ $result[] = Title::newFromId($row->subject_id);
 274+ }
 275+ }
 276+ $db->freeResult($res);
257277 }
258 - $db->freeResult($res);
259 - $res = $db->select( $db->tableName('smw_longstrings'),
260 - 'DISTINCT subject_id',
261 - $sql, 'SMW::getAllAttributeSubjects', $this->getSQLOptions($requestoptions,'subject_title') );
262 - if($db->numRows( $res ) > 0) {
263 - while($row = $db->fetchObject($res)) {
264 - $result[] = Title::newFromId($row->subject_id);
265 - }
266 - }
267 - $db->freeResult($res);
268 -
269278 return $result;
270279 }
271280
@@ -533,7 +542,6 @@
534543 * Probably the query parser (e.g. it can distinguish subqueries from other nested constructs that
535544 * are not "subqueries" from a user perspective, it also has a good insight in the query structure for
536545 * applying structural limits)
537 - * TODO: implement namespace restrictions
538546 * TODO: we now have sorting even for subquery conditions. Does this work? Is it slow/problematic?
539547 * NOTE: we do not support category wildcards, as they have no useful semantics in OWL/RDFS/LP/whatever
540548 */
@@ -676,7 +684,7 @@
677685 value_datatype VARCHAR(31) NOT NULL,
678686 value_xsd VARCHAR(255) NOT NULL,
679687 value_num DOUBLE
680 - ) TYPE=innodb';
 688+ ) TYPE=innodb'; /// TODO: remove value_datatype column completely
681689 $res = $db->query( $sql, $fname );
682690 }
683691
@@ -827,6 +835,12 @@
828836 $from .= ' INNER JOIN ' . $db->tableName('smw_attributes') . ' AS ' . $curtables['ATTS'] . ' ON ' . $curtables['ATTS'] . '.subject_id=' . $curtables['PAGE'] . '.page_id';
829837 return true;
830838 }
 839+ } elseif ($tablename == 'TEXT') {
 840+ if ($this->addInnerJoin('PAGE', $from, $db, $curtables)) { // try to add PAGE
 841+ $curtables['TEXT'] = 'txt' . $this->m_tablenum++;
 842+ $from .= ' INNER JOIN ' . $db->tableName('smw_longstrings') . ' AS ' . $curtables['TEXT'] . ' ON ' . $curtables['TEXT'] . '.subject_id=' . $curtables['PAGE'] . '.page_id';
 843+ return true;
 844+ }
831845 }
832846 return false;
833847 }
@@ -886,28 +900,33 @@
887901 $description->getIndividual()->getNamespace();
888902 }
889903 } elseif ($description instanceof SMWValueDescription) {
890 - if ( $this->addInnerJoin('ATTS', $from, $db, $curtables) ) {
891 - switch ($description->getComparator()) {
892 - case SMW_CMP_EQ: $op = '='; break;
893 - case SMW_CMP_LEQ: $op = '<='; break;
894 - case SMW_CMP_GEQ: $op = '>='; break;
895 - case SMW_CMP_NEQ: $op = '!='; break;
896 - case SMW_CMP_ANY: default: $op = NULL; break;
897 - }
898 - if ($op !== NULL) {
899 - if ($description->getDatavalue()->isNumeric()) {
900 - $valuefield = 'value_num';
901 - $value = $description->getDatavalue()->getNumericValue();
902 - } else {
903 - $valuefield = 'value_xsd';
904 - $value = $description->getDatavalue()->getXSDValue();
 904+ switch ($description->getDatavalue()->getTypeID()) {
 905+ case 'text': // actually this should not happen; we cannot do anything here
 906+ break;
 907+ default:
 908+ if ( $this->addInnerJoin('ATTS', $from, $db, $curtables) ) {
 909+ switch ($description->getComparator()) {
 910+ case SMW_CMP_EQ: $op = '='; break;
 911+ case SMW_CMP_LEQ: $op = '<='; break;
 912+ case SMW_CMP_GEQ: $op = '>='; break;
 913+ case SMW_CMP_NEQ: $op = '!='; break;
 914+ case SMW_CMP_ANY: default: $op = NULL; break;
 915+ }
 916+ if ($op !== NULL) {
 917+ if ($description->getDatavalue()->isNumeric()) {
 918+ $valuefield = 'value_num';
 919+ $value = $description->getDatavalue()->getNumericValue();
 920+ } else {
 921+ $valuefield = 'value_xsd';
 922+ $value = $description->getDatavalue()->getXSDValue();
 923+ }
 924+ ///TODO: implement check for unit
 925+ $where .= $curtables['ATTS'] . '.' . $valuefield . $op . $db->addQuotes($value);
 926+ if ($sort != '') {
 927+ $this->m_sortfield = $curtables['ATTS'] . '.' . $valuefield;
 928+ }
 929+ }
905930 }
906 - ///TODO: implement check for unit
907 - $where .= $curtables['ATTS'] . '.' . $valuefield . $op . $db->addQuotes($value);
908 - if ($sort != '') {
909 - $this->m_sortfield = $curtables['ATTS'] . '.' . $valuefield;
910 - }
911 - }
912931 }
913932 } elseif ($description instanceof SMWConjunction) {
914933 foreach ($description->getDescriptions() as $subdesc) {
@@ -950,13 +969,24 @@
951970 }
952971 }
953972 } elseif ($description instanceof SMWSomeAttribute) {
954 - if ($this->addInnerJoin('ATTS', $from, $db, $curtables)) {
955 - $where .= $curtables['ATTS'] . '.attribute_title=' .
956 - $db->addQuotes($description->getAttribute()->getDBKey());
957 - $this->createSQLQuery($description->getDescription(), $from, $subwhere, $db, $curtables, ($this->m_sortkey == $description->getAttribute()->getDBKey()) );
958 - if ( $subwhere != '') {
959 - $where .= ' AND (' . $subwhere . ')';
960 - }
 973+ $id = SMWDataValueFactory::getAttributeObjectTypeID($description->getAttribute());
 974+ switch ($id) {
 975+ case 'text':
 976+ if ($this->addInnerJoin('TEXT', $from, $db, $curtables)) {
 977+ $where .= $curtables['TEXT'] . '.attribute_title=' .
 978+ $db->addQuotes($description->getAttribute()->getDBKey());
 979+ // no recursion: we do not support further conditions on text-type values
 980+ }
 981+ break;
 982+ default:
 983+ if ($this->addInnerJoin('ATTS', $from, $db, $curtables)) {
 984+ $where .= $curtables['ATTS'] . '.attribute_title=' .
 985+ $db->addQuotes($description->getAttribute()->getDBKey());
 986+ $this->createSQLQuery($description->getDescription(), $from, $subwhere, $db, $curtables, ($this->m_sortkey == $description->getAttribute()->getDBKey()) );
 987+ if ( $subwhere != '') {
 988+ $where .= ' AND (' . $subwhere . ')';
 989+ }
 990+ }
961991 }
962992 }
963993
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_DataValueFactory.php
@@ -18,11 +18,16 @@
1919 static private $m_valueclasses = array();
2020
2121 /**
22 - * Cache for type labels, indexed by attribute name (both without namespace prefix).
 22+ * Cache for type specifications (right now strings), indexed by attribute name (both without namespace prefix).
2323 */
24 - static private $m_attributelabels = array('Testnary' => 'String;Integer;Wikipage;Date'); ///DEBUG
 24+ static private $m_typelabels = array('Testnary' => 'String;Integer;Wikipage;Date'); ///DEBUG
2525
2626 /**
 27+ * Cache for type ids, indexed by attribute name (without namespace prefix).
 28+ */
 29+ static private $m_typeids = array();
 30+
 31+ /**
2732 * Was code for handling n-ary properties already included?
2833 */
2934 static private $m_naryincluded = false;
@@ -33,14 +38,31 @@
3439 * can be set later on.
3540 */
3641 static public function newAttributeValue($attstring, $value=false) {
37 - if(!array_key_exists($attstring,SMWDataValueFactory::$m_attributelabels)) {
 42+ if(!array_key_exists($attstring,SMWDataValueFactory::$m_typelabels)) {
3843 $atitle = Title::newFromText($attstring, SMW_NS_ATTRIBUTE);
3944 if ($atitle !== NULL) {
40 - $typearray = smwfGetStore()->getSpecialValues($atitle,SMW_SP_HAS_TYPE);
41 - } else { $typearray = Array(); }
 45+ return SMWDataValueFactory::newAttributeObjectValue($atitle,$value);
 46+ } else {
 47+ return new SMWOldDataValue(new SMWErrorTypeHandler(wfMsgForContent('smw_notype')));
 48+ }
 49+ }
 50+ return SMWDataValueFactory::newTypedValue(SMWDataValueFactory::$m_typelabels[$attstring], $value);
 51+ }
4252
 53+ /**
 54+ * Create a value from a string supplied by a user for a given attribute title.
 55+ * If no value is given, an empty container is created, the value of which
 56+ * can be set later on.
 57+ */
 58+ static public function newAttributeObjectValue(Title $att, $value=false) {
 59+ $attstring = $att->getText();
 60+ if(!array_key_exists($attstring,SMWDataValueFactory::$m_typelabels)) {
 61+ $typearray = smwfGetStore()->getSpecialValues($att,SMW_SP_HAS_TYPE);
4362 if (count($typearray)==1) {
44 - SMWDataValueFactory::$m_attributelabels[$attstring] = $typearray[0];
 63+ SMWDataValueFactory::$m_typelabels[$attstring] = $typearray[0];
 64+ $result = SMWDataValueFactory::newTypedValue(SMWDataValueFactory::$m_typelabels[$attstring], $value);
 65+ SMWDataValueFactory::$m_typeids[$attstring] = $result->getTypeID(); // also cache typeid
 66+ return $result;
4567 } elseif (count($typearray)==0) {
4668 ///TODO
4769 return new SMWOldDataValue(new SMWErrorTypeHandler(wfMsgForContent('smw_notype')));
@@ -49,7 +71,7 @@
5072 return new SMWOldDataValue(new SMWErrorTypeHandler(wfMsgForContent('smw_manytypes')));
5173 }
5274 }
53 - return SMWDataValueFactory::newTypedValue(SMWDataValueFactory::$m_attributelabels[$attstring], $value);
 75+ return SMWDataValueFactory::newTypedValue(SMWDataValueFactory::$m_typelabels[$attstring], $value);
5476 }
5577
5678 /**
@@ -134,6 +156,18 @@
135157 }
136158
137159 /**
 160+ * Quickly get the type id of some attribute without necessarily making another datavalue.
 161+ */
 162+ static public function getAttributeObjectTypeID(Title $att) {
 163+ $attstring = $att->getText();
 164+ if (array_key_exists($attstring, SMWDataValueFactory::$m_typeids)) {
 165+ return SMWDataValueFactory::$m_typeids[$attstring];
 166+ } else {
 167+ return SMWDataValueFactory::newAttributeObjectValue($att)->getTypeID(); // this also triggers caching
 168+ }
 169+ }
 170+
 171+ /**
138172 * Create a value from a user-supplied string for which a type handler is known
139173 * If no value is given, an empty container is created, the value of which
140174 * can be set later on.

Status & tagging log