2007-05-10 Nagappan A <anagappan@novell.com>
[mono.git] / mcs / class / FirebirdSql.Data.Firebird / FirebirdSql.Data.Common / RemoteEvent.cs
1 /*
2  *      Firebird ADO.NET Data provider for .NET and Mono 
3  * 
4  *         The contents of this file are subject to the Initial 
5  *         Developer's Public License Version 1.0 (the "License"); 
6  *         you may not use this file except in compliance with the 
7  *         License. You may obtain a copy of the License at 
8  *         http://www.firebirdsql.org/index.php?op=doc&id=idpl
9  *
10  *         Software distributed under the License is distributed on 
11  *         an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
12  *         express or implied. See the License for the specific 
13  *         language governing rights and limitations under the License.
14  * 
15  *      Copyright (c) 2002, 2005 Carlos Guzman Alvarez
16  *      All Rights Reserved.
17  */
18
19 using System;
20 using System.Collections.Specialized;
21
22 namespace FirebirdSql.Data.Common
23 {
24         #region Delegates
25
26         internal delegate void EventCountsCallback();
27
28         #endregion
29
30         internal class RemoteEvent
31         {
32                 #region Callbacks
33
34                 public EventCountsCallback EventCountsCallback
35                 {
36                         get { return this.eventCountsCallback; }
37                         set { this.eventCountsCallback = value; }
38                 }
39
40                 #endregion
41
42                 #region Fields
43
44                 private EventCountsCallback eventCountsCallback;
45                 private StringCollection        events;
46                 private IDatabase       db;
47                 private int                     localId;
48                 private int                     remoteId;
49                 private bool            initialCounts;
50                 private int[]           previousCounts;
51                 private int[]           actualCounts;
52
53                 #endregion
54
55                 #region Properties
56
57                 public IDatabase Database
58                 {
59                         get { return this.db; }
60                 }
61
62                 public int LocalId
63                 {
64                         get { return this.localId; }
65                         set { this.localId = value; }
66                 }
67
68                 public int RemoteId
69                 {
70                         get { return this.remoteId; }
71                         set { this.remoteId = value; }
72                 }
73
74                 public StringCollection Events
75                 {
76                         get
77                         {
78                                 if (this.events == null)
79                                 {
80                                         this.events = new StringCollection();
81                                 }
82
83                                 return this.events;
84                         }
85                 }
86
87                 public bool HasChanges
88                 {
89                         get
90                         {
91                                 if (this.actualCounts == null && this.previousCounts == null)
92                                 {
93                                         return false;
94                                 }
95                                 else if (this.actualCounts != null && this.previousCounts == null)
96                                 {
97                                         return true;
98                                 }
99                                 else if (this.actualCounts.Length != this.previousCounts.Length)
100                                 {
101                                         return true;
102                                 }
103
104                                 for (int i = 0; i < this.actualCounts.Length; i++)
105                                 {
106                                         if (this.actualCounts[i] != this.previousCounts[i])
107                                         {
108                                                 return true;
109                                         }
110                                 }
111
112                                 return false;
113                         }
114                 }
115
116                 public int[] PreviousCounts
117                 {
118                         get { return this.previousCounts; }
119                 }
120
121                 public int[] ActualCounts
122                 {
123                         get { return this.actualCounts; }
124                 }
125
126                 #endregion
127
128                 #region Constructors
129
130                 public RemoteEvent(IDatabase db) : this(db, 0, 0, null)
131                 {
132                 }
133
134                 public RemoteEvent(IDatabase db, int localId, int remoteId, StringCollection events)
135                 {
136                         this.db = db;
137                         this.localId = localId;
138                         this.remoteId = remoteId;
139                         this.events = events;
140                 }
141
142                 #endregion
143
144                 #region Methods
145
146                 public void QueueEvents()
147                 {
148                         lock (this.db)
149                         {
150                                 this.db.QueueEvents(this);
151                         }
152                 }
153
154                 public void CancelEvents()
155                 {
156                         lock (this.db)
157                         {
158                                 this.db.CancelEvents(this);
159                                 this.ResetCounts();
160                         }
161                 }
162
163                 public void ResetCounts()
164                 {
165                         this.initialCounts      = false;
166                         this.actualCounts       = null;
167                         this.previousCounts = null;
168                 }
169
170                 public void EventCounts(byte[] buffer)
171                 {
172                         int pos = 1;
173                         Charset charset = this.db.Charset;
174
175                         if (buffer != null)
176                         {
177                                 if (this.initialCounts)
178                                 {
179                                         this.previousCounts = this.actualCounts;
180                                 }
181
182                                 this.actualCounts = new int[this.events.Count];
183
184                                 while (pos < buffer.Length)
185                                 {
186                                         int length = buffer[pos++];
187                                         string eventName = charset.GetString(buffer, pos, length);
188
189                                         pos += length;
190
191                                         int index = this.events.IndexOf(eventName);
192                                         if (index != -1)
193                                         {
194                                                 this.actualCounts[index] = BitConverter.ToInt32(buffer, pos) - 1;
195                                         }
196
197                                         pos += 4;
198                                 }
199
200                                 if (!this.initialCounts)
201                                 {
202                                         this.QueueEvents();
203                                         this.initialCounts = true;
204                                 }
205                                 else
206                                 {
207                                         if (this.EventCountsCallback != null)
208                                         {
209                                                 this.EventCountsCallback();
210                                         }
211                                 }
212                         }
213                 }
214
215                 public EventParameterBuffer ToEpb()
216                 {
217                         EventParameterBuffer epb = this.db.CreateEventParameterBuffer();
218
219                         epb.Append(IscCodes.EPB_version1);
220
221                         for (int i = 0; i < this.events.Count; i++)
222                         {
223                                 if (this.actualCounts != null)
224                                 {
225                                         epb.Append(this.events[i], this.actualCounts[i] + 1);
226                                 }
227                                 else
228                                 {
229                                         epb.Append(this.events[i], 0);
230                                 }
231                         }
232
233                         return epb;
234                 }
235
236                 #endregion
237         }
238 }