Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSenganal T <senga@mono-cvs.ximian.com>2006-02-11 13:03:26 +0300
committerSenganal T <senga@mono-cvs.ximian.com>2006-02-11 13:03:26 +0300
commitf66d6296f4a2730929ff0b17da858f2435a791cd (patch)
tree40f347b440308f272bbe09ba566f830ef0edd7bf /mcs/class/System.Data/Mono.Data.SqlExpressions
parentdf4807294d2cb5348c2c37eab10c25c8e67a55fe (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/ChangeLog4
-rw-r--r--mcs/class/System.Data/Mono.Data.SqlExpressions/ColumnReference.cs132
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);
+ }
}
}