Hi folks,
here's another patch for the System.Data namespace.

Explanation: you can give a DataTable a sort string (via the Sort property) 
which can look like this: "columnName1 ASC" , "columnName1, columnName2 DESC" 
or even "columnName1 ASC, columnName2 DESC".

If you want to specify column names that contain spaces you need to "escape" 
them... by putting it inside square brackets like this: "[Column name with 
spaces]".

The problem is that if someone uses a name starting with a "[" or ending with 
a "]" as ColumnName for a DataColumn (e.g., "string2]"), and you give a 
DataTable containing such a column a sort string a la "string2] ASC" then 
Monos DataTable.ParseSortString throws an ArgumentException.

Unfortunately such a string is valid... and some developers really do name 
their columns like that (let's not discuss about that ;-)

The attached patch fixes the behaviour of DataTable.ParseSortString. It also 
allows (also valid) strings like "[string2]] ASC" (yes, I've tested against 
MS .NET to make sure something like that is valid).

C'ya,
        Marc

-- 
Marc Haisenko
Systemspezialist
Webport IT-Services GmbH
mailto: [EMAIL PROTECTED]
Index: class/System.Data/System.Data/DataTable.cs
===================================================================
--- class/System.Data/System.Data/DataTable.cs	(revision 47306)
+++ class/System.Data/System.Data/DataTable.cs	(working copy)
@@ -1878,12 +1878,42 @@
 				string[] columnExpression = sort.Trim ().Split (new char[1] {','});
 			
 				for (int c = 0; c < columnExpression.Length; c++) {
-					string[] columnSortInfo = columnExpression[c].Trim ().Split (new char[1] {' '});
+					string rawColumnName = columnExpression[c].Trim ();
+					string[] columnSortInfo;
+					
+					if (rawColumnName.StartsWith ("[") && (rawColumnName.IndexOf ("]") > 0)) {
+						// Column name is "escaped" a la "[Name with spaces]", so we can't
+						// split at spaces. We just split it manually. 
+						int i = rawColumnName.LastIndexOf ("]"); 
+
+						if (i + 1 < rawColumnName.Length) {
+							// The "]" is not the last character which means we also have
+							// an optional sort order... we extract that one and trim it.
+							columnSortInfo = new String[2];
+							columnSortInfo[1] = rawColumnName.Substring (i + 1,
+								rawColumnName.Length - i - 1).Trim ();
+						} else {
+							// The "]" is the last character, we don't have a sort order
+							columnSortInfo = new String[1];
+						}
+
+						// Get everything between leading "[" and the LAST "]", no trimming !
+						columnSortInfo[0] = rawColumnName.Substring (1, i - 1);
+					} else {
+						// No column name "escaping", just split at spaces and trim just to
+						// be sure. 
+						columnSortInfo = rawColumnName.Split (new char[1] {' '});
+
+						// Fix entries (trim strings)
+						for (int i = 0; i < columnSortInfo.Length; i++) {
+							columnSortInfo[i] = columnSortInfo[i].Trim ();
+						}
+					}
 				
-					string columnName = columnSortInfo[0].Trim ();
+					string columnName = columnSortInfo[0];
 					string sortOrder = "ASC";
 					if (columnSortInfo.Length > 1) 
-						sortOrder = columnSortInfo[1].Trim ().ToUpper (table.Locale);
+						sortOrder = columnSortInfo[1].ToUpper (table.Locale);
 					
 					ListSortDirection sortDirection = ListSortDirection.Ascending;
 					switch (sortOrder) {
@@ -1894,29 +1924,22 @@
 						sortDirection = ListSortDirection.Descending;
 						break;
 					default:
-						throw new IndexOutOfRangeException ("Could not find column: " + columnExpression[c]);
+						throw new IndexOutOfRangeException ("Could not find column: " + rawColumnName);
 					}
 
-					if (columnName.StartsWith("[") || columnName.EndsWith("]")) {
-						if (columnName.StartsWith("[") && columnName.EndsWith("]"))
-							columnName = columnName.Substring(1, columnName.Length - 2);
-						else
-							throw new ArgumentException(String.Format("{0} isn't a valid Sort string entry.", columnName));
-					}
-
 					DataColumn dc = table.Columns[columnName];
 					if (dc == null){
 						try {
 							dc = table.Columns[Int32.Parse (columnName)];
-					}
-					catch (FormatException) {
+						} catch (FormatException) {
 							throw new IndexOutOfRangeException("Cannot find column " + columnName);
+						}
 					}
-					}
 
 					columns.Add (dc);
 					sorts.Add(sortDirection);
-				}	
+				}
+
 				sortColumns = (DataColumn[]) columns.ToArray (typeof (DataColumn));
 				sortDirections = new ListSortDirection[sorts.Count];
 				for (int i = 0; i < sortDirections.Length; i++)
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to