//
using System;
using System.Collections;
+using System.Reflection;
+#if !FULL_AOT_RUNTIME
+using System.Reflection.Emit;
+#endif
namespace System.Data.Common
{
- internal abstract class DataContainer
- {
+ internal abstract class DataContainer {
BitArray null_values;
System.Type _type;
DataColumn _column;
// implementing class protocol
- protected abstract object GetValue (int index);
+ protected internal abstract object GetValue (int index);
internal abstract long GetInt64 (int index);
- protected abstract void SetDefaultValue (int index);
+ // used to set the array value to something neutral when the corresponding item is null (in the database sense)
+ // note: we don't actually ever look at the value written there, but the GC may like us to avoid keeping stale
+ // values in the array.
+ protected abstract void ZeroOut (int index);
protected abstract void SetValue (int index, object value);
protected abstract void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field);
get { return IsNull (index) ? DBNull.Value : GetValue (index); }
set {
if (value == null) {
- CopyValue (Column.Table.DefaultValuesRowIndex, index);
+ // Table might not have a default values row to copy from
+ if (Column.Table.DefaultValuesRowIndex == -1) {
+ ZeroOut (index);
+ null_values [index] = true;
+ } else {
+ CopyValue (Column.Table.DefaultValuesRowIndex, index);
+ }
return;
}
bool is_dbnull = value == DBNull.Value;
if (is_dbnull)
- SetDefaultValue (index);
+ ZeroOut (index);
else
SetValue (index, value);
null_values [index] = is_dbnull;
container = new DecimalDataContainer ();
break;
default:
- container = new ObjectDataContainer();
+ container = new ObjectDataContainer ();
break;
}
container._type = type;
return container;
}
+ internal static object GetExplicitValue (object value)
+ {
+ Type valueType = value.GetType ();
+ MethodInfo method = valueType.GetMethod ("op_Explicit", new Type[]{valueType});
+ if (method != null)
+ return (method.Invoke (value, new object[]{value}));
+ return null;
+ }
+
+ internal object GetContainerData (object value)
+ {
+ object obj;
+ TypeCode tc;
+
+ if (value == null)
+ return null;
+
+ if (_type.IsInstanceOfType (value)) {
+ return value;
+ } else if ((tc = Type.GetTypeCode (_type)) == TypeCode.String) {
+ return (Convert.ToString (value));
+ } else if (value is IConvertible) {
+ switch (tc) {
+ case TypeCode.Int16:
+ return (Convert.ToInt16 (value));
+ case TypeCode.Int32:
+ return (Convert.ToInt32 (value));
+ case TypeCode.Int64:
+ return (Convert.ToInt64 (value));
+ case TypeCode.Boolean:
+ return (Convert.ToBoolean (value));
+ case TypeCode.Byte:
+ return (Convert.ToByte (value));
+ case TypeCode.Char:
+ return (Convert.ToChar (value));
+ case TypeCode.Double:
+ return (Convert.ToDouble (value));
+ case TypeCode.SByte:
+ return (Convert.ToSByte (value));
+ case TypeCode.Single:
+ return (Convert.ToSingle (value));
+ case TypeCode.UInt16:
+ return (Convert.ToUInt16 (value));
+ case TypeCode.UInt32:
+ return (Convert.ToUInt32 (value));
+ case TypeCode.UInt64:
+ return (Convert.ToUInt64 (value));
+ case TypeCode.DateTime:
+ if (value == DBNull.Value)
+ return DBNull.Value;
+ return (Convert.ToDateTime (value));
+ case TypeCode.Decimal:
+ return (Convert.ToDecimal (value));
+ default:
+ throw new InvalidCastException (string.Format ("Cannot convert from {0} to {1}", value.GetType ().FullName, _type.FullName));
+ }
+ } else if ((obj = GetExplicitValue (value)) != null) {
+ return (obj);
+ } else {
+ throw new InvalidCastException ();
+ }
+ }
+
internal bool IsNull (int index)
{
- return null_values != null ? null_values [index] : true;
+ return null_values == null || null_values [index];
}
internal void FillValues (int fromIndex)
}
}
- sealed class BitDataContainer : DataContainer
- {
+ sealed class BitDataContainer : DataContainer {
BitArray _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = false;
}
protected override void SetValue (int index, object value)
{
- if (value is bool)
- _values [index] = (bool) value;
- else
- _values [index] = Convert.ToBoolean (value);
+ _values [index] = (bool) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((BitDataContainer)from)._values [from_index];
+ _values [to_index] = (bool) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
protected override void Resize (int size)
{
- if (_values == null) {
+ if (_values == null)
_values = new BitArray (size);
- return;
- }
-
- _values.Length = size;
+ else
+ _values.Length = size;
}
internal override long GetInt64 (int index)
}
}
- sealed class CharDataContainer : DataContainer
- {
+ sealed class CharDataContainer : DataContainer {
char [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = '\0';
}
protected override void SetValue (int index, object value)
{
- if (value is char)
- _values [index] = (char) value;
- else
- _values [index] = Convert.ToChar (value);
+ _values [index] = (char) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((CharDataContainer)from)._values [from_index];
+ _values [to_index] = (char) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class ByteDataContainer : DataContainer
- {
+ sealed class ByteDataContainer : DataContainer {
byte [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is byte)
- _values [index] = (byte) value;
- else
- _values [index] = Convert.ToByte (value);
+ _values [index] = (byte) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((ByteDataContainer)from)._values [from_index];
+ _values [to_index] = (byte) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class SByteDataContainer : DataContainer
- {
+ sealed class SByteDataContainer : DataContainer {
sbyte [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is sbyte)
- _values [index] = (sbyte) value;
- else
- _values [index] = Convert.ToSByte (value);
+ _values [index] = (sbyte) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((SByteDataContainer)from)._values [from_index];
+ _values [to_index] = (sbyte) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class Int16DataContainer : DataContainer
- {
+ sealed class Int16DataContainer : DataContainer {
short [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is short)
- _values [index] = (short) value;
- else
- _values [index] = Convert.ToInt16 (value);
+ _values [index] = (short) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((Int16DataContainer)from)._values [from_index];
+ _values [to_index] = (short) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class UInt16DataContainer : DataContainer
- {
+ sealed class UInt16DataContainer : DataContainer {
ushort [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is ushort)
- _values [index] = (ushort) value;
- else
- _values [index] = Convert.ToUInt16 (value);
+ _values [index] = (ushort) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((UInt16DataContainer)from)._values [from_index];
+ _values [to_index] = (ushort) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class Int32DataContainer : DataContainer
- {
+ sealed class Int32DataContainer : DataContainer {
int [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is int)
- _values [index] = (int) value;
- else
- _values [index] = Convert.ToInt32 (value);
+ _values [index] = (int) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((Int32DataContainer)from)._values [from_index];
+ _values [to_index] = (int) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class UInt32DataContainer : DataContainer
- {
+ sealed class UInt32DataContainer : DataContainer {
uint [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is uint)
- _values [index] = (uint) value;
- else
- _values [index] = Convert.ToUInt32 (value);
+ _values [index] = (uint) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((UInt32DataContainer)from)._values [from_index];
+ _values [to_index] = (uint) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class Int64DataContainer : DataContainer
- {
+ sealed class Int64DataContainer : DataContainer {
long [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is long)
- _values [index] = (long) value;
- else
- _values [index] = Convert.ToInt64 (value);
+ _values [index] = (long) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((Int64DataContainer)from)._values [from_index];
+ _values [to_index] = (long) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class UInt64DataContainer : DataContainer
- {
+ sealed class UInt64DataContainer : DataContainer {
ulong [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is ulong)
- _values [index] = (ulong) value;
- else
- _values [index] = Convert.ToUInt64 (value);
+ _values [index] = (ulong) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((UInt64DataContainer)from)._values [from_index];
+ _values [to_index] = (ulong) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class SingleDataContainer : DataContainer
- {
+ sealed class SingleDataContainer : DataContainer {
float [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is float)
- _values [index] = (float) value;
- else
- _values [index] = Convert.ToSingle (value);
+ _values [index] = (float) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((SingleDataContainer)from)._values [from_index];
+ _values [to_index] = (float) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class DoubleDataContainer : DataContainer
- {
+ sealed class DoubleDataContainer : DataContainer {
double [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = 0;
}
protected override void SetValue (int index, object value)
{
- if (value is double)
- _values [index] = (double) value;
- else
- _values [index] = Convert.ToDouble (value);
+ _values [index] = (double) GetContainerData (value);
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((DoubleDataContainer)from)._values [from_index];
+ _values [to_index] = (double) GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- class ObjectDataContainer : DataContainer
- {
+ class ObjectDataContainer : DataContainer {
object [] _values;
- protected override object GetValue (int index)
+ protected internal override object GetValue (int index)
{
return _values [index];
}
- protected override void SetDefaultValue (int index)
+ protected override void ZeroOut (int index)
{
_values [index] = null;
}
protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
{
- _values [to_index] = ((ObjectDataContainer)from)._values [from_index];
+ _values [to_index] = GetContainerData (from.GetValue (from_index));
}
protected override int DoCompareValues (int index1, int index2)
}
}
- sealed class DateTimeDataContainer : ObjectDataContainer
- {
+ sealed class DateTimeDataContainer : ObjectDataContainer {
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
{
base.SetValue (index, record.GetDateTimeSafe (field));
protected override void SetValue (int index, object value)
{
- base.SetValue (index, Convert.ToDateTime (value));
+ base.SetValue (index, GetContainerData (value));
}
}
- sealed class DecimalDataContainer : ObjectDataContainer
- {
+ sealed class DecimalDataContainer : ObjectDataContainer {
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
{
base.SetValue (index, record.GetDecimalSafe (field));
}
- protected override void SetValue(int index, object value)
+ protected override void SetValue (int index, object value)
{
- base.SetValue (index, Convert.ToDecimal (value));
+ base.SetValue (index, GetContainerData (value));
}
}
- sealed class StringDataContainer : ObjectDataContainer
- {
+ sealed class StringDataContainer : ObjectDataContainer {
private void SetValue (int index, string value)
{
- if (value != null && Column.MaxLength >= 0 && Column.MaxLength < value.Length )
- throw new ArgumentException("Cannot set column '" + Column.ColumnName + "' to '" + value + "'. The value violates the MaxLength limit of this column.");
+ if (value != null && Column.MaxLength >= 0 && Column.MaxLength < value.Length)
+ throw new ArgumentException ("Cannot set column '" + Column.ColumnName + "' to '" + value + "'. The value violates the MaxLength limit of this column.");
base.SetValue (index, value);
}
protected override void SetValue (int index, object value)
{
- if (value is string)
- SetValue (index, (string) value);
- else
- SetValue (index, Convert.ToString (value));
+ SetValue (index, (string) GetContainerData (value));
}
protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)