From: Ittay D. <it...@ql...> - 2007-01-01 09:27:57
|
can i create an attribute whose type is some enumeration? the point is to have an attribute that accepts string values, but still be able to create order, and use comparisons in queries. my use case is a 'product_version' attribute. I'd like for different components to state since what product version they exist ('since version 1.2'). i want then to be able to list all components for a given version (something like [[product_version:=<1.3]]). version names can be anything (e.g. 'xp'). so i want to be able to map them in the attribute page (or type of). then i'd assign to 1.1 the value of 1, to 1.2 the value of 2, to 'xp' the value of 3, etc. when new versions come (incl. minor versions), i'll update the page, inserting the version and its sequence number (maybe bumping others) thanks, ittay -- =================================== Ittay Dror, Chief architect, openQRM group leader, R&D, Qlusters Inc. it...@ql... +972-3-6081994 Fax: +972-3-6081841 www.openqrm.org - Data Center Provisioning |
From: S P. <ski...@ea...> - 2007-01-05 12:24:42
|
Ittay Dror wrote: > can i create an attribute whose type is some enumeration? Not yet, but you join the list of people asking for this feature. I should be coding better date/time handling :-) but this is pretty straightforward; I've got an implementation working locally and should be able to check it into SVN tomorrow if no one objects. > the point is to have an attribute that accepts string values, but > still be able to create order, and use comparisons in queries. > > my use case is a 'product_version' attribute. I'd like for different > components to state since what product version they exist ('since > version 1.2'). i want then to be able to list all components for a > given version (something like [[product_version:=<1.3]]). The inline query code would have to detect queries on the enumerated datatype, look up the value_num for 1.3, and query on that. I don't have that part working. > version names can be anything (e.g. 'xp'). so i want to be able to > map them in the attribute page (or type of). then i'd assign to 1.1 > the value of 1, to 1.2 the value of 2, to 'xp' the value of 3, etc. In my "keep it simple" approach, the [[Attribute:Product version]] page would have the special property [[possible values:=3.0,3.1,98,98SE,ME,XP,Vista]] and each comma-separated value gets a numeric offset that you wouldn't be able to control (or see). > when new versions come (incl. minor versions), i'll update the page, > inserting the version and its sequence number (maybe bumping others) In my "keep it simple" approach, if you inserted a new value within possible values, you'd have to re-edit all pages with the attribute to update the offsets. If you really want an advanced enum type that lets you control the numeric value of each string, how would you specify this in wiki text? In another message, Ittay Dror wrote: > can anyone please give pointers (or example code) how to > implement as custom type (php)? My PHP code for SMWEnumeratedTypeHandler is a combination of SMWStringTypeHandler and SMWBooleanTypeHandler, with handling of the special property "possible values" similar to "display units". Nothing innovative ;-) Notes ----- I don't think there's any way to represent an enumerated type in RDF export beyond the string XSD type. Although strings are the obvious case for enumeration, [[possible values]] could also be applied to other attribute datatypes, and even to relations. But no one's asked for that yet. The [[possible values]] special property will really run into the 255 character limit for string values. But if you split the enumeration across two [[possible value]] attributes, I don't think order is guaranteed between them. -- =S |
From: Ittay D. <it...@ql...> - 2007-01-07 10:25:57
|
S Page wrote: > Ittay Dror wrote: > > > can i create an attribute whose type is some enumeration? > > Not yet, but you join the list of people asking for this feature. > > I should be coding better date/time handling :-) > but this is pretty straightforward; I've got an implementation working > locally and should be able to check it into SVN tomorrow if no one objects. thanks! > > > the point is to have an attribute that accepts string values, but > > still be able to create order, and use comparisons in queries. > > > > my use case is a 'product_version' attribute. I'd like for different > > components to state since what product version they exist ('since > > version 1.2'). i want then to be able to list all components for a > > given version (something like [[product_version:=<1.3]]). > > The inline query code would have to detect queries on the enumerated > datatype, look up the value_num for 1.3, and query on that. I don't > have that part working. > > > version names can be anything (e.g. 'xp'). so i want to be able to > > map them in the attribute page (or type of). then i'd assign to 1.1 > > the value of 1, to 1.2 the value of 2, to 'xp' the value of 3, etc. > > In my "keep it simple" approach, the [[Attribute:Product version]] page > would have the special property > [[possible values:=3.0,3.1,98,98SE,ME,XP,Vista]] > and each comma-separated value gets a numeric offset that you wouldn't > be able to control (or see). is it hard to allow me to assign them explicitely as [[possible values:=3.0=>100,3.1=>200,98=>300,98SE=>400]] ? the reason for the gaps is to allow me to put in a 3.1.2=>201 in the future. that way, old values don't change. > > > when new versions come (incl. minor versions), i'll update the page, > > inserting the version and its sequence number (maybe bumping others) > > In my "keep it simple" approach, if you inserted a new value within > possible values, you'd have to re-edit all pages with the attribute to > update the offsets. If you really want an advanced enum type that lets > you control the numeric value of each string, how would you specify this > in wiki text? > > In another message, Ittay Dror wrote: > > can anyone please give pointers (or example code) how to > > implement as custom type (php)? > My PHP code for SMWEnumeratedTypeHandler is a combination of > SMWStringTypeHandler and SMWBooleanTypeHandler, with handling of the > special property "possible values" similar to "display units". Nothing > innovative ;-) > > Notes > ----- > I don't think there's any way to represent an enumerated type in RDF > export beyond the string XSD type. > > Although strings are the obvious case for enumeration, [[possible > values]] could also be applied to other attribute datatypes, and even to > relations. But no one's asked for that yet. > > The [[possible values]] special property will really run into the 255 > character limit for string values. But if you split the enumeration > across two [[possible value]] attributes, I don't think order is > guaranteed between them. > > -- > =S > -- =================================== Ittay Dror, Chief architect, R&D, Qlusters Inc. it...@ql... +972-3-6081994 Fax: +972-3-6081841 www.openqrm.org - Data Center Provisioning |
From: Ittay D. <it...@ql...> - 2007-01-07 10:49:44
|
S Page wrote: > Ittay Dror wrote: > > > can i create an attribute whose type is some enumeration? > > Not yet, but you join the list of people asking for this feature. > > I should be coding better date/time handling :-) > but this is pretty straightforward; I've got an implementation working > locally and should be able to check it into SVN tomorrow if no one objects. > > > the point is to have an attribute that accepts string values, but > > still be able to create order, and use comparisons in queries. > > > > my use case is a 'product_version' attribute. I'd like for different > > components to state since what product version they exist ('since > > version 1.2'). i want then to be able to list all components for a > > given version (something like [[product_version:=<1.3]]). > > The inline query code would have to detect queries on the enumerated > datatype, look up the value_num for 1.3, and query on that. I don't > have that part working. can it be done by using special properties, like for the linear type handler (conversions) property. the conversions will be from labels to numbers, rather than factors to units. > > > version names can be anything (e.g. 'xp'). so i want to be able to > > map them in the attribute page (or type of). then i'd assign to 1.1 > > the value of 1, to 1.2 the value of 2, to 'xp' the value of 3, etc. > > In my "keep it simple" approach, the [[Attribute:Product version]] page > would have the special property > [[possible values:=3.0,3.1,98,98SE,ME,XP,Vista]] > and each comma-separated value gets a numeric offset that you wouldn't > be able to control (or see). > > > when new versions come (incl. minor versions), i'll update the page, > > inserting the version and its sequence number (maybe bumping others) > > In my "keep it simple" approach, if you inserted a new value within > possible values, you'd have to re-edit all pages with the attribute to > update the offsets. If you really want an advanced enum type that lets > you control the numeric value of each string, how would you specify this > in wiki text? > > In another message, Ittay Dror wrote: > > can anyone please give pointers (or example code) how to > > implement as custom type (php)? > My PHP code for SMWEnumeratedTypeHandler is a combination of > SMWStringTypeHandler and SMWBooleanTypeHandler, with handling of the > special property "possible values" similar to "display units". Nothing > innovative ;-) > > Notes > ----- > I don't think there's any way to represent an enumerated type in RDF > export beyond the string XSD type. > > Although strings are the obvious case for enumeration, [[possible > values]] could also be applied to other attribute datatypes, and even to > relations. But no one's asked for that yet. > > The [[possible values]] special property will really run into the 255 > character limit for string values. But if you split the enumeration > across two [[possible value]] attributes, I don't think order is > guaranteed between them. > > -- > =S > -- =================================== Ittay Dror, Chief architect, R&D, Qlusters Inc. it...@ql... +972-3-6081994 Fax: +972-3-6081841 www.openqrm.org - Data Center Provisioning |
From: Ittay D. <it...@ql...> - 2007-01-07 12:32:48
|
ok, i think i implemented this. the example is a bug 'severity' enumeration. the attribute page is: [[has type::Type:Severity]] the type pages is: [[Enum mapping:=Blocker=7]] [[Enum mapping:=Critical=6]] [[Enum mapping:=Major=5]] [[Enum mapping:=Normal=4]] [[Enum mapping:=Minor=3]] [[Enum mapping:=Trivial=2]] [[Enum mapping:=Enhancement=1]] then, i can do stuff like <ask>[[severity:=>Normal]]</ask> here is the patch diff -u -r /tmp/SemanticMediaWiki/includes/SMW_DT_Integer.php SemanticMediaWiki/includes/SMW_DT_Integer.php --- /tmp/SemanticMediaWiki/includes/SMW_DT_Integer.php 2007-01-07 10:39:35.000000000 +0200 +++ SemanticMediaWiki/includes/SMW_DT_Integer.php 2007-01-07 14:21:07.000000000 +0200 @@ -60,4 +60,76 @@ } } -?> \ No newline at end of file +/** + * Class for managing integer types. Parses whole number + * strings and generates appropriate error messages on + * failure. + */ +class SMWEnumTypeHandler extends SMWIntegerTypeHandler { + protected $typeid; + + protected $mappings = array(); + + /** + * Constructor. Since the linear type is polymorphic, a + * typeid is needed to be able to retrieve the right type for + * values stored in the database (where the typeid is used). + */ + function SMWEnumTypeHandler($typeid, $mappings = NULL) { + $this->typeid = str_replace(' ', '_', $typeid); + if ($mappings !== NULL) { + $this->parseMappings($mappings); + } + } + + function parseMappings($mappings) { + foreach ($mappings as $mapping) { + list($name, $value) = explode("=", $mapping); + $this->mappings[$name] = $value; + } + } + + function getID() { + return $this->typeid; + } + + function getXSDType() { + return 'http://www.w3.org/2001/XMLSchema#' . $this->typeid; + } + + function getUnits() { //no units for enum + return array('STDUNIT'=>false, 'ALLUNITS'=>array()); + } + + function processValue($v,&$datavalue) { + if (array_key_exists($v, $this->mappings)) { + $datavalue->setProcessedValues($v, $this->mappings[$v], $this->mappings[$v]); + $datavalue->setPrintoutString($v); + $datavalue->addQuicksearchLink(); + $datavalue->addServiceLinks($v); + } else { + $datavalue->setError(wfMsgForContent($v . " is not a valid value for " . $this->getID())); + } + return; + } + + /** + * This method parses the value in the XSD form that was + * generated by parsing some user input. It is needed since + * the XSD form must be compatible to XML, and thus does not + * respect the internationalization settings. E.g. the German + * input value "1,234" is translated into XSD "1.234" which, + * if reparsed as a user input would be misinterpreted as 1234. + * + * @public + */ + function processXSDValue($value,$unit,&$datavalue) { + return $this->processValue($value . $unit, $datavalue); + } + + function isNumeric() { + return TRUE; + } +} + +?> diff -u -r /tmp/SemanticMediaWiki/includes/SMW_Datatype.php SemanticMediaWiki/includes/SMW_Datatype.php --- /tmp/SemanticMediaWiki/includes/SMW_Datatype.php 2007-01-07 10:39:35.000000000 +0200 +++ SemanticMediaWiki/includes/SMW_Datatype.php 2007-01-07 14:16:26.000000000 +0200 @@ -23,6 +23,7 @@ * Better to only load datatype PHP files as needed!? */ require_once('SMW_DT_Float.php'); +require_once('SMW_DT_Integer.php'); /** * Static class for registerig and retrieving typehandlers. @@ -129,6 +130,8 @@ return new SMWStringTypeHandler(); case SMW_SP_CONVERSION_FACTOR: return new SMWStringTypeHandler(); + case SMW_SP_ENUM_MAP: + return new SMWStringTypeHandler(); default: global $smwgContLang; $specprops = $smwgContLang->getSpecialPropertiesArray(); @@ -141,10 +144,10 @@ * (i.e. a localized type name), or an error type handler if the label * is not associated with some handler. The label is usually the article * name of the type, without the namepsace prefix (Type:). The optional - * parameter $findConversions can be used to prevent searching for custom + * parameter $findCustom can be used to prevent searching for custom * datatypes in cases where no built-in datatype is found. */ - static function getTypeHandlerByLabel($typelabel, $findConversions=true) { + static function getTypeHandlerByLabel($typelabel, $findCustom=true) { if (array_key_exists($typelabel,SMWTypeHandlerFactory::$typeHandlersByLabel)) { $th = SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel]; if (is_array($th)) { //instantiate the handler first @@ -159,13 +162,21 @@ return SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel]; } // Maybe a custom type? Try to find conversion factors: - if (!$findConversions) return NULL; + if (!$findCustom) return NULL; $conversionFactors = SMWTypeHandlerFactory::getConversionFactors($typelabel); if (count($conversionFactors) !== 0) { $instance = new SMWLinearTypeHandler('Type:' . $typelabel, $conversionFactors); // no localisation needed -- "Type:" is just a disamb. string in the DB SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel] = $instance; return SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel]; } + + $enumMappings = SMWTypeHandlerFactory::getEnumMappings($typelabel); + if (count($enumMappings) !== 0) { + $instance = new SMWEnumTypeHandler('Type:' . $typelabel, $enumMappings); // no localisation needed -- "Type:" is just a disamb. string in the DB + SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel] = $instance; + return SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel]; + } + return new SMWErrorTypeHandler(wfMsgForContent('smw_unknowntype',$typelabel)); } @@ -253,6 +264,32 @@ return $result; } + /** + * This method retrieves the enumeration mappings if any, for a + * given type as an array of strings. It gets them from a special + * property, e.g. if Attribute:Version HasType Type:Version, then + * Type:Version page has the enumeration mapping that we have to + * pass to an SMWMappingTypeHandler instance. + * + * @return (possibly empty) array of enumeration mapping, each a string + * @param $type should be in text form without preceding namespace. + */ + static function &getEnumMappings($type) { + global $wgContLang; + + $result = array(); + $ttitle = Title::newFromText($wgContLang->getNsText(SMW_NS_TYPE) . ':' . $type); + if ( ($ttitle !== NULL) && ($ttitle->exists()) ) { + $tprops = &smwfGetSpecialProperties($ttitle, SMW_SP_ENUM_MAP, NULL); + foreach ($tprops as $uprops) { + // uprops[2] has the value_string we want, append to array. + $result[] = $uprops[2]; + } + } + return $result; + } + + /** * This method retrieves additional service links, if any, for a * given type as an array of id strings. The ids are the back part diff -u -r /tmp/SemanticMediaWiki/includes/SMW_Settings.php SemanticMediaWiki/includes/SMW_Settings.php --- /tmp/SemanticMediaWiki/includes/SMW_Settings.php 2007-01-07 10:39:35.000000000 +0200 +++ SemanticMediaWiki/includes/SMW_Settings.php 2007-01-07 12:55:04.000000000 +0200 @@ -16,6 +16,7 @@ define('SMW_SP_EXT_SECTION',11); define('SMW_SP_CONVERSION_FACTOR', 12); define('SMW_SP_SERVICE_LINK', 13); +define('SMW_SP_ENUM_MAP', 100); // constants for displaying the factbox define('SMW_FACTBOX_HIDDEN', 1); diff -u -r /tmp/SemanticMediaWiki/languages/SMW_LanguageEn.php SemanticMediaWiki/languages/SMW_LanguageEn.php --- /tmp/SemanticMediaWiki/languages/SMW_LanguageEn.php 2007-01-07 10:39:35.000000000 +0200 +++ SemanticMediaWiki/languages/SMW_LanguageEn.php 2007-01-07 12:56:01.000000000 +0200 @@ -161,7 +161,8 @@ SMW_SP_DISPLAY_UNIT => 'Display unit', SMW_SP_IMPORTED_FROM => 'Imported from', SMW_SP_CONVERSION_FACTOR => 'Corresponds to', - SMW_SP_SERVICE_LINK => 'Provides service' + SMW_SP_SERVICE_LINK => 'Provides service', + SMW_SP_ENUM_MAP => 'Enum mapping' ); S Page wrote: > Ittay Dror wrote: > > > can i create an attribute whose type is some enumeration? > > Not yet, but you join the list of people asking for this feature. > > I should be coding better date/time handling :-) > but this is pretty straightforward; I've got an implementation working > locally and should be able to check it into SVN tomorrow if no one objects. > > > the point is to have an attribute that accepts string values, but > > still be able to create order, and use comparisons in queries. > > > > my use case is a 'product_version' attribute. I'd like for different > > components to state since what product version they exist ('since > > version 1.2'). i want then to be able to list all components for a > > given version (something like [[product_version:=<1.3]]). > > The inline query code would have to detect queries on the enumerated > datatype, look up the value_num for 1.3, and query on that. I don't > have that part working. > > > version names can be anything (e.g. 'xp'). so i want to be able to > > map them in the attribute page (or type of). then i'd assign to 1.1 > > the value of 1, to 1.2 the value of 2, to 'xp' the value of 3, etc. > > In my "keep it simple" approach, the [[Attribute:Product version]] page > would have the special property > [[possible values:=3.0,3.1,98,98SE,ME,XP,Vista]] > and each comma-separated value gets a numeric offset that you wouldn't > be able to control (or see). > > > when new versions come (incl. minor versions), i'll update the page, > > inserting the version and its sequence number (maybe bumping others) > > In my "keep it simple" approach, if you inserted a new value within > possible values, you'd have to re-edit all pages with the attribute to > update the offsets. If you really want an advanced enum type that lets > you control the numeric value of each string, how would you specify this > in wiki text? > > In another message, Ittay Dror wrote: > > can anyone please give pointers (or example code) how to > > implement as custom type (php)? > My PHP code for SMWEnumeratedTypeHandler is a combination of > SMWStringTypeHandler and SMWBooleanTypeHandler, with handling of the > special property "possible values" similar to "display units". Nothing > innovative ;-) > > Notes > ----- > I don't think there's any way to represent an enumerated type in RDF > export beyond the string XSD type. > > Although strings are the obvious case for enumeration, [[possible > values]] could also be applied to other attribute datatypes, and even to > relations. But no one's asked for that yet. > > The [[possible values]] special property will really run into the 255 > character limit for string values. But if you split the enumeration > across two [[possible value]] attributes, I don't think order is > guaranteed between them. > > -- > =S > -- =================================== Ittay Dror, Chief architect, R&D, Qlusters Inc. it...@ql... +972-3-6081994 Fax: +972-3-6081841 www.openqrm.org - Data Center Provisioning |
From: Ittay D. <it...@ql...> - 2007-01-07 19:49:45
|
oops, didn't manage the conversions right. here's the fixed SMWEnumTypeHandler: class SMWEnumTypeHandler extends SMWIntegerTypeHandler { protected $typeid; protected $mappings = array(); /** * Constructor. Since the linear type is polymorphic, a * typeid is needed to be able to retrieve the right type for * values stored in the database (where the typeid is used). */ function SMWEnumTypeHandler($typeid, $mappings = NULL) { $this->typeid = str_replace(' ', '_', $typeid); if ($mappings !== NULL) { $this->parseMappings($mappings); } } function parseMappings($mappings) { foreach ($mappings as $mapping) { list($name, $value) = explode("=", $mapping); $this->mappings[$name] = $value; } } function getID() { return $this->typeid; } function getXSDType() { return 'http://www.w3.org/2001/XMLSchema#' . $this->typeid; } function getUnits() { //no units for enum return array('STDUNIT'=>false, 'ALLUNITS'=>array()); } function processValue($enum,&$datavalue) { if (array_key_exists($enum, $this->mappings)) { $this->setValue($enum, $this->mappings[$enum], $datavalue); } else { $datavalue->setError(wfMsgForContent($enum . " is not a valid enumeration for " . $this->getID())); } return; } function setValue($enum, $value, &$datavalue) { $datavalue->setProcessedValues($enum, $value, $value); $datavalue->setPrintoutString($enum); $datavalue->addQuicksearchLink(); $datavalue->addServiceLinks($enum); } /** * This method parses the value in the XSD form that was * generated by parsing some user input. It is needed since * the XSD form must be compatible to XML, and thus does not * respect the internationalization settings. E.g. the German * input value "1,234" is translated into XSD "1.234" which, * if reparsed as a user input would be misinterpreted as 1234. * * @public */ function processXSDValue($value,$unit,&$datavalue) { $enum = array_search($value, $this->mappings); if ($enum) { $this->setValue($enum, $value, $datavalue); } else { $datavalue->setError(wfMsgForContent($value . " is not a valid enum value for " . $this->getID())); } } function isNumeric() { return TRUE; } } Ittay Dror wrote: > ok, i think i implemented this. > > the example is a bug 'severity' enumeration. > > the attribute page is: > > [[has type::Type:Severity]] > > the type pages is: > [[Enum mapping:=Blocker=7]] > [[Enum mapping:=Critical=6]] > [[Enum mapping:=Major=5]] > [[Enum mapping:=Normal=4]] > [[Enum mapping:=Minor=3]] > [[Enum mapping:=Trivial=2]] > [[Enum mapping:=Enhancement=1]] > > > then, i can do stuff like <ask>[[severity:=>Normal]]</ask> > > here is the patch > > diff -u -r /tmp/SemanticMediaWiki/includes/SMW_DT_Integer.php SemanticMediaWiki/includes/SMW_DT_Integer.php > --- /tmp/SemanticMediaWiki/includes/SMW_DT_Integer.php 2007-01-07 10:39:35.000000000 +0200 > +++ SemanticMediaWiki/includes/SMW_DT_Integer.php 2007-01-07 14:21:07.000000000 +0200 > @@ -60,4 +60,76 @@ > } > } > > -?> > \ No newline at end of file > +/** > + * Class for managing integer types. Parses whole number > + * strings and generates appropriate error messages on > + * failure. > + */ > +class SMWEnumTypeHandler extends SMWIntegerTypeHandler { > + protected $typeid; > + > + protected $mappings = array(); > + > + /** > + * Constructor. Since the linear type is polymorphic, a > + * typeid is needed to be able to retrieve the right type for > + * values stored in the database (where the typeid is used). > + */ > + function SMWEnumTypeHandler($typeid, $mappings = NULL) { > + $this->typeid = str_replace(' ', '_', $typeid); > + if ($mappings !== NULL) { > + $this->parseMappings($mappings); > + } > + } > + > + function parseMappings($mappings) { > + foreach ($mappings as $mapping) { > + list($name, $value) = explode("=", $mapping); > + $this->mappings[$name] = $value; > + } > + } > + > + function getID() { > + return $this->typeid; > + } > + > + function getXSDType() { > + return 'http://www.w3.org/2001/XMLSchema#' . $this->typeid; > + } > + > + function getUnits() { //no units for enum > + return array('STDUNIT'=>false, 'ALLUNITS'=>array()); > + } > + > + function processValue($v,&$datavalue) { > + if (array_key_exists($v, $this->mappings)) { > + $datavalue->setProcessedValues($v, $this->mappings[$v], $this->mappings[$v]); > + $datavalue->setPrintoutString($v); > + $datavalue->addQuicksearchLink(); > + $datavalue->addServiceLinks($v); > + } else { > + $datavalue->setError(wfMsgForContent($v . " is not a valid value for " . $this->getID())); > + } > + return; > + } > + > + /** > + * This method parses the value in the XSD form that was > + * generated by parsing some user input. It is needed since > + * the XSD form must be compatible to XML, and thus does not > + * respect the internationalization settings. E.g. the German > + * input value "1,234" is translated into XSD "1.234" which, > + * if reparsed as a user input would be misinterpreted as 1234. > + * > + * @public > + */ > + function processXSDValue($value,$unit,&$datavalue) { > + return $this->processValue($value . $unit, $datavalue); > + } > + > + function isNumeric() { > + return TRUE; > + } > +} > + > +?> > diff -u -r /tmp/SemanticMediaWiki/includes/SMW_Datatype.php SemanticMediaWiki/includes/SMW_Datatype.php > --- /tmp/SemanticMediaWiki/includes/SMW_Datatype.php 2007-01-07 10:39:35.000000000 +0200 > +++ SemanticMediaWiki/includes/SMW_Datatype.php 2007-01-07 14:16:26.000000000 +0200 > @@ -23,6 +23,7 @@ > * Better to only load datatype PHP files as needed!? > */ > require_once('SMW_DT_Float.php'); > +require_once('SMW_DT_Integer.php'); > > /** > * Static class for registerig and retrieving typehandlers. > @@ -129,6 +130,8 @@ > return new SMWStringTypeHandler(); > case SMW_SP_CONVERSION_FACTOR: > return new SMWStringTypeHandler(); > + case SMW_SP_ENUM_MAP: > + return new SMWStringTypeHandler(); > default: > global $smwgContLang; > $specprops = $smwgContLang->getSpecialPropertiesArray(); > @@ -141,10 +144,10 @@ > * (i.e. a localized type name), or an error type handler if the label > * is not associated with some handler. The label is usually the article > * name of the type, without the namepsace prefix (Type:). The optional > - * parameter $findConversions can be used to prevent searching for custom > + * parameter $findCustom can be used to prevent searching for custom > * datatypes in cases where no built-in datatype is found. > */ > - static function getTypeHandlerByLabel($typelabel, $findConversions=true) { > + static function getTypeHandlerByLabel($typelabel, $findCustom=true) { > if (array_key_exists($typelabel,SMWTypeHandlerFactory::$typeHandlersByLabel)) { > $th = SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel]; > if (is_array($th)) { //instantiate the handler first > @@ -159,13 +162,21 @@ > return SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel]; > } > // Maybe a custom type? Try to find conversion factors: > - if (!$findConversions) return NULL; > + if (!$findCustom) return NULL; > $conversionFactors = SMWTypeHandlerFactory::getConversionFactors($typelabel); > if (count($conversionFactors) !== 0) { > $instance = new SMWLinearTypeHandler('Type:' . $typelabel, $conversionFactors); // no localisation needed -- "Type:" is just a disamb. string in the DB > SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel] = $instance; > return SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel]; > } > + > + $enumMappings = SMWTypeHandlerFactory::getEnumMappings($typelabel); > + if (count($enumMappings) !== 0) { > + $instance = new SMWEnumTypeHandler('Type:' . $typelabel, $enumMappings); // no localisation needed -- "Type:" is just a disamb. string in the DB > + SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel] = $instance; > + return SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel]; > + } > + > return new SMWErrorTypeHandler(wfMsgForContent('smw_unknowntype',$typelabel)); > } > > @@ -253,6 +264,32 @@ > return $result; > } > > + /** > + * This method retrieves the enumeration mappings if any, for a > + * given type as an array of strings. It gets them from a special > + * property, e.g. if Attribute:Version HasType Type:Version, then > + * Type:Version page has the enumeration mapping that we have to > + * pass to an SMWMappingTypeHandler instance. > + * > + * @return (possibly empty) array of enumeration mapping, each a string > + * @param $type should be in text form without preceding namespace. > + */ > + static function &getEnumMappings($type) { > + global $wgContLang; > + > + $result = array(); > + $ttitle = Title::newFromText($wgContLang->getNsText(SMW_NS_TYPE) . ':' . $type); > + if ( ($ttitle !== NULL) && ($ttitle->exists()) ) { > + $tprops = &smwfGetSpecialProperties($ttitle, SMW_SP_ENUM_MAP, NULL); > + foreach ($tprops as $uprops) { > + // uprops[2] has the value_string we want, append to array. > + $result[] = $uprops[2]; > + } > + } > + return $result; > + } > + > + > /** > * This method retrieves additional service links, if any, for a > * given type as an array of id strings. The ids are the back part > diff -u -r /tmp/SemanticMediaWiki/includes/SMW_Settings.php SemanticMediaWiki/includes/SMW_Settings.php > --- /tmp/SemanticMediaWiki/includes/SMW_Settings.php 2007-01-07 10:39:35.000000000 +0200 > +++ SemanticMediaWiki/includes/SMW_Settings.php 2007-01-07 12:55:04.000000000 +0200 > @@ -16,6 +16,7 @@ > define('SMW_SP_EXT_SECTION',11); > define('SMW_SP_CONVERSION_FACTOR', 12); > define('SMW_SP_SERVICE_LINK', 13); > +define('SMW_SP_ENUM_MAP', 100); > > // constants for displaying the factbox > define('SMW_FACTBOX_HIDDEN', 1); > diff -u -r /tmp/SemanticMediaWiki/languages/SMW_LanguageEn.php SemanticMediaWiki/languages/SMW_LanguageEn.php > --- /tmp/SemanticMediaWiki/languages/SMW_LanguageEn.php 2007-01-07 10:39:35.000000000 +0200 > +++ SemanticMediaWiki/languages/SMW_LanguageEn.php 2007-01-07 12:56:01.000000000 +0200 > @@ -161,7 +161,8 @@ > SMW_SP_DISPLAY_UNIT => 'Display unit', > SMW_SP_IMPORTED_FROM => 'Imported from', > SMW_SP_CONVERSION_FACTOR => 'Corresponds to', > - SMW_SP_SERVICE_LINK => 'Provides service' > + SMW_SP_SERVICE_LINK => 'Provides service', > + SMW_SP_ENUM_MAP => 'Enum mapping' > ); > > > S Page wrote: >> Ittay Dror wrote: >> >> > can i create an attribute whose type is some enumeration? >> >> Not yet, but you join the list of people asking for this feature. >> >> I should be coding better date/time handling :-) >> but this is pretty straightforward; I've got an implementation working >> locally and should be able to check it into SVN tomorrow if no one objects. >> >> > the point is to have an attribute that accepts string values, but >> > still be able to create order, and use comparisons in queries. >> > >> > my use case is a 'product_version' attribute. I'd like for different >> > components to state since what product version they exist ('since >> > version 1.2'). i want then to be able to list all components for a >> > given version (something like [[product_version:=<1.3]]). >> >> The inline query code would have to detect queries on the enumerated >> datatype, look up the value_num for 1.3, and query on that. I don't >> have that part working. >> >> > version names can be anything (e.g. 'xp'). so i want to be able to >> > map them in the attribute page (or type of). then i'd assign to 1.1 >> > the value of 1, to 1.2 the value of 2, to 'xp' the value of 3, etc. >> >> In my "keep it simple" approach, the [[Attribute:Product version]] page >> would have the special property >> [[possible values:=3.0,3.1,98,98SE,ME,XP,Vista]] >> and each comma-separated value gets a numeric offset that you wouldn't >> be able to control (or see). >> >> > when new versions come (incl. minor versions), i'll update the page, >> > inserting the version and its sequence number (maybe bumping others) >> >> In my "keep it simple" approach, if you inserted a new value within >> possible values, you'd have to re-edit all pages with the attribute to >> update the offsets. If you really want an advanced enum type that lets >> you control the numeric value of each string, how would you specify this >> in wiki text? >> >> In another message, Ittay Dror wrote: >> > can anyone please give pointers (or example code) how to >> > implement as custom type (php)? >> My PHP code for SMWEnumeratedTypeHandler is a combination of >> SMWStringTypeHandler and SMWBooleanTypeHandler, with handling of the >> special property "possible values" similar to "display units". Nothing >> innovative ;-) >> >> Notes >> ----- >> I don't think there's any way to represent an enumerated type in RDF >> export beyond the string XSD type. >> >> Although strings are the obvious case for enumeration, [[possible >> values]] could also be applied to other attribute datatypes, and even to >> relations. But no one's asked for that yet. >> >> The [[possible values]] special property will really run into the 255 >> character limit for string values. But if you split the enumeration >> across two [[possible value]] attributes, I don't think order is >> guaranteed between them. >> >> -- >> =S >> > > -- =================================== Ittay Dror, Chief architect, R&D, Qlusters Inc. it...@ql... +972-3-6081994 Fax: +972-3-6081841 www.openqrm.org - Data Center Provisioning |