Bug #48586 Expose defined possible enum values
Submitted: 5 Nov 2009 22:22 Modified: 10 Nov 2009 13:54
Reporter: Matt Jackson Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S4 (Feature request)
Version:6.0.3 OS:Any
Assigned to: Reggie Burnett CPU Architecture:Any
Tags: Contribution, enum

[5 Nov 2009 22:22] Matt Jackson
Description:
Background: I've been working with SubSonic and one thing I wanted was to expose the defined enum values as a .net enum without reinventing the wheel while executing DeriveParameters(MySqlCommand command) on the CommandBuilder.

I've written a patch to the source for 6.0.3 and was wandering if there was any likelyhood this could make it into any main trunk as I'm sure other users would like to have the ability.

Even better if you think it's a good patch but can optimise it to run faster and possibly in other places where something similar might be useful.

How to repeat:
execute the method DeriveParameters(MySqlCommand command) against any stored procedure and the derived parameters currently don't have any information relating to the defined possible values for any enum defined.

Suggested fix:
Index: MySql.Data/Provider/Source/CommandBuilder.cs
===================================================================
--- MySql.Data/Provider/Source/CommandBuilder.cs	(revision 1597)
+++ MySql.Data/Provider/Source/CommandBuilder.cs	(working copy)
@@ -40,6 +40,7 @@
     {
         private string finalSelect;
         private bool returnGeneratedIds;
+		private static readonly char[] EnumValueSeparater = { ',' };
 
         #region Constructors
 
@@ -129,7 +130,38 @@
                     p.Precision = Convert.ToByte(row["NUMERIC_PRECISION"]);
                 if (!row["NUMERIC_SCALE"].Equals(DBNull.Value))
                     p.Scale = Convert.ToByte(row["NUMERIC_SCALE"]);
-                command.Parameters.Add(p);
+				if (p.MySqlDbType == MySqlDbType.Enum )
+				{
+					p.MySQLEnumValues.Clear( ) ;
+					string dtdIdentifier = row[ "DTD_IDENTIFIER" ].ToString( ) ;
+					string dtdIdentifierKey = "'" ;
+
+					if ( dtdIdentifier.StartsWith( "ENUM", StringComparison.InvariantCultureIgnoreCase ) == true )
+					{
+						dtdIdentifier = dtdIdentifier.Substring( 4 ).Trim( ) ;
+					}
+					if ( dtdIdentifier.StartsWith( "(" ) == true && dtdIdentifier.EndsWith( ")" ) == true)				
+					{
+						dtdIdentifier = dtdIdentifier.Substring( 1, dtdIdentifier.Length - 2 ).Trim( );
+					}
+					dtdIdentifierKey = dtdIdentifier.Substring( 0 , 1 ) ;
+					switch(dtdIdentifierKey)
+					{
+						case "'":
+						case "\"":
+							string[] enumValues = dtdIdentifier.Split( EnumValueSeparater , StringSplitOptions.RemoveEmptyEntries );
+							string enumValue ;
+							// Apparently using a foreach loop requires building an enumerator which is excess cycles not required and the follow for loop is more effecient
+							for ( int iEnumValuesLoopCount = 0 ; iEnumValuesLoopCount < enumValues.Length ; iEnumValuesLoopCount++ )
+							{
+								enumValue = enumValues[ iEnumValuesLoopCount ];
+								enumValue = enumValue.Substring( dtdIdentifierKey.Length , enumValue.Length - ( dtdIdentifierKey.Length * 2 ) ) ;
+								p.MySQLEnumValues.Add( enumValue );
+							}
+							break;
+					}
+				}
+				command.Parameters.Add(p);
             }
         }
 
Index: MySql.Data/Provider/Source/parameter.cs
===================================================================
--- MySql.Data/Provider/Source/parameter.cs	(revision 1597)
+++ MySql.Data/Provider/Source/parameter.cs	(working copy)
@@ -19,6 +19,7 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
 using System;
+using System.Collections.Generic;
 using System.Data;
 using System.Data.Common;
 using MySql.Data.Types;
@@ -51,6 +52,7 @@
         private byte precision;
         private byte scale;
         private MySqlDbType mySqlDbType;
+    	private IList< string > mySQLEnumValues = new List< string >( ) ;
         private DbType dbType;
         private bool inferType;
         private bool sourceColumnNullMapping;
@@ -231,6 +233,14 @@
             }
         }
 
+    	public IList<string> MySQLEnumValues
+    	{
+    		get
+    		{
+    			return mySQLEnumValues ;
+    		}
+    	}
+
         /// <summary>
         /// Gets or sets the name of the MySqlParameter.
         /// </summary>
[5 Nov 2009 22:24] Matt Jackson
A possible Enum Patch to the source

Attachment: EnumPatch.patch (application/octet-stream, text), 3.22 KiB.

[6 Nov 2009 18:04] Tonci Grgin
Hi Matt and thanks for patch.

Reggie?
[9 Nov 2009 18:00] Reggie Burnett
Implemented this in 6.2.1.  

The MySqlParameter class now has a property named 'PossibleValues'.  This property  is null unless the parameter was created by MySqlCommandBuilder.DeriveParameters.  Even then it will be null unless the parameter is of type enum or set.  Then it will be a list of strings that are the possible values for the column.  This is meant as an aid to the developer.
[10 Nov 2009 13:54] Tony Bedford
A 'change' entry has been added to the 6.2.1 changelog:

The MySqlParameter class now has a property named PossibleValues. This property is NULL unless the parameter is created by MySqlCommandBuilder.DeriveParameters. Further, it will be NULL unless the parameter is of type enum or set - in this case it will be a list of strings that are the possible values for the column. This feature is designed as an aid to the developer.