diff options
author | Senganal T <senga@mono-cvs.ximian.com> | 2006-02-11 13:03:26 +0300 |
---|---|---|
committer | Senganal T <senga@mono-cvs.ximian.com> | 2006-02-11 13:03:26 +0300 |
commit | f66d6296f4a2730929ff0b17da858f2435a791cd (patch) | |
tree | 40f347b440308f272bbe09ba566f830ef0edd7bf /mcs/class/System.Data/Mono.Data.SqlExpressions | |
parent | df4807294d2cb5348c2c37eab10c25c8e67a55fe (diff) |
2006-01-16 Boris Kirzner <borisk@mainsoft.com>
* Test/System.Data/DataColumnCollectionTest2.cs: added test case for index update on
column removal
2006-01-18 Boris Kirzner <borisk@mainsoft.com>
* Mono.Data.SqlExpressions/ColumnReference.cs: added column and relation lazy evaluation
and caching.
2006-01-11 Boris Kirzner <borisk@mainsoft.com>
* System.Data.Common/Index.cs: removed redundant call to RebuildIndex() in constructor.
Backporting Boris Kirzner's fixes to 1_1_13 (r55374,55636,55710)
svn path=/branches/mono-1-1-13/mcs/; revision=56788
Diffstat (limited to 'mcs/class/System.Data/Mono.Data.SqlExpressions')
-rw-r--r-- | mcs/class/System.Data/Mono.Data.SqlExpressions/ChangeLog | 4 | ||||
-rw-r--r-- | mcs/class/System.Data/Mono.Data.SqlExpressions/ColumnReference.cs | 132 |
2 files changed, 117 insertions, 19 deletions
diff --git a/mcs/class/System.Data/Mono.Data.SqlExpressions/ChangeLog b/mcs/class/System.Data/Mono.Data.SqlExpressions/ChangeLog index 237f607562c..c0f8596dc88 100644 --- a/mcs/class/System.Data/Mono.Data.SqlExpressions/ChangeLog +++ b/mcs/class/System.Data/Mono.Data.SqlExpressions/ChangeLog @@ -1,3 +1,7 @@ +2006-01-18 Boris Kirzner <borisk@mainsoft.com> + * ColumnReference.cs: added column and relation lazy evaluation + and caching. + 2006-01-09 Senganal T <tsenganal@novell.com> * Aggregation.cs * Expression.cs diff --git a/mcs/class/System.Data/Mono.Data.SqlExpressions/ColumnReference.cs b/mcs/class/System.Data/Mono.Data.SqlExpressions/ColumnReference.cs index 0cb357c0b4f..4e89b437069 100644 --- a/mcs/class/System.Data/Mono.Data.SqlExpressions/ColumnReference.cs +++ b/mcs/class/System.Data/Mono.Data.SqlExpressions/ColumnReference.cs @@ -33,6 +33,7 @@ using System; using System.Collections; using System.Data; +using System.ComponentModel; namespace Mono.Data.SqlExpressions { internal enum ReferencedTable { @@ -44,6 +45,8 @@ namespace Mono.Data.SqlExpressions { internal class ColumnReference : BaseExpression { ReferencedTable refTable; string relationName, columnName; + DataColumn _cachedColumn; + DataRelation _cachedRelation; public ColumnReference (string columnName) : this (ReferencedTable.Self, null, columnName) {} @@ -88,26 +91,55 @@ namespace Mono.Data.SqlExpressions { get { return refTable; } } - protected DataRelation GetRelation (DataRow row) + private DataRelation GetRelation (DataRow row) { - DataRelationCollection relations; - if (relationName != null) { - relations = row.Table.DataSet.Relations; - return relations[relations.IndexOf(relationName)]; + if (_cachedRelation == null) { + DataTable table = row.Table; + DataRelationCollection relations; + if (relationName != null) { + relations = table.DataSet.Relations; + _cachedRelation = relations [relations.IndexOf (relationName)]; + } + else { + if (refTable == ReferencedTable.Parent) + relations = table.ParentRelations; + else + relations = table.ChildRelations; + + if (relations.Count > 1) + throw new EvaluateException (String.Format ( + "The table [{0}] is involved in more than one relation." + + "You must explicitly mention a relation name.", + table.TableName)); + else + _cachedRelation = relations [0]; + } + _cachedRelation.DataSet.Relations.CollectionChanged += new CollectionChangeEventHandler (OnRelationRemoved); } + return _cachedRelation; + } - if (refTable == ReferencedTable.Parent) - relations = row.Table.ParentRelations; - else - relations = row.Table.ChildRelations; - - if (relations.Count > 1) - throw new EvaluateException (String.Format ( - "The table [{0}] is involved in more than one relation." + - "You must explicitly mention a relation name.", - row.Table.TableName)); - else - return relations[0]; + private DataColumn GetColumn (DataRow row) + { + if (_cachedColumn == null) { + DataTable table = row.Table; + switch (refTable) { + case ReferencedTable.Parent: + table = GetRelation (row).ParentTable; + break; + case ReferencedTable.Child: + table = GetRelation (row).ChildTable; + break; + } + + _cachedColumn = table.Columns [columnName]; + if (_cachedColumn == null) + throw new EvaluateException (String.Format ("Cannot find column [{0}].", columnName)); + + _cachedColumn.PropertyChanged += new PropertyChangedEventHandler (OnColumnPropertyChanged); + _cachedColumn.Table.Columns.CollectionChanged += new CollectionChangeEventHandler (OnColumnRemoved); + } + return _cachedColumn; } public DataRow GetReferencedRow (DataRow row) @@ -146,7 +178,7 @@ namespace Mono.Data.SqlExpressions { { object[] values = new object [rows.Length]; for (int i = 0; i < rows.Length; i++) - values [i] = Unify (rows [i][columnName]); + values [i] = Unify (rows [i][GetColumn (rows [i])]); return values; } @@ -176,7 +208,7 @@ namespace Mono.Data.SqlExpressions { object val; try { referencedRow._inExpressionEvaluation = true; - val = referencedRow [columnName]; + val = referencedRow [GetColumn (row)]; referencedRow._inExpressionEvaluation = false; } catch (IndexOutOfRangeException) { throw new EvaluateException (String.Format ("Cannot find column [{0}].", columnName)); @@ -188,5 +220,67 @@ namespace Mono.Data.SqlExpressions { { return refTable == ReferencedTable.Self && columnName == other.ColumnName; } + + private void DropCached (DataColumnCollection columnCollection, DataRelationCollection relationCollection) + { + if (_cachedColumn != null) { + // unregister column listener + _cachedColumn.PropertyChanged -= new PropertyChangedEventHandler (OnColumnPropertyChanged); + + // unregister column collection listener + if (columnCollection != null) + columnCollection.CollectionChanged -= new CollectionChangeEventHandler (OnColumnRemoved); + else if (_cachedColumn.Table != null) + _cachedColumn.Table.Columns.CollectionChanged -= new CollectionChangeEventHandler (OnColumnRemoved); + + _cachedColumn = null; + } + + if (_cachedRelation != null) { + // unregister relation collection listener + if (relationCollection != null) + relationCollection.CollectionChanged -= new CollectionChangeEventHandler (OnRelationRemoved); + else if (_cachedRelation.DataSet != null) + _cachedRelation.DataSet.Relations.CollectionChanged -= new CollectionChangeEventHandler (OnRelationRemoved); + + _cachedRelation = null; + } + } + + private void OnColumnPropertyChanged (object sender, PropertyChangedEventArgs args) + { + if (!(sender is DataColumn)) + return; + + DataColumn dc = (DataColumn) sender; + if ((dc == _cachedColumn) && args.PropertyName == "ColumnName") + DropCached (null, null); + } + + private void OnColumnRemoved (object sender, CollectionChangeEventArgs args) + { + if (!(args.Element is DataColumnCollection)) + return; + + if (args.Action != CollectionChangeAction.Remove) + return; + + DataColumnCollection columnCollection = (DataColumnCollection) args.Element; + if (_cachedColumn != null && columnCollection != null && (columnCollection.IndexOf (_cachedColumn)) == -1) + DropCached (columnCollection, null); + } + + private void OnRelationRemoved (object sender, CollectionChangeEventArgs args) + { + if (!(args.Element is DataRelationCollection)) + return; + + if (args.Action != CollectionChangeAction.Remove) + return; + + DataRelationCollection relationCollection = (DataRelationCollection) args.Element; + if (_cachedRelation != null && relationCollection != null && (relationCollection.IndexOf (_cachedRelation)) == -1) + DropCached (null, relationCollection); + } } } |