source: BMXNET_RPMS_dotNET_UTILITIES-BMX/branch/BMX41000/IHS BMX Framework/IndianHealthService.BMXNet/Ado/BMXNetDataReader.cs@ 1416

Last change on this file since 1416 was 1146, checked in by Sam Habiel, 14 years ago

Initial Import of BMX4

File size: 11.3 KB
Line 
1using System;
2using System.Data;
3using System.Globalization;
4
5namespace IndianHealthService.BMXNet.Ado
6{
7 /// <summary>
8 /// BMXNET implementaiton of IDataReader. This class can be used like
9 /// any ADO.NET IDataReader implementation or the suggested RemoteSession API's can
10 /// be used.
11 ///
12 /// See ADO.NET documentation for details of this class.
13 /// </summary>
14 public class BMXNetDataReader : IDataReader
15 {
16 // The DataReader should always be open when returned to the user.
17 private bool m_fOpen = true;
18
19 // Keep track of the results and position
20 // within the resultset (starts prior to first record).
21 private RPMSDb.RPMSDbResultSet m_resultset;
22 private static int m_STARTPOS = -1;
23 private int m_nPos = m_STARTPOS;
24
25 /*
26 * Keep track of the connection in order to implement the
27 * CommandBehavior.CloseConnection flag. A null reference means
28 * normal behavior (do not automatically close).
29 */
30 private BMXNetConnection m_connection = null;
31
32 /*
33 * Because the user should not be able to directly create a
34 * DataReader object, the constructors are
35 * marked as internal.
36 */
37 internal BMXNetDataReader(RPMSDb.RPMSDbResultSet resultset)
38 {
39 m_resultset = resultset;
40 }
41
42 internal BMXNetDataReader(RPMSDb.RPMSDbResultSet resultset, BMXNetConnection connection)
43 {
44 m_resultset = resultset;
45 m_connection = connection;
46 }
47
48 /****
49 * METHODS / PROPERTIES FROM IDataReader.
50 ****/
51 public int Depth
52 {
53 /*
54 * Always return a value of zero if nesting is not supported.
55 */
56 get { return 0; }
57 }
58
59 public bool IsClosed
60 {
61 /*
62 * Keep track of the reader state - some methods should be
63 * disallowed if the reader is closed.
64 */
65 get { return !m_fOpen; }
66 }
67
68 public int RecordsAffected
69 {
70 /*
71 * RecordsAffected is only applicable to batch statements
72 * that include inserts/updates/deletes. BMXNet always
73 * returns -1.
74 */
75 get { return -1; }
76 }
77
78 public void Close()
79 {
80 /*
81 * Close the reader. BMXNet only changes the state,
82 * but an actual implementation would also clean up any
83 * resources used by the operation. For example,
84 * cleaning up any resources waiting for data to be
85 * returned by the server.
86 */
87 m_fOpen = false;
88 }
89
90 public bool NextResult()
91 {
92 // BMXNet only returns a single resultset. However,
93 // DbDataAdapter expects NextResult to return a value.
94 return false;
95 }
96
97 public bool Read()
98 {
99 // Return true if it is possible to advance and if you are still positioned
100 // on a valid row. Because the data array in the resultset
101 // is two-dimensional, you must divide by the number of columns.
102 if (++m_nPos >= m_resultset.data.Length / m_resultset.metaData.Length)
103 return false;
104 else
105 return true;
106 }
107
108 public DataTable GetSchemaTable()
109 {
110 DataTable dtSchema = new DataTable();
111
112 dtSchema.Columns.Add("ColumnName", typeof(System.String));
113 dtSchema.Columns.Add("ColumnSize", typeof(Int32));
114 dtSchema.Columns.Add("ColumnOrdinal", typeof(Int32));
115 dtSchema.Columns.Add("NumericPrecision", typeof(Int16));
116 dtSchema.Columns.Add("NumericScale", typeof(Int16));
117 dtSchema.Columns.Add("DataType", typeof(System.Type));
118 dtSchema.Columns.Add("AllowDBNull", typeof(bool));
119 dtSchema.Columns.Add("IsReadOnly", typeof(bool));
120 dtSchema.Columns.Add("IsUnique", typeof(bool));
121 dtSchema.Columns.Add("IsRowVersion", typeof(bool));
122 dtSchema.Columns.Add("IsKey", typeof(bool));
123 dtSchema.Columns.Add("IsAutoIncrement", typeof(bool));
124 dtSchema.Columns.Add("IsLong", typeof(bool));
125 dtSchema.Columns.Add("BaseTableName", typeof(System.String));
126 dtSchema.Columns.Add("BaseColumnName", typeof(System.String));
127
128 //dtSchema.ExtendedProperties.Add("BMXTable", m_resultset.fmFileID);
129 //dtSchema.ExtendedProperties.Add("BMXKey", m_resultset.fmKeyField);
130 //dtSchema.ExtendedProperties.Add("BMXParentPath", m_resultset.fmParentPath);
131 dtSchema.ExtendedProperties["BMXTable"]= m_resultset.fmFileID;
132 dtSchema.ExtendedProperties["BMXKey"]= m_resultset.fmKeyField;
133 dtSchema.ExtendedProperties["BMXParentPath"]= m_resultset.fmParentPath;
134
135 for (int i=0; i < m_resultset.metaData.GetLength(0); i++)
136 {
137 DataRow r = dtSchema.NewRow();
138 r["BaseTableName"] = m_resultset.fmFileID;
139 r["BaseColumnName"] = m_resultset.metaData[i].fmFieldID;
140 r["ColumnName"] = m_resultset.metaData[i].name;
141 r["ColumnSize"] = m_resultset.metaData[i].maxSize;
142 r["ColumnOrdinal"] = i;
143 r["NumericPrecision"] = 0;
144 r["NumericScale"] = 0;
145 r["DataType"] = m_resultset.metaData[i].type;
146 //TODO: Look at allowing nulls in future .NET (like 3.0/3.5)
147 r["AllowDBNull"] = false;
148 r["IsReadOnly"] = m_resultset.metaData[i].fmReadOnly;
149 r["IsUnique"] = false;
150 if (m_resultset.metaData[i].name == "BMXIEN")
151 r["IsUnique"] = true;
152 r["IsRowVersion"] = false;
153 r["IsKey"] = m_resultset.metaData[i].fmKeyField;
154 r["IsAutoIncrement"] = false;
155 r["IsLong"] = false;
156
157 dtSchema.Rows.Add(r);
158 }
159 return dtSchema;
160 }
161
162 /****
163 * METHODS / PROPERTIES FROM IDataRecord.
164 ****/
165 public int FieldCount
166 {
167 // Return the count of the number of columns, which in
168 // this case is the size of the column metadata
169 // array.
170 get { return m_resultset.metaData.Length; }
171 }
172
173 public String GetName(int i)
174 {
175 return m_resultset.metaData[i].name;
176 }
177
178 public String GetDataTypeName(int i)
179 {
180 /*
181 * Usually this would return the name of the type
182 * as used on the back end, for example 'smallint' or 'varchar'.
183 * BMXNet returns the simple name of the .NET Framework type.
184 */
185 return m_resultset.metaData[i].type.Name;
186 }
187
188 public Type GetFieldType(int i)
189 {
190 // Return the actual Type class for the data type.
191 return m_resultset.metaData[i].type;
192 }
193
194 public Object GetValue(int i)
195 {
196 return m_resultset.data[m_nPos, i];
197 }
198
199 public int GetValues(object[] values)
200 {
201 int i = 0, j = 0;
202 for ( ; i < values.Length && j < m_resultset.metaData.Length; i++, j++)
203 {
204 values[i] = m_resultset.data[m_nPos, j];
205 }
206
207 return i;
208 }
209
210 public int GetOrdinal(string name)
211 {
212 // Look for the ordinal of the column with the same name and return it.
213 for (int i = 0; i < m_resultset.metaData.Length; i++)
214 {
215 if (0 == _cultureAwareCompare(name, m_resultset.metaData[i].name))
216 {
217 return i;
218 }
219 }
220
221 // Throw an exception if the ordinal cannot be found.
222 throw new IndexOutOfRangeException("Could not find specified column in results");
223 }
224
225 public object this [ int i ]
226 {
227 get { return m_resultset.data[m_nPos, i]; }
228 }
229
230 public object this [ String name ]
231 {
232 // Look up the ordinal and return
233 // the value at that position.
234 get { return this[GetOrdinal(name)]; }
235 }
236
237 public bool GetBoolean(int i)
238 {
239 /*
240 * Force the cast to return the type. InvalidCastException
241 * should be thrown if the data is not already of the correct type.
242 */
243 return (bool)m_resultset.data[m_nPos, i];
244 }
245
246 public byte GetByte(int i)
247 {
248 /*
249 * Force the cast to return the type. InvalidCastException
250 * should be thrown if the data is not already of the correct type.
251 */
252 return (byte)m_resultset.data[m_nPos, i];
253 }
254
255 public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
256 {
257 // BMXNet does not support this method.
258 throw new NotSupportedException("GetBytes not supported.");
259 }
260
261 public char GetChar(int i)
262 {
263 /*
264 * Force the cast to return the type. InvalidCastException
265 * should be thrown if the data is not already of the correct type.
266 */
267 return (char)m_resultset.data[m_nPos, i];
268 }
269
270 public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
271 {
272 // BMXNet does not support this method.
273 throw new NotSupportedException("GetChars not supported.");
274 }
275
276 public Guid GetGuid(int i)
277 {
278 /*
279 * Force the cast to return the type. InvalidCastException
280 * should be thrown if the data is not already of the correct type.
281 */
282 return (Guid)m_resultset.data[m_nPos, i];
283 }
284
285 public Int16 GetInt16(int i)
286 {
287 /*
288 * Force the cast to return the type. InvalidCastException
289 * should be thrown if the data is not already of the correct type.
290 */
291 return (Int16)m_resultset.data[m_nPos, i];
292 }
293
294 public Int32 GetInt32(int i)
295 {
296 /*
297 * Force the cast to return the type. InvalidCastException
298 * should be thrown if the data is not already of the correct type.
299 */
300 return (Int32)m_resultset.data[m_nPos, i];
301 }
302
303 public Int64 GetInt64(int i)
304 {
305 /*
306 * Force the cast to return the type. InvalidCastException
307 * should be thrown if the data is not already of the correct type.
308 */
309 return (Int64)m_resultset.data[m_nPos, i];
310 }
311
312 public float GetFloat(int i)
313 {
314 /*
315 * Force the cast to return the type. InvalidCastException
316 * should be thrown if the data is not already of the correct type.
317 */
318 return (float)m_resultset.data[m_nPos, i];
319 }
320
321 public double GetDouble(int i)
322 {
323 /*
324 * Force the cast to return the type. InvalidCastException
325 * should be thrown if the data is not already of the correct type.
326 */
327 return (double)m_resultset.data[m_nPos, i];
328 }
329
330 public String GetString(int i)
331 {
332 /*
333 * Force the cast to return the type. InvalidCastException
334 * should be thrown if the data is not already of the correct type.
335 */
336 return (String)m_resultset.data[m_nPos, i];
337 }
338
339 public Decimal GetDecimal(int i)
340 {
341 /*
342 * Force the cast to return the type. InvalidCastException
343 * should be thrown if the data is not already of the correct type.
344 */
345 return (Decimal)m_resultset.data[m_nPos, i];
346 }
347
348 public DateTime GetDateTime(int i)
349 {
350 /*
351 * Force the cast to return the type. InvalidCastException
352 * should be thrown if the data is not already of the correct type.
353 */
354 return (DateTime)m_resultset.data[m_nPos, i];
355 }
356
357 public IDataReader GetData(int i)
358 {
359 /*
360 * BMXNet code does not support this method. Need,
361 * to implement this in order to expose nested tables and
362 * other hierarchical data.
363 */
364 throw new NotSupportedException("GetData not supported.");
365 }
366
367 public bool IsDBNull(int i)
368 {
369 return m_resultset.data[m_nPos, i] == DBNull.Value;
370 }
371
372 /*
373 * Implementation specific methods.
374 */
375 private int _cultureAwareCompare(string strA, string strB)
376 {
377 return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase);
378 }
379
380 void IDisposable.Dispose()
381 {
382 this.Dispose(true);
383 System.GC.SuppressFinalize(this);
384 }
385
386 private void Dispose(bool disposing)
387 {
388 if (disposing)
389 {
390 try
391 {
392 this.Close();
393 }
394 catch (Exception e)
395 {
396 throw new SystemException("An exception of type " + e.GetType() +
397 " was encountered while closing the BMXNetDataReader.");
398 }
399 }
400 }
401
402 }
403}
Note: See TracBrowser for help on using the repository browser.