2 // System.Data.Common.Key.cs
\r
5 // Boris Kirzner <borisk@mainsoft.com>
\r
6 // Konstantin Triger (kostat@mainsoft.com)
\r
10 * Copyright (c) 2002-2004 Mainsoft Corporation.
\r
12 * Permission is hereby granted, free of charge, to any person obtaining a
\r
13 * copy of this software and associated documentation files (the "Software"),
\r
14 * to deal in the Software without restriction, including without limitation
\r
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
16 * and/or sell copies of the Software, and to permit persons to whom the
\r
17 * Software is furnished to do so, subject to the following conditions:
\r
19 * The above copyright notice and this permission notice shall be included in
\r
20 * all copies or substantial portions of the Software.
\r
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
\r
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
\r
28 * DEALINGS IN THE SOFTWARE.
\r
32 using Mono.Data.SqlExpressions;
\r
33 using System.ComponentModel;
\r
35 namespace System.Data.Common
\r
42 DataColumn[] _columns;
\r
43 ListSortDirection[] _sortDirection;
\r
44 DataViewRowState _rowStateFilter;
\r
45 IExpression _filter;
\r
46 //Currently IExpression.Eval does not receive DataRowVersion
\r
47 // and always uses the _current version
\r
48 //so need a temp row for Eval calls
\r
53 #region Constructors
\r
55 internal Key(DataTable table,DataColumn[] columns,ListSortDirection[] sort, DataViewRowState rowState, IExpression filter)
\r
59 if (_filter != null)
\r
60 _tmpRow = _table.NewNotInitializedRow();
\r
62 if (sort != null && sort.Length == columns.Length) {
\r
63 _sortDirection = sort;
\r
66 _sortDirection = new ListSortDirection[columns.Length];
\r
67 for(int i=0; i < _sortDirection.Length; i++) {
\r
68 _sortDirection[i] = ListSortDirection.Ascending;
\r
72 if (rowState != DataViewRowState.None)
\r
73 _rowStateFilter = rowState;
\r
75 // FIXME : what is the correct value ?
\r
76 _rowStateFilter = DataViewRowState.CurrentRows;
\r
79 #endregion // Constructors
\r
83 internal DataColumn[] Columns
\r
90 internal DataTable Table
\r
97 ListSortDirection[] Sort
\r
100 return _sortDirection;
\r
104 internal DataViewRowState RowStateFilter
\r
107 return _rowStateFilter;
\r
111 _rowStateFilter = value;
\r
115 internal bool HasFilter
\r
117 get { return _filter != null; }
\r
120 #endregion // Properties
\r
124 internal int CompareRecords(int first, int second)
\r
126 if (first == second) {
\r
130 for(int i = 0; i < Columns.Length; i++) {
\r
132 int res = Columns[i].CompareValues(first,second);
\r
138 return (Sort[i] == ListSortDirection.Ascending) ? res : -res;
\r
143 internal int GetRecord(DataRow row)
\r
145 int index = Key.GetRecord(row,_rowStateFilter);
\r
146 if (_filter == null)
\r
152 return CanContain (index) ? index : -1;
\r
155 internal bool CanContain (int index)
\r
157 if (_filter == null)
\r
160 _tmpRow._current = index;
\r
161 return _filter.EvalBoolean(_tmpRow);
\r
164 internal bool ContainsVersion (DataRowState state, DataRowVersion version)
\r
167 case DataRowState.Unchanged:
\r
168 if ((_rowStateFilter & DataViewRowState.Unchanged) != DataViewRowState.None)
\r
169 return ((version & DataRowVersion.Default) != 0);
\r
171 case DataRowState.Added:
\r
172 if ((_rowStateFilter & DataViewRowState.Added) != DataViewRowState.None)
\r
173 return ((version & DataRowVersion.Default) != 0);
\r
175 case DataRowState.Deleted:
\r
176 if ((_rowStateFilter & DataViewRowState.Deleted) != DataViewRowState.None)
\r
177 return (version == DataRowVersion.Original);
\r
180 if ((_rowStateFilter & DataViewRowState.ModifiedCurrent) != DataViewRowState.None)
\r
181 return ((version & DataRowVersion.Default) != 0);
\r
182 if ((_rowStateFilter & DataViewRowState.ModifiedOriginal) != DataViewRowState.None)
\r
183 return (version == DataRowVersion.Original);
\r
190 internal static int GetRecord(DataRow row, DataViewRowState rowStateFilter)
\r
192 switch (row.RowState) {
\r
193 case DataRowState.Unchanged: {
\r
194 if ((rowStateFilter & DataViewRowState.Unchanged) != DataViewRowState.None)
\r
195 return row.Proposed >= 0 ? row.Proposed : row.Current;
\r
198 case DataRowState.Added: {
\r
199 if ((rowStateFilter & DataViewRowState.Added) != DataViewRowState.None)
\r
200 return row.Proposed >= 0 ? row.Proposed : row.Current;
\r
203 case DataRowState.Deleted: {
\r
204 if ((rowStateFilter & DataViewRowState.Deleted) != DataViewRowState.None)
\r
205 return row.Original;
\r
209 if ((rowStateFilter & DataViewRowState.ModifiedCurrent) != DataViewRowState.None)
\r
210 return row.Proposed >= 0 ? row.Proposed : row.Current;
\r
211 if ((rowStateFilter & DataViewRowState.ModifiedOriginal) != DataViewRowState.None)
\r
212 return row.Original;
\r
220 /// Checks for key equality to parameters set given
\r
222 /// <param name="columns">Columns the key consits of. If this parameter is null, it does not affects equality check</param>
\r
223 /// <param name="sort">Sort order of columns. If this parameter is null, it does not affects equality check</param>
\r
224 /// <param name="rowState">DataViewRowState to check for.If this parameter is null, it does not affects equality check</param>
\r
225 /// <param name="unique">Indicates whenever the index managed by this key allows non-uniqie keys to appear.</param>
\r
226 /// <param name="strict">Indicates whenever unique parameter should affect the equality check.</param>
\r
227 /// <returns></returns>
\r
228 internal bool Equals(DataColumn[] columns, ListSortDirection[] sort, DataViewRowState rowState, IExpression filter)
\r
230 if (rowState != DataViewRowState.None && RowStateFilter != rowState) {
\r
234 if (_filter != null) {
\r
235 if (!_filter.Equals (filter))
\r
238 else if (filter != null)
\r
241 if (Columns.Length != columns.Length) {
\r
245 if (sort != null && Sort.Length != sort.Length) {
\r
249 if (sort != null) {
\r
250 for(int i=0; i < columns.Length; i++) {
\r
251 if (Sort[i] != sort[i] || Columns[i] != columns[i]) {
\r
257 for(int i=0; i < columns.Length; i++) {
\r
258 if (Sort [i] != ListSortDirection.Ascending || Columns[i] != columns[i]) {
\r
266 internal bool DependsOn (DataColumn column)
\r
268 if (_filter == null)
\r
271 return _filter.DependsOn (column);
\r
274 #endregion // Methods
\r