2 using System.Collections;
4 namespace System.Data.Common
6 internal abstract class AbstractDataContainer
18 internal abstract object this[int index] {
23 internal virtual int Capacity {
25 return (_nullValues != null) ? _nullValues.Count : 0;
28 if (_nullValues == null) {
29 _nullValues = new BitArray(value);
32 _nullValues.Length = value;
43 protected DataColumn Column {
49 #endregion //Properties
53 internal static AbstractDataContainer CreateInstance(Type type, DataColumn column)
55 AbstractDataContainer container;
56 switch (Type.GetTypeCode(type)) {
58 container = new Int16DataContainer();
61 container = new Int32DataContainer();
64 container = new Int64DataContainer();
66 case TypeCode.String :
67 container = new StringDataContainer();
69 case TypeCode.Boolean:
70 container = new BitDataContainer();
73 container = new ByteDataContainer();
75 //case TypeCode.Char :
76 case TypeCode.DateTime :
77 container = new DateTimeDataContainer();
79 //case TypeCode.Decimal :
80 case TypeCode.Double :
81 container = new DoubleDataContainer();
83 //case TypeCode.SByte :
84 case TypeCode.Single :
85 container = new SingleDataContainer();
87 //case TypeCode.UInt16 :
88 //case TypeCode.UInt32 :
89 //case TypeCode.UInt64 :
91 container = new ObjectDataContainer();
94 container._type = type;
95 container._column = column;
99 internal bool IsNull(int index)
101 return (_nullValues != null) ? _nullValues[index] : true;
104 protected void SetNull(int index,bool isNull)
106 _nullValues[index] = isNull;
109 internal virtual void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
111 _nullValues[toIndex] = fromContainer._nullValues[fromIndex];
114 internal virtual void CopyValue(int fromIndex, int toIndex)
116 _nullValues[toIndex] = _nullValues[fromIndex];
119 internal virtual void SetItemFromDataRecord(int index, IDataRecord record, int field)
121 SetNull(index,record.IsDBNull(field));
124 protected int CompareNulls(int index1, int index2)
126 bool null1 = IsNull(index1);
127 bool null2 = IsNull(index2);
129 if ( null1 ^ null2 ) {
130 return null1 ? -1 : 1;
137 internal abstract int CompareValues(int index1, int index2);
141 sealed class Int16DataContainer : AbstractDataContainer
151 internal override object this[int index] {
157 return _values[index];
161 bool isDbNull = (value == DBNull.Value);
162 if (value == null || isDbNull) {
165 else if( value is short ) {
166 SetValue(index,(short)value);
169 SetValue(index,Convert.ToInt16(value));
171 SetNull(index,isDbNull);
175 internal override int Capacity {
177 base.Capacity = value;
178 if (_values == null) {
179 _values = new short[value];
182 short[] tmp = new short[value];
183 Array.Copy(_values,0,tmp,0,_values.Length);
189 #endregion //Properties
193 private void SetValue(int index, short value)
195 _values[index] = value;
198 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
200 // if exception thrown, it should be caught
201 // in the caller method
202 SetValue(index,record.GetInt16(field));
203 base.SetItemFromDataRecord(index,record,field);
206 internal override void CopyValue(int fromIndex, int toIndex)
208 base.CopyValue(fromIndex, toIndex);
209 _values[toIndex] = _values[fromIndex];
212 internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
214 base.CopyValue(fromContainer, fromIndex, toIndex);
215 _values[toIndex] = ((Int16DataContainer)fromContainer)._values[fromIndex];
218 internal override int CompareValues(int index1, int index2)
220 short s1 = _values[index1];
221 short s2 = _values[index2];
223 if ( s1 == 0 && s2 == 0 ) {
224 int cn = CompareNulls(index1, index2);
228 bool b1 = IsNull(index1);
229 bool b2 = IsNull(index2);
231 if ( s1 == 0 && b1 ) {
235 if ( s2 == 0 && b2 ) {
240 return ( s1 != s2 ) ? -1 : 0;
248 sealed class Int32DataContainer : AbstractDataContainer
258 internal override object this[int index] {
264 return _values[index];
268 bool isDbNull = (value == DBNull.Value);
269 if (value == null || isDbNull) {
272 else if( value is int ) {
273 SetValue(index,(int)value);
276 SetValue(index,Convert.ToInt32(value));
278 SetNull(index,isDbNull);
282 internal override int Capacity {
284 base.Capacity = value;
285 if (_values == null) {
286 _values = new int[value];
289 int[] tmp = new int[value];
290 Array.Copy(_values,0,tmp,0,_values.Length);
296 #endregion //Properties
300 private void SetValue(int index, int value)
302 _values[index] = value;
305 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
307 // if exception thrown, it should be caught
308 // in the caller method
309 SetValue(index,record.GetInt32(field));
310 base.SetItemFromDataRecord(index,record,field);
313 internal override void CopyValue(int fromIndex, int toIndex)
315 base.CopyValue(fromIndex, toIndex);
316 _values[toIndex] = _values[fromIndex];
319 internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
321 base.CopyValue(fromContainer, fromIndex, toIndex);
322 _values[toIndex] = ((Int32DataContainer)fromContainer)._values[fromIndex];
325 internal override int CompareValues(int index1, int index2)
327 int i1 = _values[index1];
328 int i2 = _values[index2];
330 if ( i1 == 0 && i2 == 0 ) {
331 int cn = CompareNulls(index1, index2);
335 bool b1 = IsNull(index1);
336 bool b2 = IsNull(index2);
338 if ( i1 == 0 && b1 ) {
342 if ( i2 == 0 && b2 ) {
347 return ( i1 != i2 ) ? -1 : 0;
355 sealed class Int64DataContainer : AbstractDataContainer
365 internal override object this[int index] {
371 return _values[index];
375 bool isDbNull = (value == DBNull.Value);
376 if (value == null || isDbNull) {
379 else if( value is long ) {
380 SetValue(index,(long)value);
383 SetValue(index,Convert.ToInt64(value));
385 SetNull(index,isDbNull);
389 internal override int Capacity {
391 base.Capacity = value;
392 if (_values == null) {
393 _values = new long[value];
396 long[] tmp = new long[value];
397 Array.Copy(_values,0,tmp,0,_values.Length);
403 #endregion //Properties
407 private void SetValue(int index, long value)
409 _values[index] = value;
412 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
414 // if exception thrown, it should be caught
415 // in the caller method
416 SetValue(index,record.GetInt64(field));
417 base.SetItemFromDataRecord(index,record,field);
420 internal override void CopyValue(int fromIndex, int toIndex)
422 base.CopyValue(fromIndex, toIndex);
423 _values[toIndex] = _values[fromIndex];
426 internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
428 base.CopyValue(fromContainer, fromIndex, toIndex);
429 _values[toIndex] = ((Int64DataContainer)fromContainer)._values[fromIndex];
432 internal override int CompareValues(int index1, int index2)
434 long l1 = _values[index1];
435 long l2 = _values[index2];
437 if ( l1 == 0 || l2 == 0 ) {
438 int cn = CompareNulls(index1, index2);
445 return ( l1 != l2 ) ? -1 : 0;
453 sealed class SingleDataContainer : AbstractDataContainer
463 internal override object this[int index] {
469 return _values[index];
473 bool isDbNull = (value == DBNull.Value);
474 if (value == null || isDbNull) {
477 else if( value is float ) {
478 SetValue(index,(float)value);
481 SetValue(index,Convert.ToSingle(value));
483 SetNull(index,isDbNull);
487 internal override int Capacity {
489 base.Capacity = value;
490 if (_values == null) {
491 _values = new float[value];
494 float[] tmp = new float[value];
495 Array.Copy(_values,0,tmp,0,_values.Length);
501 #endregion //Properties
505 private void SetValue(int index, float value)
507 _values[index] = value;
510 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
512 // if exception thrown, it should be caught
513 // in the caller method
514 SetValue(index,record.GetFloat(field));
515 base.SetItemFromDataRecord(index,record,field);
518 internal override void CopyValue(int fromIndex, int toIndex)
520 base.CopyValue(fromIndex, toIndex);
521 _values[toIndex] = _values[fromIndex];
524 internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
526 base.CopyValue(fromContainer, fromIndex, toIndex);
527 _values[toIndex] = ((SingleDataContainer)fromContainer)._values[fromIndex];
530 internal override int CompareValues(int index1, int index2)
532 float f1 = _values[index1];
533 float f2 = _values[index2];
535 if ( f1 == 0 || f2 == 0 ) {
536 int cn = CompareNulls(index1, index2);
543 return ( f1 != f2 ) ? -1 : 0;
551 sealed class DoubleDataContainer : AbstractDataContainer
561 internal override object this[int index] {
567 return _values[index];
571 bool isDbNull = (value == DBNull.Value);
572 if (value == null || isDbNull) {
575 else if( value is double ) {
576 SetValue(index,(double)value);
579 SetValue(index,Convert.ToDouble(value));
581 SetNull(index,isDbNull);
585 internal override int Capacity {
587 base.Capacity = value;
588 if (_values == null) {
589 _values = new double[value];
592 double[] tmp = new double[value];
593 Array.Copy(_values,0,tmp,0,_values.Length);
599 #endregion //Properties
603 private void SetValue(int index, double value)
605 _values[index] = value;
608 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
610 // if exception thrown, it should be caught
611 // in the caller method
612 SetValue(index,record.GetDouble(field));
613 base.SetItemFromDataRecord(index,record,field);
616 internal override void CopyValue(int fromIndex, int toIndex)
618 base.CopyValue(fromIndex, toIndex);
619 _values[toIndex] = _values[fromIndex];
622 internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
624 base.CopyValue(fromContainer, fromIndex, toIndex);
625 _values[toIndex] = ((DoubleDataContainer)fromContainer)._values[fromIndex];
628 internal override int CompareValues(int index1, int index2)
630 double d1 = _values[index1];
631 double d2 = _values[index2];
633 if ( d1 == 0 || d2 == 0 ) {
634 int cn = CompareNulls(index1, index2);
641 return ( d1 != d2 ) ? -1 : 0;
649 sealed class ByteDataContainer : AbstractDataContainer
659 internal override object this[int index] {
665 return _values[index];
669 bool isDbNull = (value == DBNull.Value);
670 if (value == null || isDbNull) {
673 else if( value is byte ) {
674 SetValue(index,(byte)value);
677 SetValue(index,Convert.ToByte(value));
679 SetNull(index,isDbNull);
683 internal override int Capacity {
685 base.Capacity = value;
686 if (_values == null) {
687 _values = new byte[value];
690 byte[] tmp = new byte[value];
691 Array.Copy(_values,0,tmp,0,_values.Length);
697 #endregion //Properties
701 private void SetValue(int index, byte value)
703 _values[index] = value;
706 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
708 // if exception thrown, it should be caught
709 // in the caller method
710 SetValue(index,record.GetByte(field));
711 base.SetItemFromDataRecord(index,record,field);
714 internal override void CopyValue(int fromIndex, int toIndex)
716 base.CopyValue(fromIndex, toIndex);
717 _values[toIndex] = _values[fromIndex];
720 internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
722 base.CopyValue(fromContainer, fromIndex, toIndex);
723 _values[toIndex] = ((ByteDataContainer)fromContainer)._values[fromIndex];
726 internal override int CompareValues(int index1, int index2)
728 byte b1 = _values[index1];
729 byte b2 = _values[index2];
731 if ( b1 == 0 || b2 == 0 ) {
732 int cn = CompareNulls(index1, index2);
739 return ( b1 != b2 ) ? -1 : 0;
747 sealed class BitDataContainer : AbstractDataContainer
757 internal override object this[int index] {
759 bool isNull = IsNull(index);
764 return _values[index];
768 bool isDbNull = (value == DBNull.Value);
769 if (value == null || isDbNull) {
770 SetValue(index,false);
772 else if( value is bool ) {
773 SetValue(index,(bool)value);
776 SetValue(index,Convert.ToBoolean(value));
778 SetNull(index,isDbNull);
782 internal override int Capacity {
784 base.Capacity = value;
785 if (_values == null) {
786 _values = new bool[value];
789 bool[] tmp = new bool[value];
790 Array.Copy(_values,0,tmp,0,_values.Length);
796 #endregion //Properties
800 private void SetValue(int index, bool value)
802 _values[index] = value;
805 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
807 // if exception thrown, it should be caught
808 // in the caller method
809 SetValue(index,record.GetBoolean(field));
812 internal override void CopyValue(int fromIndex, int toIndex)
814 base.CopyValue(fromIndex, toIndex);
817 internal override int CompareValues(int index1, int index2)
819 bool b1 = _values[index1];
820 bool b2 = _values[index2];
830 return CompareNulls(index1, index2);
836 class ObjectDataContainer : AbstractDataContainer
846 internal override object this[int index] {
848 return _values[index];
851 SetValue(index,value);
852 SetNull(index,value == DBNull.Value);
856 internal override int Capacity {
858 base.Capacity = value;
859 if (_values == null) {
860 _values = new object[value];
863 object[] tmp = new object[value];
864 Array.Copy(_values,0,tmp,0,_values.Length);
870 #endregion //Properties
874 protected virtual void SetValue(int index, object value)
877 value = Column.DefaultValue;
879 _values[index] = value;
882 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
884 // if exception thrown, it should be caught
885 // in the caller method
886 SetValue(index,record.GetValue(field));
887 base.SetItemFromDataRecord(index,record,field);
890 internal override void CopyValue(int fromIndex, int toIndex)
892 base.CopyValue(fromIndex, toIndex);
893 _values[toIndex] = _values[fromIndex];
896 internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
898 base.CopyValue(fromContainer, fromIndex, toIndex);
899 _values[toIndex] = ((ObjectDataContainer)fromContainer)._values[fromIndex];
902 internal override int CompareValues(int index1, int index2)
904 object obj1 = _values[index1];
905 object obj2 = _values[index2];
909 else if (obj1 is IComparable) {
911 return ((IComparable)obj1).CompareTo(obj2);
917 if (obj2 is IComparable) {
918 obj2 = Convert.ChangeType(obj2, Type.GetTypeCode(obj1.GetType()));
919 return ((IComparable)obj1).CompareTo(obj2);
923 return String.Compare(obj1.ToString(), obj2.ToString());
930 sealed class StringDataContainer : ObjectDataContainer
934 private void SetValue(int index, string value)
936 if (value != null && Column.MaxLength >= 0 && Column.MaxLength < value.Length ) {
937 throw new ArgumentException("Cannot set column '" + Column.ColumnName + "' to '" + value + "'. The value violates the MaxLength limit of this column.");
939 base.SetValue(index,value);
942 protected override void SetValue(int index, object value)
944 if ( value != null && value != DBNull.Value ) {
945 if ( value is string ) {
946 SetValue(index, (string) value);
949 SetValue(index, Convert.ToString(value));
954 base.SetValue(index, value);
957 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
959 // if exception thrown, it should be caught
960 // in the caller method
961 SetValue(index,record.GetString(field));
962 base.SetItemFromDataRecord(index,record,field);
965 internal override int CompareValues(int index1, int index2)
967 bool isNull1 = IsNull(index1);
968 bool isNull2 = IsNull(index2);
971 return isNull2 ? 0 : -1;
978 return String.Compare((string)this[index1], (string)this[index2], !Column.Table.CaseSensitive);
984 sealed class DateTimeDataContainer : ObjectDataContainer
988 protected override void SetValue(int index, object value)
990 if ( value != null && value != DBNull.Value && !(value is DateTime)) {
991 value = Convert.ToDateTime(value);
994 base.SetValue(index,value);
997 internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
999 // if exception thrown, it should be caught
1000 // in the caller method
1001 base.SetValue(index,record.GetDateTime(field));
1002 base.SetItemFromDataRecord(index,record,field);
1005 internal override int CompareValues(int index1, int index2)
1007 bool isNull1 = IsNull(index1);
1008 bool isNull2 = IsNull(index2);
1011 return isNull2 ? 0 : -1;
1018 return DateTime.Compare((DateTime)this[index1], (DateTime)this[index2]);
1021 #endregion //Methods