// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
using System.Text.RegularExpressions;
namespace System.Data {
- public sealed class DataTableReader : DbDataReader
- {
- bool _closed;
- DataTable [] _tables;
- int _current = -1;
- int _index;
- DataTable _schemaTable;
- bool _tableCleared = false;
- bool _subscribed = false;
- DataRow _rowRef;
+ public sealed class DataTableReader : DbDataReader {
+ bool _closed;
+ DataTable [] _tables;
+ int _current = -1;
+ int _index;
+ DataTable _schemaTable;
+ bool _tableCleared = false;
+ bool _subscribed = false;
+ DataRow _rowRef;
bool _schemaChanged = false;
- #region Constructors
-
- public DataTableReader (DataTable dt)
- : this (new DataTable[] {dt})
- {
- }
-
- public DataTableReader (DataTable[] dataTables)
- {
- if (dataTables == null
- || dataTables.Length <= 0)
- throw new ArgumentException ("Cannot Create DataTable. Argument Empty!");
-
- this._tables = new DataTable [dataTables.Length];
-
- for (int i = 0; i < dataTables.Length; i++)
- this._tables [i] = dataTables [i];
-
- _closed = false;
- _index = 0;
- _current = -1;
- _rowRef = null;
- _tableCleared = false;
-
- SubscribeEvents ();
- }
-
- #endregion // Constructors
-
- #region Properties
-
- public override int Depth {
- get { return 0; }
- }
-
- public override int FieldCount {
- get { return CurrentTable.Columns.Count; }
- }
-
- public override bool HasRows {
- get { return CurrentTable.Rows.Count > 0; }
- }
-
- public override bool IsClosed {
- get { return _closed; }
- }
-
- public override object this [int index] {
- get {
- Validate ();
- if (index < 0 || index >= FieldCount)
- throw new ArgumentOutOfRangeException ("index " + index + " is not in the range");
- DataRow row = CurrentRow;
- if (row.RowState == DataRowState.Deleted)
- throw new InvalidOperationException ("Deleted Row's information cannot be accessed!");
- return row [index];
- }
- }
-
- private DataTable CurrentTable
- {
- get { return _tables [_index]; }
- }
-
- private DataRow CurrentRow
- {
- get { return (DataRow) CurrentTable.Rows [_current]; }
- }
-
-
- public override object this [string name] {
- get {
- Validate ();
- DataRow row = CurrentRow;
- if (row.RowState == DataRowState.Deleted)
- throw new InvalidOperationException ("Deleted Row's information cannot be accessed!");
- return row [name];
- }
- }
-
- public override int RecordsAffected {
- get { return 0; }
- }
-
- #endregion // Properties
-
- #region Methods
-
- private void SubscribeEvents ()
- {
- if (_subscribed) // avoid subscribing multiple times
- return;
- CurrentTable.TableCleared += new DataTableClearEventHandler (OnTableCleared);
- CurrentTable.RowChanged += new DataRowChangeEventHandler (OnRowChanged);
+ #region Constructors
+
+ public DataTableReader (DataTable dt)
+ : this (new DataTable[] {dt})
+ {
+ }
+
+ public DataTableReader (DataTable[] dataTables)
+ {
+ if (dataTables == null || dataTables.Length <= 0)
+ throw new ArgumentException ("Cannot Create DataTable. Argument Empty!");
+
+ this._tables = new DataTable [dataTables.Length];
+
+ for (int i = 0; i < dataTables.Length; i++)
+ this._tables [i] = dataTables [i];
+
+ _closed = false;
+ _index = 0;
+ _current = -1;
+ _rowRef = null;
+ _tableCleared = false;
+
+ SubscribeEvents ();
+ }
+
+ #endregion // Constructors
+
+ #region Properties
+
+ public override int Depth {
+ get { return 0; }
+ }
+
+ public override int FieldCount {
+ get { return CurrentTable.Columns.Count; }
+ }
+
+ public override bool HasRows {
+ get { return CurrentTable.Rows.Count > 0; }
+ }
+
+ public override bool IsClosed {
+ get { return _closed; }
+ }
+
+ public override object this [int index] {
+ get {
+ Validate ();
+ if (index < 0 || index >= FieldCount)
+ throw new ArgumentOutOfRangeException ("index " + index + " is not in the range");
+ DataRow row = CurrentRow;
+ if (row.RowState == DataRowState.Deleted)
+ throw new InvalidOperationException ("Deleted Row's information cannot be accessed!");
+ return row [index];
+ }
+ }
+
+ private DataTable CurrentTable {
+ get { return _tables [_index]; }
+ }
+
+ private DataRow CurrentRow {
+ get { return (DataRow) CurrentTable.Rows [_current]; }
+ }
+
+
+ public override object this [string name] {
+ get {
+ Validate ();
+ DataRow row = CurrentRow;
+ if (row.RowState == DataRowState.Deleted)
+ throw new InvalidOperationException ("Deleted Row's information cannot be accessed!");
+ return row [name];
+ }
+ }
+
+ public override int RecordsAffected {
+ get { return 0; }
+ }
+
+ #endregion // Properties
+
+ #region Methods
+
+ private void SubscribeEvents ()
+ {
+ if (_subscribed) // avoid subscribing multiple times
+ return;
+ CurrentTable.TableCleared += new DataTableClearEventHandler (OnTableCleared);
+ CurrentTable.RowChanged += new DataRowChangeEventHandler (OnRowChanged);
CurrentTable.Columns.CollectionChanged += new CollectionChangeEventHandler (OnColumnCollectionChanged);
for (int i=0; i < CurrentTable.Columns.Count; ++i)
CurrentTable.Columns [i].PropertyChanged += new PropertyChangedEventHandler (OnColumnChanged);
- _subscribed = true;
+ _subscribed = true;
_schemaChanged = false;
- }
-
- private void UnsubscribeEvents ()
- {
- if (!_subscribed) // avoid un-subscribing multiple times
- return;
- CurrentTable.TableCleared -= new DataTableClearEventHandler (OnTableCleared);
- CurrentTable.RowChanged -= new DataRowChangeEventHandler (OnRowChanged);
+ }
+
+ private void UnsubscribeEvents ()
+ {
+ if (!_subscribed) // avoid un-subscribing multiple times
+ return;
+ CurrentTable.TableCleared -= new DataTableClearEventHandler (OnTableCleared);
+ CurrentTable.RowChanged -= new DataRowChangeEventHandler (OnRowChanged);
CurrentTable.Columns.CollectionChanged -= new CollectionChangeEventHandler (OnColumnCollectionChanged);
for (int i=0; i < CurrentTable.Columns.Count; ++i)
CurrentTable.Columns [i].PropertyChanged -= new PropertyChangedEventHandler (OnColumnChanged);
- _subscribed = false;
+ _subscribed = false;
_schemaChanged = false;
- }
-
- public override void Close ()
- {
- if (IsClosed)
- return;
-
- UnsubscribeEvents ();
- _closed = true;
- }
-
- public override bool GetBoolean (int i)
- {
- return (bool) GetValue (i);
- }
-
- public override byte GetByte (int i)
- {
- return (byte) GetValue (i);
- }
-
- public override long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
- {
+ }
+
+ public override void Close ()
+ {
+ if (IsClosed)
+ return;
+
+ UnsubscribeEvents ();
+ _closed = true;
+ }
+
+ public override bool GetBoolean (int i)
+ {
+ return (bool) GetValue (i);
+ }
+
+ public override byte GetByte (int i)
+ {
+ return (byte) GetValue (i);
+ }
+
+ public override long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
+ {
byte[] value = this [i] as byte[];
if (value == null)
ThrowInvalidCastException (this [i].GetType (), typeof (byte[]));
int copylen = length > value.Length ? value.Length : length;
Array.Copy (value, dataIndex, buffer, bufferIndex, copylen);
return copylen;
- }
-
- public override char GetChar (int i)
- {
- return (char) GetValue (i);
- }
-
- public override long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
- {
+ }
+
+ public override char GetChar (int i)
+ {
+ return (char) GetValue (i);
+ }
+
+ public override long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
+ {
char[] value = this [i] as char[];
if (value == null)
ThrowInvalidCastException (this [i].GetType (), typeof (char[]));
int copylen = length > value.Length ? value.Length : length;
Array.Copy (value, dataIndex, buffer, bufferIndex, copylen);
return copylen;
- }
-
- public override string GetDataTypeName (int i)
- {
- return GetFieldType (i).ToString ();
- }
-
- public override DateTime GetDateTime (int i)
- {
- return (DateTime) GetValue (i);
- }
-
- public override decimal GetDecimal (int i)
- {
- return (decimal) GetValue (i);
- }
-
- public override double GetDouble (int i)
- {
- return (double) GetValue (i);
- }
-
- public override IEnumerator GetEnumerator ()
- {
+ }
+
+ public override string GetDataTypeName (int i)
+ {
+ return GetFieldType (i).ToString ();
+ }
+
+ public override DateTime GetDateTime (int i)
+ {
+ return (DateTime) GetValue (i);
+ }
+
+ public override decimal GetDecimal (int i)
+ {
+ return (decimal) GetValue (i);
+ }
+
+ public override double GetDouble (int i)
+ {
+ return (double) GetValue (i);
+ }
+
+ public override IEnumerator GetEnumerator ()
+ {
return new DbEnumerator (this);
- }
+ }
- public override Type GetProviderSpecificFieldType (int i)
- {
+ public override Type GetProviderSpecificFieldType (int i)
+ {
return GetFieldType (i);
- }
-
- public override Type GetFieldType (int i)
- {
- ValidateClosed ();
- return CurrentTable.Columns [i].DataType;
- }
-
- public override float GetFloat (int i)
- {
- return (float) GetValue (i);
- }
-
- public override Guid GetGuid (int i)
- {
- return (Guid) GetValue (i);
- }
-
- public override short GetInt16 (int i)
- {
- return (short) GetValue (i);
- }
-
- public override int GetInt32 (int i)
- {
- return (int) GetValue (i);
- }
-
- public override long GetInt64 (int i)
- {
- return (long) GetValue (i);
- }
-
- public override string GetName (int i)
- {
+ }
+
+ public override Type GetFieldType (int i)
+ {
+ ValidateClosed ();
+ return CurrentTable.Columns [i].DataType;
+ }
+
+ public override float GetFloat (int i)
+ {
+ return (float) GetValue (i);
+ }
+
+ public override Guid GetGuid (int i)
+ {
+ return (Guid) GetValue (i);
+ }
+
+ public override short GetInt16 (int i)
+ {
+ return (short) GetValue (i);
+ }
+
+ public override int GetInt32 (int i)
+ {
+ return (int) GetValue (i);
+ }
+
+ public override long GetInt64 (int i)
+ {
+ return (long) GetValue (i);
+ }
+
+ public override string GetName (int i)
+ {
ValidateClosed ();
return CurrentTable.Columns [i].ColumnName;
- }
-
- public override int GetOrdinal (string name)
- {
+ }
+
+ public override int GetOrdinal (string name)
+ {
ValidateClosed ();
int index = CurrentTable.Columns.IndexOf (name);
if (index == -1)
- throw new ArgumentException (String.Format ("Column {0} is not found in the schema",
- name));
+ throw new ArgumentException (String.Format ("Column {0} is not found in the schema", name));
return index;
- }
+ }
- public override object GetProviderSpecificValue (int i)
- {
+ public override object GetProviderSpecificValue (int i)
+ {
return GetValue (i);
- }
+ }
- public override int GetProviderSpecificValues (object[] values)
- {
+ public override int GetProviderSpecificValues (object[] values)
+ {
return GetValues (values);
- }
-
- public override string GetString (int i)
- {
- return (string) GetValue (i);
- }
-
- public override object GetValue (int i)
- {
- return this [i];
- }
-
- public override int GetValues (object[] values)
- {
+ }
+
+ public override string GetString (int i)
+ {
+ return (string) GetValue (i);
+ }
+
+ public override object GetValue (int i)
+ {
+ return this [i];
+ }
+
+ public override int GetValues (object[] values)
+ {
Validate ();
if (CurrentRow.RowState == DataRowState.Deleted)
throw new DeletedRowInaccessibleException ("");
for (int i=0; i < count; ++i)
values [i] = CurrentRow [i];
return count;
- }
-
- public override bool IsDBNull (int i)
- {
- return GetValue (i) is DBNull;
- }
-
- public override DataTable GetSchemaTable ()
- {
+ }
+
+ public override bool IsDBNull (int i)
+ {
+ return GetValue (i) is DBNull;
+ }
+
+ public override DataTable GetSchemaTable ()
+ {
ValidateClosed ();
ValidateSchemaIntact ();
- if (_schemaTable != null)
- return _schemaTable;
-
+ if (_schemaTable != null)
+ return _schemaTable;
+
DataTable dt = new DataTable ();
- DataColumn[] cols = new DataColumn [25];
dt.Columns.Add ("ColumnName", typeof (string));
dt.Columns.Add ("ColumnOrdinal", typeof (int));
dt.Columns.Add ("ColumnSize", typeof (int));
row ["DataType"] = col.DataType;
row ["ProviderType"] = DBNull.Value; //col.ProviderType;
// ms.net doesent set this when datatype is string and maxlength = -1
- // when is this set ?
+ // when is this set ?
row ["IsLong"] = false;
row ["AllowDBNull"] = col.AllowDBNull;
row ["IsReadOnly"] = col.ReadOnly;
dt.Rows.Add (row);
}
- return _schemaTable = dt;
- }
+ return _schemaTable = dt;
+ }
- private void Validate ()
- {
+ private void Validate ()
+ {
ValidateClosed ();
- if (_index >= _tables.Length)
- throw new InvalidOperationException ("Invalid attempt to read when " +
- "no data is present");
- if (_tableCleared)
- throw new RowNotInTableException ("The table is cleared, no rows are " +
- "accessible");
+ if (_index >= _tables.Length)
+ throw new InvalidOperationException ("Invalid attempt to read when no data is present");
+ if (_tableCleared)
+ throw new RowNotInTableException ("The table is cleared, no rows are accessible");
if (_current == -1)
- throw new InvalidOperationException ("DataReader is invalid " +
- "for the DataTable");
+ throw new InvalidOperationException ("DataReader is invalid for the DataTable");
ValidateSchemaIntact ();
- }
+ }
- private void ValidateClosed ()
- {
- if (IsClosed)
- throw new InvalidOperationException ("Invalid attempt to read when " +
- "the reader is closed");
- }
+ private void ValidateClosed ()
+ {
+ if (IsClosed)
+ throw new InvalidOperationException ("Invalid attempt to read when the reader is closed");
+ }
private void ValidateSchemaIntact ()
{
void ThrowInvalidCastException (Type sourceType, Type destType)
{
- throw new InvalidCastException (String.Format ("Unable to cast object of type '{0}' to type '{1}'.",
- sourceType, destType));
- }
-
- private bool MoveNext ()
- {
- if (_index >= _tables.Length || _tableCleared)
- return false;
-
- do {
- _current++;
- } while (_current < CurrentTable.Rows.Count
- && CurrentRow.RowState == DataRowState.Deleted);
-
- _rowRef = _current < CurrentTable.Rows.Count ? CurrentRow : null;
-
- return _current < CurrentTable.Rows.Count;
-
- }
-
- public override bool NextResult ()
- {
- if ((_index + 1) >= _tables.Length) {
- UnsubscribeEvents ();
- _index = _tables.Length; // to make any attempt invalid
- return false; // end of tables.
- }
-
- UnsubscribeEvents ();
- _index++;
- _current = -1;
- _rowRef = null;
- _schemaTable = null; // force to create fresh
- _tableCleared = false;
- SubscribeEvents ();
- return true;
- }
-
- public override bool Read ()
- {
- ValidateClosed ();
- return MoveNext ();
- }
-
- #endregion // Methods
-
- #region // Event Handlers
-
+ throw new InvalidCastException (
+ String.Format ("Unable to cast object of type '{0}' to type '{1}'.", sourceType, destType));
+ }
+
+ private bool MoveNext ()
+ {
+ if (_index >= _tables.Length || _tableCleared)
+ return false;
+
+ do {
+ _current++;
+ } while (_current < CurrentTable.Rows.Count && CurrentRow.RowState == DataRowState.Deleted);
+
+ _rowRef = _current < CurrentTable.Rows.Count ? CurrentRow : null;
+
+ return _current < CurrentTable.Rows.Count;
+
+ }
+
+ public override bool NextResult ()
+ {
+ if ((_index + 1) >= _tables.Length) {
+ UnsubscribeEvents ();
+ _index = _tables.Length; // to make any attempt invalid
+ return false; // end of tables.
+ }
+
+ UnsubscribeEvents ();
+ _index++;
+ _current = -1;
+ _rowRef = null;
+ _schemaTable = null; // force to create fresh
+ _tableCleared = false;
+ SubscribeEvents ();
+ return true;
+ }
+
+ public override bool Read ()
+ {
+ ValidateClosed ();
+ return MoveNext ();
+ }
+
+ #endregion // Methods
+
+ #region // Event Handlers
+
private void OnColumnChanged (object sender, PropertyChangedEventArgs args)
{
_schemaChanged = true;
}
- private void OnColumnCollectionChanged (object sender, CollectionChangeEventArgs args)
+ private void OnColumnCollectionChanged (object sender, CollectionChangeEventArgs args)
{
_schemaChanged = true;
}
- private void OnRowChanged (object src, DataRowChangeEventArgs args)
- {
- DataRowAction action = args.Action;
- DataRow row = args.Row;
- if (action == DataRowAction.Add) {
- if (_tableCleared && _current != -1)
- return;
-
- if (_current == -1 // yet to read
- || (_current >= 0 && row.RowID > CurrentRow.RowID) // row added above
- ) {
- _tableCleared = false;
- return; // no. movement required, if row added after current.
- }
-
- _current++;
- _rowRef = CurrentRow;
-
- }
-
- if (action == DataRowAction.Commit
- && row.RowState == DataRowState.Detached) {
-
- // if i am the row deleted, move one down
- if (_rowRef == row) {
- _current --;
- _rowRef = _current >= 0 ? CurrentRow : null;
- }
-
- // if the row deleted is the last row, move down
- if (_current >= CurrentTable.Rows.Count) {
- _current--;
- _rowRef = _current >= 0 ? CurrentRow : null;
- return;
- }
-
- // deleting a row below _current moves the row one down
- if (_current > 0 && _rowRef == CurrentTable.Rows [_current-1]) {
- _current--;
- _rowRef = CurrentRow;
- return;
- }
- }
- }
-
- private void OnTableCleared (object src, DataTableClearEventArgs args)
- {
- _tableCleared = true;
- }
-
- #endregion // Event Handlers
- }
+ private void OnRowChanged (object src, DataRowChangeEventArgs args)
+ {
+ DataRowAction action = args.Action;
+ DataRow row = args.Row;
+ if (action == DataRowAction.Add) {
+ if (_tableCleared && _current != -1)
+ return;
+
+ if (_current == -1 || (_current >= 0 && row.RowID > CurrentRow.RowID)) {
+ _tableCleared = false;
+ return; // no. movement required, if row added after current.
+ }
+
+ _current++;
+ _rowRef = CurrentRow;
+ }
+
+ if (action == DataRowAction.Commit && row.RowState == DataRowState.Detached) {
+ // if i am the row deleted, move one down
+ if (_rowRef == row) {
+ _current --;
+ _rowRef = _current >= 0 ? CurrentRow : null;
+ }
+
+ // if the row deleted is the last row, move down
+ if (_current >= CurrentTable.Rows.Count) {
+ _current--;
+ _rowRef = _current >= 0 ? CurrentRow : null;
+ return;
+ }
+
+ // deleting a row below _current moves the row one down
+ if (_current > 0 && _rowRef == CurrentTable.Rows [_current-1]) {
+ _current--;
+ _rowRef = CurrentRow;
+ return;
+ }
+ }
+ }
+
+ private void OnTableCleared (object src, DataTableClearEventArgs args)
+ {
+ _tableCleared = true;
+ }
+
+ #endregion // Event Handlers
+ }
}
#endif // NET_2_0