5 // Juraj Skripsky (juraj@hotfeet.ch)
7 // (C) 2004 HotFeet GmbH (http://www.hotfeet.ch)
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
37 namespace Mono.Data.SqlExpressions {
38 internal enum ReferencedTable {
44 internal class ColumnReference : IExpression {
45 ReferencedTable refTable;
46 string relationName, columnName;
48 public ColumnReference (string columnName) : this (ReferencedTable.Self, null, columnName) {}
50 public ColumnReference (ReferencedTable refTable, string relationName, string columnName)
52 this.refTable = refTable;
53 this.relationName = relationName;
54 this.columnName = columnName;
57 public ReferencedTable ReferencedTable {
58 get { return refTable; }
61 protected DataRelation GetRelation (DataRow row)
63 DataRelationCollection relations;
64 if (relationName != null) {
65 relations = row.Table.DataSet.Relations;
66 return relations[relations.IndexOf(relationName)];
69 if (refTable == ReferencedTable.Parent)
70 relations = row.Table.ParentRelations;
72 relations = row.Table.ChildRelations;
74 if (relations.Count > 1)
75 throw new EvaluateException (String.Format (
76 "The table [{0}] is involved in more than one relation." +
77 "You must explicitly mention a relation name.",
78 row.Table.TableName));
83 public DataRow GetReferencedRow (DataRow row)
86 case ReferencedTable.Self:
90 case ReferencedTable.Parent:
91 return row.GetParentRow (GetRelation (row));
93 case ReferencedTable.Child:
94 return row.GetChildRows (GetRelation (row)) [0];
98 public DataRow[] GetReferencedRows (DataRow row)
101 case ReferencedTable.Self:
103 DataRow[] rows = new DataRow [row.Table.Rows.Count];
104 row.Table.Rows.CopyTo (rows, 0);
107 case ReferencedTable.Parent:
108 return row.GetParentRows (GetRelation (row));
110 case ReferencedTable.Child:
111 return row.GetChildRows (GetRelation (row));
115 public object[] GetValues (DataRow[] rows)
117 object[] values = new object [rows.Length];
118 for (int i = 0; i < rows.Length; i++)
119 values [i] = Unify (rows [i][columnName]);
124 private object Unify (object val) {
125 if (Numeric.IsNumeric (val))
126 return Numeric.Unify ((IConvertible)val);
128 if (val == null || val == DBNull.Value)
131 if (val is bool || val is string || val is DateTime)
137 throw new EvaluateException (String.Format ("Cannot handle data type found in column '{0}'.", columnName));
140 public object Eval (DataRow row)
142 DataRow referencedRow = GetReferencedRow (row);
143 if (referencedRow == null)
148 referencedRow._inExpressionEvaluation = true;
149 val = referencedRow [columnName];
150 referencedRow._inExpressionEvaluation = false;
151 } catch (IndexOutOfRangeException) {
152 throw new EvaluateException (String.Format ("Cannot find column [{0}].", columnName));