|
|
@@ -359,7 +359,9 @@ namespace System.Data {
|
|
|
|
|
|
//Unique?
|
|
|
DataTable tbl = _dataTable;
|
|
|
-
|
|
|
+ bool ignoreCase = false;
|
|
|
+ if (_dataTable.DataSet != null)
|
|
|
+ ignoreCase = !_dataTable.DataSet.CaseSensitive;
|
|
|
//TODO: Investigate other ways of speeding up the validation work below.
|
|
|
|
|
|
//validate no duplicates exists.
|
|
|
@@ -371,20 +373,31 @@ namespace System.Data {
|
|
|
DataRow[] rows = new DataRow [tbl.Rows.Count];
|
|
|
tbl.Rows.CopyTo (rows, 0);
|
|
|
|
|
|
- Array.Sort(rows, new RowsComparer(this));
|
|
|
+ Array.Sort(rows, new RowsComparer(this, ignoreCase));
|
|
|
+
|
|
|
for (int i = 0 ; i < rows.Length - 1 ; i++)
|
|
|
- {
|
|
|
- bool match = true;
|
|
|
- // check if the values in the constraints columns are equal
|
|
|
- for (int j = 0; j < _dataColumns.Length; j++)
|
|
|
- {
|
|
|
- if (!rows[i][_dataColumns[j]].Equals(rows[i + 1][_dataColumns[j]]))
|
|
|
- {
|
|
|
- match = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (match)
|
|
|
+ {
|
|
|
+ bool match = true;
|
|
|
+ // check if the values in the constraints columns are equal
|
|
|
+ for (int j = 0; j < _dataColumns.Length; j++)
|
|
|
+ {
|
|
|
+ if (_dataColumns[j].DataType == typeof(string))
|
|
|
+ {
|
|
|
+ string origVal = (string)rows[i][_dataColumns[j]];
|
|
|
+ string compVal = (string)rows[i + 1][_dataColumns[j]];
|
|
|
+ if (String.Compare(origVal, compVal, ignoreCase) != 0)
|
|
|
+ {
|
|
|
+ match = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (!rows[i][_dataColumns[j]].Equals(rows[i + 1][_dataColumns[j]]))
|
|
|
+ {
|
|
|
+ match = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (match)
|
|
|
throw new ConstraintException (String.Format ("Column '{0}' contains non-unique values", this._dataColumns[0]));
|
|
|
}
|
|
|
}
|
|
|
@@ -420,6 +433,10 @@ namespace System.Data {
|
|
|
rowVals[i] = row[_dataColumns[i], DataRowVersion.Current];
|
|
|
}
|
|
|
|
|
|
+ bool ignoreCase = false;
|
|
|
+ if (_dataTable.DataSet != null)
|
|
|
+ ignoreCase = !_dataTable.DataSet.CaseSensitive;
|
|
|
+
|
|
|
foreach(DataRow compareRow in tbl.Rows)
|
|
|
{
|
|
|
if (compareRow.RowState != DataRowState.Deleted)
|
|
|
@@ -428,13 +445,21 @@ namespace System.Data {
|
|
|
//skip if it is the same row to be validated
|
|
|
if(!row.Equals(compareRow))
|
|
|
{
|
|
|
- //FIXME: should we compare to compareRow[DataRowVersion.Current]?
|
|
|
- //FIXME: We need to compare to all columns the constraint is set to.
|
|
|
for (int i = 0; i < _dataColumns.Length; i++)
|
|
|
{
|
|
|
// if the values in the row are not equal to the values of
|
|
|
// the original row from the table we can move to the next row.
|
|
|
- if(!rowVals[i].Equals( compareRow[_dataColumns[i]]))
|
|
|
+ if (_dataColumns[i].DataType == typeof(string))
|
|
|
+ {
|
|
|
+ string origVal = (string)rowVals[i];
|
|
|
+ string compVal = (string)compareRow[_dataColumns[i]];
|
|
|
+ if (String.Compare(origVal, compVal, ignoreCase) != 0)
|
|
|
+ {
|
|
|
+ isValid = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (!rowVals[i].Equals( compareRow[_dataColumns[i]]))
|
|
|
{
|
|
|
isValid = true;
|
|
|
break;
|
|
|
@@ -467,15 +492,24 @@ namespace System.Data {
|
|
|
}
|
|
|
|
|
|
// generates a hash key for a given row based on the constraints columns.
|
|
|
- internal int CalcHashValue(DataRow row)
|
|
|
+ internal int CalcHashValue(DataRow row, bool ignoreCase)
|
|
|
{
|
|
|
object o;
|
|
|
int retVal = 0;
|
|
|
+ CaseInsensitiveHashCodeProvider ciProvider = null;
|
|
|
+ if (ignoreCase)
|
|
|
+ ciProvider = new CaseInsensitiveHashCodeProvider(_dataTable.Locale);
|
|
|
for (int i = 0; i < _dataColumns.Length; i++)
|
|
|
{
|
|
|
o = row[_dataColumns[i]];
|
|
|
if (o != null)
|
|
|
- retVal += o.GetHashCode();
|
|
|
+ {
|
|
|
+ if (ciProvider != null)
|
|
|
+ retVal += ciProvider.GetHashCode(o);
|
|
|
+ else
|
|
|
+ retVal += o.GetHashCode();
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
return retVal;
|
|
|
}
|
|
|
@@ -485,9 +519,11 @@ namespace System.Data {
|
|
|
private class RowsComparer : IComparer
|
|
|
{
|
|
|
private UniqueConstraint _uc;
|
|
|
+ private bool _ignoreCase;
|
|
|
|
|
|
- public RowsComparer(UniqueConstraint uc)
|
|
|
+ public RowsComparer(UniqueConstraint uc, bool ignoreCase)
|
|
|
{
|
|
|
+ _ignoreCase = ignoreCase;
|
|
|
_uc = uc;
|
|
|
}
|
|
|
|
|
|
@@ -495,10 +531,14 @@ namespace System.Data {
|
|
|
{
|
|
|
DataRow row1 = (DataRow) o1;
|
|
|
DataRow row2 = (DataRow) o2;
|
|
|
- int val1 = _uc.CalcHashValue(row1);
|
|
|
- int val2 = _uc.CalcHashValue(row2);
|
|
|
+ int val1 = _uc.CalcHashValue(row1, _ignoreCase);
|
|
|
+ int val2 = _uc.CalcHashValue(row2, _ignoreCase);
|
|
|
|
|
|
- return val1 - val2;
|
|
|
+ if (val1 > val2)
|
|
|
+ return 1;
|
|
|
+ if (val1 == val2)
|
|
|
+ return 0;
|
|
|
+ return -1;
|
|
|
}
|
|
|
}
|
|
|
}
|