You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,95 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ActivityCorrelator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common
|
||||
{
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
/// <summary>
|
||||
/// This class defines the data strucutre for ActvitiyId used for correlated tracing between client (bid trace event) and server (XEvent).
|
||||
/// It also includes all the APIs used to access the ActivityId. Note: ActivityId is thread based which is stored in TLS.
|
||||
/// </summary>
|
||||
|
||||
internal static class ActivityCorrelator
|
||||
{
|
||||
internal const Bid.ApiGroup CorrelationTracePoints = Bid.ApiGroup.Correlation;
|
||||
|
||||
internal class ActivityId
|
||||
{
|
||||
internal Guid Id { get; private set; }
|
||||
internal UInt32 Sequence { get; private set; }
|
||||
|
||||
internal ActivityId()
|
||||
{
|
||||
this.Id = Guid.NewGuid();
|
||||
this.Sequence = 0; // the first event will start 1
|
||||
}
|
||||
|
||||
// copy-constructor
|
||||
internal ActivityId(ActivityId activity)
|
||||
{
|
||||
this.Id = activity.Id;
|
||||
this.Sequence = activity.Sequence;
|
||||
}
|
||||
|
||||
internal void Increment()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
++this.Sequence;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}:{1}", this.Id, this.Sequence);
|
||||
}
|
||||
}
|
||||
|
||||
// Declare the ActivityId which will be stored in TLS. The Id is unique for each thread.
|
||||
// The Sequence number will be incremented when each event happens.
|
||||
// Correlation along threads is consistent with the current XEvent mechanisam at server.
|
||||
[ThreadStaticAttribute]
|
||||
static ActivityId tlsActivity;
|
||||
|
||||
/// <summary>
|
||||
/// Get the current ActivityId
|
||||
/// </summary>
|
||||
internal static ActivityId Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (tlsActivity == null)
|
||||
{
|
||||
tlsActivity = new ActivityId();
|
||||
}
|
||||
|
||||
return new ActivityId(tlsActivity);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increment the sequence number and generate the new ActviityId
|
||||
/// </summary>
|
||||
/// <returns>ActivityId</returns>
|
||||
internal static ActivityId Next()
|
||||
{
|
||||
if (tlsActivity == null)
|
||||
{
|
||||
tlsActivity = new ActivityId();
|
||||
}
|
||||
|
||||
tlsActivity.Increment();
|
||||
|
||||
return new ActivityId(tlsActivity);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="AdapterSwitches.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">markash</owner>
|
||||
// <owner current="true" primary="false">laled</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if DEBUG
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
internal static class AdapterSwitches {
|
||||
|
||||
static private TraceSwitch _dataSchema;
|
||||
|
||||
static internal TraceSwitch DataSchema {
|
||||
get {
|
||||
TraceSwitch dataSchema = _dataSchema;
|
||||
if (null == dataSchema) {
|
||||
_dataSchema = dataSchema = new TraceSwitch("Data.Schema", "Enable tracing for schema actions.");
|
||||
}
|
||||
return dataSchema;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1 @@
|
||||
662c1c9130d8b675f4109598e703ac7e2a22bf93
|
@@ -0,0 +1,160 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="BigIntStorage.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Numerics;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Collections;
|
||||
|
||||
internal sealed class BigIntegerStorage : DataStorage {
|
||||
|
||||
private BigInteger[] values;
|
||||
|
||||
internal BigIntegerStorage(DataColumn column)
|
||||
: base(column, typeof(BigInteger), BigInteger.Zero, StorageType.BigInteger)
|
||||
{
|
||||
}
|
||||
|
||||
override public Object Aggregate(int[] records, AggregateType kind) {
|
||||
throw ExceptionBuilder.AggregateException(kind, DataType);
|
||||
}
|
||||
|
||||
override public int Compare(int recordNo1, int recordNo2) {
|
||||
BigInteger valueNo1 = values[recordNo1];
|
||||
BigInteger valueNo2 = values[recordNo2];
|
||||
|
||||
if (valueNo1.IsZero || valueNo2.IsZero) {
|
||||
int bitCheck = CompareBits(recordNo1, recordNo2);
|
||||
if (0 != bitCheck) {
|
||||
return bitCheck;
|
||||
}
|
||||
}
|
||||
|
||||
return valueNo1.CompareTo(valueNo2);
|
||||
}
|
||||
|
||||
public override int CompareValueTo(int recordNo, object value) {
|
||||
System.Diagnostics.Debug.Assert(0 <= recordNo, "Invalid record");
|
||||
System.Diagnostics.Debug.Assert(null != value, "null value");
|
||||
|
||||
if (NullValue == value) {
|
||||
return (HasValue(recordNo) ? 1 : 0);
|
||||
}
|
||||
|
||||
BigInteger valueNo1 = values[recordNo];
|
||||
if (valueNo1.IsZero && !HasValue(recordNo)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return valueNo1.CompareTo((BigInteger)value);
|
||||
}
|
||||
|
||||
// supported implict casts
|
||||
internal static BigInteger ConvertToBigInteger(object value, IFormatProvider formatProvider) {
|
||||
if (value.GetType() == typeof(BigInteger)) { return (BigInteger)value; }
|
||||
else if (value.GetType() == typeof(String)) { return BigInteger.Parse((string)value, formatProvider); }
|
||||
else if (value.GetType() == typeof(Int64)) { return (BigInteger)(Int64)value; }
|
||||
else if (value.GetType() == typeof(Int32)) { return (BigInteger)(Int32)value; }
|
||||
else if (value.GetType() == typeof(Int16)) { return (BigInteger)(Int16)value; }
|
||||
else if (value.GetType() == typeof(SByte)) { return (BigInteger)(SByte)value; }
|
||||
else if (value.GetType() == typeof(UInt64)) { return (BigInteger)(UInt64)value; }
|
||||
else if (value.GetType() == typeof(UInt32)) { return (BigInteger)(UInt32)value; }
|
||||
else if (value.GetType() == typeof(UInt16)) { return (BigInteger)(UInt16)value; }
|
||||
else if (value.GetType() == typeof(Byte)) { return (BigInteger)(Byte)value; }
|
||||
else { throw ExceptionBuilder.ConvertFailed(value.GetType(), typeof(System.Numerics.BigInteger)); }
|
||||
}
|
||||
|
||||
internal static object ConvertFromBigInteger(BigInteger value, Type type, IFormatProvider formatProvider) {
|
||||
if (type == typeof(string)) { return value.ToString("D", formatProvider); }
|
||||
else if (type == typeof(SByte)) { return checked((SByte)value); }
|
||||
else if (type == typeof(Int16)) { return checked((Int16)value); }
|
||||
else if (type == typeof(Int32)) { return checked((Int32)value); }
|
||||
else if (type == typeof(Int64)) { return checked((Int64)value); }
|
||||
else if (type == typeof(Byte)) { return checked((Byte)value); }
|
||||
else if (type == typeof(UInt16)) { return checked((UInt16)value); }
|
||||
else if (type == typeof(UInt32)) { return checked((UInt32)value); }
|
||||
else if (type == typeof(UInt64)) { return checked((UInt64)value); }
|
||||
else if (type == typeof(Single)) { return checked((Single)value); }
|
||||
else if (type == typeof(Double)) { return checked((Double)value); }
|
||||
else if (type == typeof(Decimal)) { return checked((Decimal)value); }
|
||||
else if (type == typeof(System.Numerics.BigInteger)) { return value; }
|
||||
else { throw ExceptionBuilder.ConvertFailed(typeof(System.Numerics.BigInteger), type); }
|
||||
}
|
||||
|
||||
public override object ConvertValue(object value) {
|
||||
if (NullValue != value) {
|
||||
if (null != value) {
|
||||
value = ConvertToBigInteger(value, this.FormatProvider);
|
||||
}
|
||||
else {
|
||||
value = NullValue;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
override public void Copy(int recordNo1, int recordNo2) {
|
||||
CopyBits(recordNo1, recordNo2);
|
||||
values[recordNo2] = values[recordNo1];
|
||||
}
|
||||
|
||||
override public Object Get(int record) {
|
||||
BigInteger value = values[record];
|
||||
if (!value.IsZero) {
|
||||
return value;
|
||||
}
|
||||
return GetBits(record);
|
||||
}
|
||||
|
||||
override public void Set(int record, Object value) {
|
||||
System.Diagnostics.Debug.Assert(null != value, "null value");
|
||||
if (NullValue == value) {
|
||||
values[record] = BigInteger.Zero;
|
||||
SetNullBit(record, true);
|
||||
}
|
||||
else {
|
||||
values[record] = ConvertToBigInteger(value, this.FormatProvider);
|
||||
SetNullBit(record, false);
|
||||
}
|
||||
}
|
||||
|
||||
override public void SetCapacity(int capacity) {
|
||||
BigInteger[] newValues = new BigInteger[capacity];
|
||||
if (null != values) {
|
||||
Array.Copy(values, 0, newValues, 0, Math.Min(capacity, values.Length));
|
||||
}
|
||||
values = newValues;
|
||||
base.SetCapacity(capacity);
|
||||
}
|
||||
|
||||
override public object ConvertXmlToObject(string s) {
|
||||
return BigInteger.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
override public string ConvertObjectToXml(object value) {
|
||||
return ((BigInteger)value).ToString("D", System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
override protected object GetEmptyStorage(int recordCount) {
|
||||
return new BigInteger[recordCount];
|
||||
}
|
||||
|
||||
override protected void CopyValue(int record, object store, BitArray nullbits, int storeIndex) {
|
||||
BigInteger[] typedStore = (BigInteger[])store;
|
||||
typedStore[storeIndex] = values[record];
|
||||
nullbits.Set(storeIndex, !HasValue(record));
|
||||
}
|
||||
|
||||
override protected void SetStorage(object store, BitArray nullbits) {
|
||||
values = (BigInteger[])store;
|
||||
SetNullStorage(nullbits);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,176 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="BooleanStorage.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
// <owner current="false" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Collections;
|
||||
|
||||
internal sealed class BooleanStorage : DataStorage {
|
||||
|
||||
private const Boolean defaultValue = false;
|
||||
|
||||
private Boolean[] values;
|
||||
|
||||
internal BooleanStorage(DataColumn column)
|
||||
: base(column, typeof(Boolean), defaultValue, StorageType.Boolean) {
|
||||
}
|
||||
|
||||
override public Object Aggregate(int[] records, AggregateType kind) {
|
||||
bool hasData = false;
|
||||
try {
|
||||
switch (kind) {
|
||||
case AggregateType.Min:
|
||||
Boolean min = true;
|
||||
for (int i = 0; i < records.Length; i++) {
|
||||
int record = records[i];
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
min=values[record] && min;
|
||||
hasData = true;
|
||||
}
|
||||
if (hasData) {
|
||||
return min;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.Max:
|
||||
Boolean max = false;
|
||||
for (int i = 0; i < records.Length; i++) {
|
||||
int record = records[i];
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
max=values[record] || max;
|
||||
hasData = true;
|
||||
}
|
||||
if (hasData) {
|
||||
return max;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.First:
|
||||
if (records.Length > 0) {
|
||||
return values[records[0]];
|
||||
}
|
||||
return null;
|
||||
|
||||
case AggregateType.Count:
|
||||
return base.Aggregate(records, kind);
|
||||
|
||||
}
|
||||
}
|
||||
catch (OverflowException) {
|
||||
throw ExprException.Overflow(typeof(Boolean));
|
||||
}
|
||||
throw ExceptionBuilder.AggregateException(kind, DataType);
|
||||
}
|
||||
|
||||
override public int Compare(int recordNo1, int recordNo2) {
|
||||
Boolean valueNo1 = values[recordNo1];
|
||||
Boolean valueNo2 = values[recordNo2];
|
||||
|
||||
if (valueNo1 == defaultValue || valueNo2 == defaultValue) {
|
||||
int bitCheck = CompareBits(recordNo1, recordNo2);
|
||||
if (0 != bitCheck)
|
||||
return bitCheck;
|
||||
}
|
||||
return valueNo1.CompareTo(valueNo2);
|
||||
//return ((valueNo1 == valueNo2) ? 0 : ((false == valueNo1) ? -1 : 1)); // similar to Boolean.CompareTo(Boolean)
|
||||
}
|
||||
|
||||
public override int CompareValueTo(int recordNo, object value) {
|
||||
System.Diagnostics.Debug.Assert(0 <= recordNo, "Invalid record");
|
||||
System.Diagnostics.Debug.Assert(null != value, "null value");
|
||||
|
||||
if (NullValue == value) {
|
||||
if (IsNull(recordNo)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Boolean valueNo1 = values[recordNo];
|
||||
if ((defaultValue == valueNo1) && IsNull(recordNo)) {
|
||||
return -1;
|
||||
}
|
||||
return valueNo1.CompareTo((Boolean)value);
|
||||
//return ((valueNo1 == valueNo2) ? 0 : ((false == valueNo1) ? -1 : 1)); // similar to Boolean.CompareTo(Boolean)
|
||||
}
|
||||
|
||||
public override object ConvertValue(object value) {
|
||||
if (NullValue != value) {
|
||||
if (null != value) {
|
||||
value = ((IConvertible)value).ToBoolean(FormatProvider);
|
||||
}
|
||||
else {
|
||||
value = NullValue;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
override public void Copy(int recordNo1, int recordNo2) {
|
||||
CopyBits(recordNo1, recordNo2);
|
||||
values[recordNo2] = values[recordNo1];
|
||||
}
|
||||
|
||||
override public Object Get(int record) {
|
||||
Boolean value = values[record];
|
||||
if (value != defaultValue) {
|
||||
return value;
|
||||
}
|
||||
return GetBits(record);
|
||||
}
|
||||
|
||||
override public void Set(int record, Object value) {
|
||||
System.Diagnostics.Debug.Assert(null != value, "null value");
|
||||
if (NullValue == value) {
|
||||
values[record] = defaultValue;
|
||||
SetNullBit(record, true);
|
||||
}
|
||||
else {
|
||||
values[record] = ((IConvertible)value).ToBoolean(FormatProvider);
|
||||
SetNullBit(record, false);
|
||||
}
|
||||
}
|
||||
|
||||
override public void SetCapacity(int capacity) {
|
||||
Boolean[] newValues = new Boolean[capacity];
|
||||
if (null != values) {
|
||||
Array.Copy(values, 0, newValues, 0, Math.Min(capacity, values.Length));
|
||||
}
|
||||
values = newValues;
|
||||
base.SetCapacity(capacity);
|
||||
}
|
||||
|
||||
override public object ConvertXmlToObject(string s) {
|
||||
return XmlConvert.ToBoolean(s);
|
||||
}
|
||||
|
||||
override public string ConvertObjectToXml(object value) {
|
||||
return XmlConvert.ToString((Boolean) value);
|
||||
}
|
||||
|
||||
override protected object GetEmptyStorage(int recordCount) {
|
||||
return new Boolean[recordCount];
|
||||
}
|
||||
|
||||
override protected void CopyValue(int record, object store, BitArray nullbits, int storeIndex) {
|
||||
Boolean[] typedStore = (Boolean[]) store;
|
||||
typedStore[storeIndex] = values[record];
|
||||
nullbits.Set(storeIndex, IsNull(record));
|
||||
}
|
||||
|
||||
override protected void SetStorage(object store, BitArray nullbits) {
|
||||
values = (Boolean[]) store;
|
||||
SetNullStorage(nullbits);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,242 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ByteStorage.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
// <owner current="false" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Collections;
|
||||
|
||||
internal sealed class ByteStorage : DataStorage {
|
||||
|
||||
private const Byte defaultValue = 0;
|
||||
|
||||
private Byte[] values;
|
||||
|
||||
internal ByteStorage(DataColumn column)
|
||||
: base(column, typeof(Byte), defaultValue, StorageType.Byte) {
|
||||
}
|
||||
|
||||
override public Object Aggregate(int[] records, AggregateType kind) {
|
||||
bool hasData = false;
|
||||
try {
|
||||
switch (kind) {
|
||||
case AggregateType.Sum:
|
||||
UInt64 sum = defaultValue;
|
||||
foreach (int record in records) {
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
checked { sum += values[record];}
|
||||
hasData = true;
|
||||
}
|
||||
if (hasData) {
|
||||
return sum;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.Mean:
|
||||
Int64 meanSum = (Int64)defaultValue;
|
||||
int meanCount = 0;
|
||||
foreach (int record in records) {
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
checked { meanSum += (Int64)values[record];}
|
||||
meanCount++;
|
||||
hasData = true;
|
||||
}
|
||||
if (hasData) {
|
||||
Byte mean;
|
||||
checked {mean = (Byte)(meanSum / meanCount);}
|
||||
return mean;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.Var:
|
||||
case AggregateType.StDev:
|
||||
int count = 0;
|
||||
double var = (double)defaultValue;
|
||||
double prec = (double)defaultValue;
|
||||
double dsum = (double)defaultValue;
|
||||
double sqrsum = (double)defaultValue;
|
||||
|
||||
foreach (int record in records) {
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
dsum += (double)values[record];
|
||||
sqrsum += (double)values[record]*(double)values[record];
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count > 1) {
|
||||
var = ((double)count * sqrsum - (dsum * dsum));
|
||||
prec = var / (dsum * dsum);
|
||||
|
||||
// we are dealing with the risk of a cancellation error
|
||||
// double is guaranteed only for 15 digits so a difference
|
||||
// with a result less than 1e-15 should be considered as zero
|
||||
|
||||
if ((prec < 1e-15) || (var <0))
|
||||
var = 0;
|
||||
else
|
||||
var = var / (count * (count -1));
|
||||
|
||||
if (kind == AggregateType.StDev) {
|
||||
return Math.Sqrt(var);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.Min:
|
||||
Byte min = Byte.MaxValue;
|
||||
for (int i = 0; i < records.Length; i++) {
|
||||
int record = records[i];
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
min=Math.Min(values[record], min);
|
||||
hasData = true;
|
||||
}
|
||||
if (hasData) {
|
||||
return min;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.Max:
|
||||
Byte max = Byte.MinValue;
|
||||
for (int i = 0; i < records.Length; i++) {
|
||||
int record = records[i];
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
max=Math.Max(values[record], max);
|
||||
hasData = true;
|
||||
}
|
||||
if (hasData) {
|
||||
return max;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.First:
|
||||
if (records.Length > 0) {
|
||||
return values[records[0]];
|
||||
}
|
||||
return null;
|
||||
|
||||
case AggregateType.Count:
|
||||
return base.Aggregate(records, kind);
|
||||
|
||||
}
|
||||
}
|
||||
catch (OverflowException) {
|
||||
throw ExprException.Overflow(typeof(Byte));
|
||||
}
|
||||
throw ExceptionBuilder.AggregateException(kind, DataType);
|
||||
}
|
||||
|
||||
override public int Compare(int recordNo1, int recordNo2) {
|
||||
Byte valueNo1 = values[recordNo1];
|
||||
Byte valueNo2 = values[recordNo2];
|
||||
|
||||
if (valueNo1 == defaultValue || valueNo2 == defaultValue) {
|
||||
int bitCheck = CompareBits(recordNo1, recordNo2);
|
||||
if (0 != bitCheck)
|
||||
return bitCheck;
|
||||
}
|
||||
return valueNo1.CompareTo(valueNo2);
|
||||
//return(valueNo1 - valueNo2); // copied from Byte.CompareTo(Byte)
|
||||
}
|
||||
|
||||
public override int CompareValueTo(int recordNo, object value) {
|
||||
System.Diagnostics.Debug.Assert(0 <= recordNo, "Invalid record");
|
||||
System.Diagnostics.Debug.Assert(null != value, "null value");
|
||||
|
||||
if (NullValue == value) {
|
||||
if (IsNull(recordNo)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Byte valueNo1 = values[recordNo];
|
||||
if ((defaultValue == valueNo1) && IsNull(recordNo)) {
|
||||
return -1;
|
||||
}
|
||||
return valueNo1.CompareTo((Byte)value);
|
||||
//return(valueNo1 - valueNo2); // copied from Byte.CompareTo(Byte)
|
||||
}
|
||||
|
||||
public override object ConvertValue(object value) {
|
||||
if (NullValue != value) {
|
||||
if (null != value) {
|
||||
value = ((IConvertible)value).ToByte(FormatProvider);
|
||||
}
|
||||
else {
|
||||
value = NullValue;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
override public void Copy(int recordNo1, int recordNo2) {
|
||||
CopyBits(recordNo1, recordNo2);
|
||||
values[recordNo2] = values[recordNo1];
|
||||
}
|
||||
|
||||
override public Object Get(int record) {
|
||||
Byte value = values[record];
|
||||
if (value != defaultValue) {
|
||||
return value;
|
||||
}
|
||||
return GetBits(record);
|
||||
}
|
||||
|
||||
override public void Set(int record, Object value) {
|
||||
System.Diagnostics.Debug.Assert(null != value, "null value");
|
||||
if (NullValue == value) {
|
||||
values[record] = defaultValue;
|
||||
SetNullBit(record, true);
|
||||
}
|
||||
else {
|
||||
values[record] = ((IConvertible)value).ToByte(FormatProvider);
|
||||
SetNullBit(record, false);
|
||||
}
|
||||
}
|
||||
|
||||
override public void SetCapacity(int capacity) {
|
||||
Byte[] newValues = new Byte[capacity];
|
||||
if (null != values) {
|
||||
Array.Copy(values, 0, newValues, 0, Math.Min(capacity, values.Length));
|
||||
}
|
||||
values = newValues;
|
||||
base.SetCapacity(capacity);
|
||||
}
|
||||
|
||||
override public object ConvertXmlToObject(string s) {
|
||||
return XmlConvert.ToByte(s);
|
||||
}
|
||||
|
||||
override public string ConvertObjectToXml(object value) {
|
||||
return XmlConvert.ToString((Byte) value);
|
||||
}
|
||||
|
||||
override protected object GetEmptyStorage(int recordCount) {
|
||||
return new Byte[recordCount];
|
||||
}
|
||||
|
||||
override protected void CopyValue(int record, object store, BitArray nullbits, int storeIndex) {
|
||||
Byte[] typedStore = (Byte[]) store;
|
||||
typedStore[storeIndex] = values[record];
|
||||
nullbits.Set(storeIndex, IsNull(record));
|
||||
}
|
||||
|
||||
override protected void SetStorage(object store, BitArray nullbits) {
|
||||
values = (Byte[]) store;
|
||||
SetNullStorage(nullbits);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,180 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CharStorage.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
// <owner current="false" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Collections;
|
||||
|
||||
internal sealed class CharStorage : DataStorage {
|
||||
|
||||
private const Char defaultValue = '\0';
|
||||
|
||||
private Char[] values;
|
||||
|
||||
internal CharStorage(DataColumn column)
|
||||
: base(column, typeof(Char), defaultValue, StorageType.Char) {
|
||||
}
|
||||
|
||||
override public Object Aggregate(int[] records, AggregateType kind) {
|
||||
bool hasData = false;
|
||||
try {
|
||||
switch (kind) {
|
||||
case AggregateType.Min:
|
||||
Char min = Char.MaxValue;
|
||||
for (int i = 0; i < records.Length; i++) {
|
||||
int record = records[i];
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
min=(values[record] < min) ? values[record] : min;
|
||||
hasData = true;
|
||||
}
|
||||
if (hasData) {
|
||||
return min;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.Max:
|
||||
Char max = Char.MinValue;
|
||||
for (int i = 0; i < records.Length; i++) {
|
||||
int record = records[i];
|
||||
if (IsNull(record))
|
||||
continue;
|
||||
max=(values[record] > max) ? values[record] : max;
|
||||
hasData = true;
|
||||
}
|
||||
if (hasData) {
|
||||
return max;
|
||||
}
|
||||
return NullValue;
|
||||
|
||||
case AggregateType.First:
|
||||
if (records.Length > 0) {
|
||||
return values[records[0]];
|
||||
}
|
||||
return null;
|
||||
|
||||
case AggregateType.Count:
|
||||
return base.Aggregate(records, kind);
|
||||
|
||||
}
|
||||
}
|
||||
catch (OverflowException) {
|
||||
throw ExprException.Overflow(typeof(Char));
|
||||
}
|
||||
throw ExceptionBuilder.AggregateException(kind, DataType);
|
||||
}
|
||||
|
||||
override public int Compare(int recordNo1, int recordNo2) {
|
||||
Char valueNo1 = values[recordNo1];
|
||||
Char valueNo2 = values[recordNo2];
|
||||
|
||||
if (valueNo1 == defaultValue || valueNo2 == defaultValue) {
|
||||
int bitCheck = CompareBits(recordNo1, recordNo2);
|
||||
if (0 != bitCheck)
|
||||
return bitCheck;
|
||||
}
|
||||
return valueNo1.CompareTo(valueNo2);
|
||||
//return (valueNo1-valueNo2); // copied from Char.CompareTo(Char)
|
||||
}
|
||||
|
||||
public override int CompareValueTo(int recordNo, object value) {
|
||||
System.Diagnostics.Debug.Assert(0 <= recordNo, "Invalid record");
|
||||
System.Diagnostics.Debug.Assert(null != value, "null value");
|
||||
|
||||
if (NullValue == value) {
|
||||
if (IsNull(recordNo)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Char valueNo1 = values[recordNo];
|
||||
if ((defaultValue == valueNo1) && IsNull(recordNo)) {
|
||||
return -1;
|
||||
}
|
||||
return valueNo1.CompareTo((Char)value);
|
||||
//return (valueNo1-valueNo2); // copied from Char.CompareTo(Char)
|
||||
}
|
||||
|
||||
public override object ConvertValue(object value) {
|
||||
if (NullValue != value) {
|
||||
if (null != value) {
|
||||
value = ((IConvertible)value).ToChar(FormatProvider);
|
||||
}
|
||||
else {
|
||||
value = NullValue;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
override public void Copy(int recordNo1, int recordNo2) {
|
||||
CopyBits(recordNo1, recordNo2);
|
||||
values[recordNo2] = values[recordNo1];
|
||||
}
|
||||
|
||||
override public Object Get(int record) {
|
||||
Char value = values[record];
|
||||
if (value != defaultValue) {
|
||||
return value;
|
||||
}
|
||||
return GetBits(record);
|
||||
}
|
||||
|
||||
override public void Set(int record, Object value) {
|
||||
System.Diagnostics.Debug.Assert(null != value, "null value");
|
||||
if (NullValue == value) {
|
||||
values[record] = defaultValue;
|
||||
SetNullBit(record, true);
|
||||
}
|
||||
else {
|
||||
Char ch = ((IConvertible)value).ToChar(FormatProvider);
|
||||
if ((ch >= (char)0xd800 && ch <= (char)0xdfff) || (ch < (char)0x21 && (ch == (char)0x9 || ch == (char)0xa || ch == (char)0xd ))) {
|
||||
throw ExceptionBuilder.ProblematicChars(ch);
|
||||
}
|
||||
values[record] = ch;
|
||||
SetNullBit(record, false);
|
||||
}
|
||||
}
|
||||
|
||||
override public void SetCapacity(int capacity) {
|
||||
Char[] newValues = new Char[capacity];
|
||||
if (null != values) {
|
||||
Array.Copy(values, 0, newValues, 0, Math.Min(capacity, values.Length));
|
||||
}
|
||||
values = newValues;
|
||||
base.SetCapacity(capacity);
|
||||
}
|
||||
|
||||
override public object ConvertXmlToObject(string s) {
|
||||
return XmlConvert.ToChar(s);
|
||||
}
|
||||
|
||||
override public string ConvertObjectToXml(object value) {
|
||||
return XmlConvert.ToString((Char) value);
|
||||
}
|
||||
|
||||
override protected object GetEmptyStorage(int recordCount) {
|
||||
return new Char[recordCount];
|
||||
}
|
||||
|
||||
override protected void CopyValue(int record, object store, BitArray nullbits, int storeIndex) {
|
||||
Char[] typedStore = (Char[]) store;
|
||||
typedStore[storeIndex] = values[record];
|
||||
nullbits.Set(storeIndex, IsNull(record));
|
||||
}
|
||||
|
||||
override protected void SetStorage(object store, BitArray nullbits) {
|
||||
values = (Char[]) store;
|
||||
SetNullStorage(nullbits);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,292 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DbCommand.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
public abstract class DbCommand : Component, IDbCommand { // V1.2.3300
|
||||
protected DbCommand() : base() {
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(""),
|
||||
RefreshProperties(RefreshProperties.All),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbCommand_CommandText),
|
||||
]
|
||||
abstract public string CommandText {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbCommand_CommandTimeout),
|
||||
]
|
||||
abstract public int CommandTimeout {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(System.Data.CommandType.Text),
|
||||
RefreshProperties(RefreshProperties.All),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbCommand_CommandType),
|
||||
]
|
||||
abstract public CommandType CommandType {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DefaultValue(null),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbCommand_Connection),
|
||||
]
|
||||
public DbConnection Connection {
|
||||
get {
|
||||
return DbConnection;
|
||||
}
|
||||
set {
|
||||
DbConnection = value;
|
||||
}
|
||||
}
|
||||
|
||||
IDbConnection IDbCommand.Connection {
|
||||
get {
|
||||
return DbConnection;
|
||||
}
|
||||
set {
|
||||
DbConnection = (DbConnection)value;
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected DbConnection DbConnection { // V1.2.3300
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
abstract protected DbParameterCollection DbParameterCollection { // V1.2.3300
|
||||
get;
|
||||
}
|
||||
|
||||
abstract protected DbTransaction DbTransaction { // V1.2.3300
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
// @devnote: By default, the cmd object is visible on the design surface (i.e. VS7 Server Tray)
|
||||
// to limit the number of components that clutter the design surface,
|
||||
// when the DataAdapter design wizard generates the insert/update/delete commands it will
|
||||
// set the DesignTimeVisible property to false so that cmds won't appear as individual objects
|
||||
[
|
||||
DefaultValue(true),
|
||||
DesignOnly(true),
|
||||
Browsable(false),
|
||||
EditorBrowsableAttribute(EditorBrowsableState.Never),
|
||||
]
|
||||
public abstract bool DesignTimeVisible {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbCommand_Parameters),
|
||||
]
|
||||
public DbParameterCollection Parameters {
|
||||
get {
|
||||
return DbParameterCollection;
|
||||
}
|
||||
}
|
||||
|
||||
IDataParameterCollection IDbCommand.Parameters {
|
||||
get {
|
||||
return (DbParameterCollection)DbParameterCollection;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DefaultValue(null),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
ResDescriptionAttribute(Res.DbCommand_Transaction),
|
||||
]
|
||||
public DbTransaction Transaction {
|
||||
get {
|
||||
return DbTransaction;
|
||||
}
|
||||
set {
|
||||
DbTransaction = value;
|
||||
}
|
||||
}
|
||||
|
||||
IDbTransaction IDbCommand.Transaction {
|
||||
get {
|
||||
return DbTransaction;
|
||||
}
|
||||
set {
|
||||
DbTransaction = (DbTransaction)value;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(System.Data.UpdateRowSource.Both),
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbCommand_UpdatedRowSource),
|
||||
]
|
||||
abstract public UpdateRowSource UpdatedRowSource {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
internal void CancelIgnoreFailure() {
|
||||
// This method is used to route CancellationTokens to the Cancel method.
|
||||
// Cancellation is a suggestion, and exceptions should be ignored
|
||||
// rather than allowed to be unhandled, as there is no way to route
|
||||
// them to the caller. It would be expected that the error will be
|
||||
// observed anyway from the regular method. An example is cancelling
|
||||
// an operation on a closed connection.
|
||||
try
|
||||
{
|
||||
Cancel();
|
||||
} catch(Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
abstract public void Cancel();
|
||||
|
||||
public DbParameter CreateParameter(){ // V1.2.3300
|
||||
return CreateDbParameter();
|
||||
}
|
||||
|
||||
IDbDataParameter IDbCommand.CreateParameter() { // V1.2.3300
|
||||
return CreateDbParameter();
|
||||
}
|
||||
|
||||
abstract protected DbParameter CreateDbParameter();
|
||||
|
||||
abstract protected DbDataReader ExecuteDbDataReader(CommandBehavior behavior);
|
||||
|
||||
abstract public int ExecuteNonQuery();
|
||||
|
||||
public DbDataReader ExecuteReader() {
|
||||
return (DbDataReader)ExecuteDbDataReader(CommandBehavior.Default);
|
||||
}
|
||||
|
||||
IDataReader IDbCommand.ExecuteReader() {
|
||||
return (DbDataReader)ExecuteDbDataReader(CommandBehavior.Default);
|
||||
}
|
||||
|
||||
public DbDataReader ExecuteReader(CommandBehavior behavior){
|
||||
return (DbDataReader)ExecuteDbDataReader(behavior);
|
||||
}
|
||||
|
||||
IDataReader IDbCommand.ExecuteReader(CommandBehavior behavior) {
|
||||
return (DbDataReader)ExecuteDbDataReader(behavior);
|
||||
}
|
||||
|
||||
public Task<int> ExecuteNonQueryAsync() {
|
||||
return ExecuteNonQueryAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public virtual Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken) {
|
||||
if (cancellationToken.IsCancellationRequested) {
|
||||
return ADP.CreatedTaskWithCancellation<int>();
|
||||
}
|
||||
else {
|
||||
CancellationTokenRegistration registration = new CancellationTokenRegistration();
|
||||
if (cancellationToken.CanBeCanceled) {
|
||||
registration = cancellationToken.Register(CancelIgnoreFailure);
|
||||
}
|
||||
|
||||
try {
|
||||
return Task.FromResult<int>(ExecuteNonQuery());
|
||||
}
|
||||
catch (Exception e) {
|
||||
registration.Dispose();
|
||||
return ADP.CreatedTaskWithException<int>(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task<DbDataReader> ExecuteReaderAsync() {
|
||||
return ExecuteReaderAsync(CommandBehavior.Default, CancellationToken.None);
|
||||
}
|
||||
|
||||
public Task<DbDataReader> ExecuteReaderAsync(CancellationToken cancellationToken) {
|
||||
return ExecuteReaderAsync(CommandBehavior.Default, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<DbDataReader> ExecuteReaderAsync(CommandBehavior behavior) {
|
||||
return ExecuteReaderAsync(behavior, CancellationToken.None);
|
||||
}
|
||||
|
||||
public Task<DbDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) {
|
||||
return ExecuteDbDataReaderAsync(behavior, cancellationToken);
|
||||
}
|
||||
|
||||
protected virtual Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) {
|
||||
if (cancellationToken.IsCancellationRequested) {
|
||||
return ADP.CreatedTaskWithCancellation<DbDataReader>();
|
||||
}
|
||||
else {
|
||||
CancellationTokenRegistration registration = new CancellationTokenRegistration();
|
||||
if (cancellationToken.CanBeCanceled) {
|
||||
registration = cancellationToken.Register(CancelIgnoreFailure);
|
||||
}
|
||||
|
||||
try {
|
||||
return Task.FromResult<DbDataReader>(ExecuteReader(behavior));
|
||||
}
|
||||
catch (Exception e) {
|
||||
registration.Dispose();
|
||||
return ADP.CreatedTaskWithException<DbDataReader>(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task<object> ExecuteScalarAsync() {
|
||||
return ExecuteScalarAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public virtual Task<object> ExecuteScalarAsync(CancellationToken cancellationToken) {
|
||||
if (cancellationToken.IsCancellationRequested) {
|
||||
return ADP.CreatedTaskWithCancellation<object>();
|
||||
}
|
||||
else {
|
||||
CancellationTokenRegistration registration = new CancellationTokenRegistration();
|
||||
if (cancellationToken.CanBeCanceled) {
|
||||
registration = cancellationToken.Register(CancelIgnoreFailure);
|
||||
}
|
||||
|
||||
try {
|
||||
return Task.FromResult<object>(ExecuteScalar());
|
||||
}
|
||||
catch (Exception e) {
|
||||
registration.Dispose();
|
||||
return ADP.CreatedTaskWithException<object>(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract public object ExecuteScalar();
|
||||
|
||||
abstract public void Prepare();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,203 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DbConnection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public abstract class DbConnection : Component, IDbConnection { // V1.2.3300
|
||||
|
||||
private StateChangeEventHandler _stateChangeEventHandler;
|
||||
|
||||
protected DbConnection() : base() {
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(""),
|
||||
#pragma warning disable 618 // ignore obsolete warning about RecommendedAsConfigurable to use SettingsBindableAttribute
|
||||
RecommendedAsConfigurable(true),
|
||||
#pragma warning restore 618
|
||||
SettingsBindableAttribute(true),
|
||||
RefreshProperties(RefreshProperties.All),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
]
|
||||
abstract public string ConnectionString {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
]
|
||||
virtual public int ConnectionTimeout {
|
||||
get {
|
||||
return ADP.DefaultConnectionTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
]
|
||||
abstract public string Database {
|
||||
get;
|
||||
}
|
||||
|
||||
[
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
]
|
||||
abstract public string DataSource {
|
||||
// NOTE: if you plan on allowing the data source to be changed, you
|
||||
// should implement a ChangeDataSource method, in keeping with
|
||||
// the ChangeDatabase method paradigm.
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The associated provider factory for derived class.
|
||||
/// </summary>
|
||||
virtual protected DbProviderFactory DbProviderFactory {
|
||||
get {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal DbProviderFactory ProviderFactory {
|
||||
get {
|
||||
return DbProviderFactory;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
]
|
||||
abstract public string ServerVersion {
|
||||
get;
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
ResDescriptionAttribute(Res.DbConnection_State),
|
||||
]
|
||||
abstract public ConnectionState State {
|
||||
get;
|
||||
}
|
||||
|
||||
[
|
||||
ResCategoryAttribute(Res.DataCategory_StateChange),
|
||||
ResDescriptionAttribute(Res.DbConnection_StateChange),
|
||||
]
|
||||
virtual public event StateChangeEventHandler StateChange {
|
||||
add {
|
||||
_stateChangeEventHandler += value;
|
||||
}
|
||||
remove {
|
||||
_stateChangeEventHandler -= value;
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected DbTransaction BeginDbTransaction(IsolationLevel isolationLevel);
|
||||
|
||||
public DbTransaction BeginTransaction() {
|
||||
return BeginDbTransaction(IsolationLevel.Unspecified);
|
||||
}
|
||||
|
||||
public DbTransaction BeginTransaction(IsolationLevel isolationLevel) {
|
||||
return BeginDbTransaction(isolationLevel);
|
||||
}
|
||||
|
||||
IDbTransaction IDbConnection.BeginTransaction() {
|
||||
return BeginDbTransaction(IsolationLevel.Unspecified);
|
||||
}
|
||||
|
||||
IDbTransaction IDbConnection.BeginTransaction(IsolationLevel isolationLevel) {
|
||||
return BeginDbTransaction(isolationLevel);
|
||||
}
|
||||
|
||||
abstract public void Close();
|
||||
|
||||
abstract public void ChangeDatabase(string databaseName);
|
||||
|
||||
public DbCommand CreateCommand() {
|
||||
return CreateDbCommand();
|
||||
}
|
||||
|
||||
IDbCommand IDbConnection.CreateCommand() {
|
||||
return CreateDbCommand();
|
||||
}
|
||||
|
||||
abstract protected DbCommand CreateDbCommand();
|
||||
|
||||
virtual public void EnlistTransaction(System.Transactions.Transaction transaction) {
|
||||
// NOTE: This is virtual because not all providers may choose to support
|
||||
// distributed transactions.
|
||||
throw ADP.NotSupported();
|
||||
}
|
||||
|
||||
// these need to be here so that GetSchema is visible when programming to a dbConnection object.
|
||||
// they are overridden by the real implementations in DbConnectionBase
|
||||
virtual public DataTable GetSchema() {
|
||||
throw ADP.NotSupported();
|
||||
}
|
||||
|
||||
virtual public DataTable GetSchema(string collectionName) {
|
||||
throw ADP.NotSupported();
|
||||
}
|
||||
|
||||
virtual public DataTable GetSchema(string collectionName, string[] restrictionValues ) {
|
||||
throw ADP.NotSupported();
|
||||
}
|
||||
|
||||
internal bool _supressStateChangeForReconnection = false; // Do not use for anything else ! Value will be overwritten by CR process
|
||||
|
||||
protected virtual void OnStateChange(StateChangeEventArgs stateChange) {
|
||||
if (_supressStateChangeForReconnection) {
|
||||
return;
|
||||
}
|
||||
StateChangeEventHandler handler = _stateChangeEventHandler;
|
||||
if (null != handler) {
|
||||
handler(this, stateChange);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ForceNewConnection {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
abstract public void Open();
|
||||
|
||||
public Task OpenAsync() {
|
||||
return OpenAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public virtual Task OpenAsync(CancellationToken cancellationToken) {
|
||||
TaskCompletionSource<object> taskCompletionSource = new TaskCompletionSource<object>();
|
||||
|
||||
if (cancellationToken.IsCancellationRequested) {
|
||||
taskCompletionSource.SetCanceled();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Open();
|
||||
taskCompletionSource.SetResult(null);
|
||||
}
|
||||
catch (Exception e) {
|
||||
taskCompletionSource.SetException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,476 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DBConnectionString.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
[Serializable] // MDAC 83147
|
||||
internal sealed class DBConnectionString {
|
||||
// instances of this class are intended to be immutable, i.e readonly
|
||||
// used by permission classes so it is much easier to verify correctness
|
||||
// when not worried about the class being modified during execution
|
||||
|
||||
private static class KEY {
|
||||
internal const string Password = "password";
|
||||
internal const string PersistSecurityInfo = "persist security info";
|
||||
internal const string Pwd = "pwd";
|
||||
};
|
||||
|
||||
// this class is serializable with Everett, so ugly field names can't be changed
|
||||
readonly private string _encryptedUsersConnectionString;
|
||||
|
||||
// hash of unique keys to values
|
||||
readonly private Hashtable _parsetable;
|
||||
|
||||
// a linked list of key/value and their length in _encryptedUsersConnectionString
|
||||
readonly private NameValuePair _keychain;
|
||||
|
||||
// track the existance of "password" or "pwd" in the connection string
|
||||
// not used for anything anymore but must keep it set correct for V1.1 serialization
|
||||
readonly private bool _hasPassword;
|
||||
|
||||
readonly private string[] _restrictionValues;
|
||||
readonly private string _restrictions;
|
||||
|
||||
readonly private KeyRestrictionBehavior _behavior;
|
||||
|
||||
#pragma warning disable 169
|
||||
// this field is no longer used, hence the warning was disabled
|
||||
// however, it can not be removed or it will break serialization with V1.1
|
||||
readonly private string _encryptedActualConnectionString;
|
||||
#pragma warning restore 169
|
||||
|
||||
internal DBConnectionString(string value, string restrictions, KeyRestrictionBehavior behavior, Hashtable synonyms, bool useOdbcRules)
|
||||
: this(new DbConnectionOptions(value, synonyms, useOdbcRules), restrictions, behavior, synonyms, false)
|
||||
{
|
||||
// useOdbcRules is only used to parse the connection string, not to parse restrictions because values don't apply there
|
||||
// the hashtable doesn't need clone since it isn't shared with anything else
|
||||
}
|
||||
|
||||
internal DBConnectionString(DbConnectionOptions connectionOptions)
|
||||
: this(connectionOptions, (string)null, KeyRestrictionBehavior.AllowOnly, (Hashtable)null, true)
|
||||
{
|
||||
// used by DBDataPermission to convert from DbConnectionOptions to DBConnectionString
|
||||
// since backward compatability requires Everett level classes
|
||||
}
|
||||
|
||||
private DBConnectionString(DbConnectionOptions connectionOptions, string restrictions, KeyRestrictionBehavior behavior, Hashtable synonyms, bool mustCloneDictionary) { // used by DBDataPermission
|
||||
Debug.Assert(null != connectionOptions, "null connectionOptions");
|
||||
switch(behavior) {
|
||||
case KeyRestrictionBehavior.PreventUsage:
|
||||
case KeyRestrictionBehavior.AllowOnly:
|
||||
_behavior = behavior;
|
||||
break;
|
||||
default:
|
||||
throw ADP.InvalidKeyRestrictionBehavior(behavior);
|
||||
}
|
||||
|
||||
// grab all the parsed details from DbConnectionOptions
|
||||
_encryptedUsersConnectionString = connectionOptions.UsersConnectionString(false);
|
||||
_hasPassword = connectionOptions.HasPasswordKeyword;
|
||||
_parsetable = connectionOptions.Parsetable;
|
||||
_keychain = connectionOptions.KeyChain;
|
||||
|
||||
// we do not want to serialize out user password unless directed so by "persist security info=true"
|
||||
// otherwise all instances of user's password will be replaced with "*"
|
||||
if (_hasPassword && !connectionOptions.HasPersistablePassword) {
|
||||
|
||||
if (mustCloneDictionary) {
|
||||
// clone the hashtable to replace user's password/pwd value with "*"
|
||||
// we only need to clone if coming from DbConnectionOptions and password exists
|
||||
_parsetable = (Hashtable) _parsetable.Clone();
|
||||
}
|
||||
|
||||
// different than Everett in that instead of removing password/pwd from
|
||||
// the hashtable, we replace the value with '*'. This is okay since we
|
||||
// serialize out with '*' so already knows what we do. Better this way
|
||||
// than to treat password specially later on which causes problems.
|
||||
const string star = "*";
|
||||
if (_parsetable.ContainsKey(KEY.Password)) {
|
||||
_parsetable[KEY.Password] = star;
|
||||
}
|
||||
if (_parsetable.ContainsKey(KEY.Pwd)) {
|
||||
_parsetable[KEY.Pwd] = star;
|
||||
}
|
||||
|
||||
// replace user's password/pwd value with "*" in the linked list and build a new string
|
||||
_keychain = connectionOptions.ReplacePasswordPwd(out _encryptedUsersConnectionString, true);
|
||||
}
|
||||
|
||||
if (!ADP.IsEmpty(restrictions)) {
|
||||
_restrictionValues = ParseRestrictions(restrictions, synonyms);
|
||||
_restrictions = restrictions;
|
||||
}
|
||||
}
|
||||
|
||||
private DBConnectionString(DBConnectionString connectionString, string[] restrictionValues, KeyRestrictionBehavior behavior) {
|
||||
// used by intersect for two equal connection strings with different restrictions
|
||||
_encryptedUsersConnectionString = connectionString._encryptedUsersConnectionString;
|
||||
_parsetable = connectionString._parsetable;
|
||||
_keychain = connectionString._keychain;
|
||||
_hasPassword = connectionString._hasPassword;
|
||||
|
||||
_restrictionValues = restrictionValues;
|
||||
_restrictions = null;
|
||||
_behavior = behavior;
|
||||
|
||||
Verify(restrictionValues);
|
||||
}
|
||||
|
||||
internal KeyRestrictionBehavior Behavior {
|
||||
get { return _behavior; }
|
||||
}
|
||||
|
||||
internal string ConnectionString {
|
||||
get { return _encryptedUsersConnectionString; }
|
||||
}
|
||||
|
||||
internal bool IsEmpty {
|
||||
get { return (null == _keychain); }
|
||||
}
|
||||
|
||||
internal NameValuePair KeyChain {
|
||||
get { return _keychain; }
|
||||
}
|
||||
|
||||
internal string Restrictions {
|
||||
get {
|
||||
string restrictions = _restrictions;
|
||||
if (null == restrictions) {
|
||||
string[] restrictionValues = _restrictionValues;
|
||||
if ((null != restrictionValues) && (0 < restrictionValues.Length)) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for(int i = 0; i < restrictionValues.Length; ++i) {
|
||||
if (!ADP.IsEmpty(restrictionValues[i])) {
|
||||
builder.Append(restrictionValues[i]);
|
||||
builder.Append("=;");
|
||||
}
|
||||
#if DEBUG
|
||||
else {
|
||||
Debug.Assert(false, "empty restriction");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
restrictions = builder.ToString();
|
||||
}
|
||||
}
|
||||
return ((null != restrictions) ? restrictions: "");
|
||||
}
|
||||
}
|
||||
|
||||
internal string this[string keyword] {
|
||||
get { return (string)_parsetable[keyword]; }
|
||||
}
|
||||
|
||||
internal bool ContainsKey(string keyword) {
|
||||
return _parsetable.ContainsKey(keyword);
|
||||
}
|
||||
|
||||
internal DBConnectionString Intersect(DBConnectionString entry) {
|
||||
KeyRestrictionBehavior behavior = _behavior;
|
||||
string[] restrictionValues = null;
|
||||
|
||||
if (null == entry) {
|
||||
//Debug.WriteLine("0 entry AllowNothing");
|
||||
behavior = KeyRestrictionBehavior.AllowOnly;
|
||||
}
|
||||
else if (this._behavior != entry._behavior) { // subset of the AllowOnly array
|
||||
behavior = KeyRestrictionBehavior.AllowOnly;
|
||||
|
||||
if (KeyRestrictionBehavior.AllowOnly == entry._behavior) { // this PreventUsage and entry AllowOnly
|
||||
if (!ADP.IsEmptyArray(_restrictionValues)) {
|
||||
if (!ADP.IsEmptyArray(entry._restrictionValues)) {
|
||||
//Debug.WriteLine("1 this PreventUsage with restrictions and entry AllowOnly with restrictions");
|
||||
restrictionValues = NewRestrictionAllowOnly(entry._restrictionValues, _restrictionValues);
|
||||
}
|
||||
else {
|
||||
//Debug.WriteLine("2 this PreventUsage with restrictions and entry AllowOnly with no restrictions");
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Debug.WriteLine("3/4 this PreventUsage with no restrictions and entry AllowOnly");
|
||||
restrictionValues = entry._restrictionValues;
|
||||
}
|
||||
}
|
||||
else if (!ADP.IsEmptyArray(_restrictionValues)) { // this AllowOnly and entry PreventUsage
|
||||
if (!ADP.IsEmptyArray(entry._restrictionValues)) {
|
||||
//Debug.WriteLine("5 this AllowOnly with restrictions and entry PreventUsage with restrictions");
|
||||
restrictionValues = NewRestrictionAllowOnly(_restrictionValues, entry._restrictionValues);
|
||||
}
|
||||
else {
|
||||
//Debug.WriteLine("6 this AllowOnly and entry PreventUsage with no restrictions");
|
||||
restrictionValues = _restrictionValues;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Debug.WriteLine("7/8 this AllowOnly with no restrictions and entry PreventUsage");
|
||||
}
|
||||
}
|
||||
else if (KeyRestrictionBehavior.PreventUsage == this._behavior) { // both PreventUsage
|
||||
if (ADP.IsEmptyArray(_restrictionValues)) {
|
||||
//Debug.WriteLine("9/10 both PreventUsage and this with no restrictions");
|
||||
restrictionValues = entry._restrictionValues;
|
||||
}
|
||||
else if (ADP.IsEmptyArray(entry._restrictionValues)) {
|
||||
//Debug.WriteLine("11 both PreventUsage and entry with no restrictions");
|
||||
restrictionValues = _restrictionValues;
|
||||
}
|
||||
else {
|
||||
//Debug.WriteLine("12 both PreventUsage with restrictions");
|
||||
restrictionValues = NoDuplicateUnion(_restrictionValues, entry._restrictionValues);
|
||||
}
|
||||
}
|
||||
else if (!ADP.IsEmptyArray(_restrictionValues) && !ADP.IsEmptyArray(entry._restrictionValues)) { // both AllowOnly with restrictions
|
||||
if (this._restrictionValues.Length <= entry._restrictionValues.Length) {
|
||||
//Debug.WriteLine("13a this AllowOnly with restrictions and entry AllowOnly with restrictions");
|
||||
restrictionValues = NewRestrictionIntersect(_restrictionValues, entry._restrictionValues);
|
||||
}
|
||||
else {
|
||||
//Debug.WriteLine("13b this AllowOnly with restrictions and entry AllowOnly with restrictions");
|
||||
restrictionValues = NewRestrictionIntersect(entry._restrictionValues, _restrictionValues);
|
||||
}
|
||||
}
|
||||
else { // both AllowOnly
|
||||
//Debug.WriteLine("14/15/16 this AllowOnly and entry AllowOnly but no restrictions");
|
||||
}
|
||||
|
||||
// verify _hasPassword & _parsetable are in [....] between Everett/Whidbey
|
||||
Debug.Assert(!_hasPassword || ContainsKey(KEY.Password) || ContainsKey(KEY.Pwd), "OnDeserialized password mismatch this");
|
||||
Debug.Assert(null == entry || !entry._hasPassword || entry.ContainsKey(KEY.Password) || entry.ContainsKey(KEY.Pwd), "OnDeserialized password mismatch entry");
|
||||
|
||||
DBConnectionString value = new DBConnectionString(this, restrictionValues, behavior);
|
||||
ValidateCombinedSet(this, value);
|
||||
ValidateCombinedSet(entry, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void ValidateCombinedSet(DBConnectionString componentSet, DBConnectionString combinedSet) {
|
||||
Debug.Assert(combinedSet != null, "The combined connection string should not be null");
|
||||
if ((componentSet != null) && (combinedSet._restrictionValues != null) && (componentSet._restrictionValues != null)) {
|
||||
if (componentSet._behavior == KeyRestrictionBehavior.AllowOnly) {
|
||||
if (combinedSet._behavior == KeyRestrictionBehavior.AllowOnly) {
|
||||
// Component==Allow, Combined==Allow
|
||||
// All values in the Combined Set should also be in the Component Set
|
||||
// Combined - Component == null
|
||||
Debug.Assert(combinedSet._restrictionValues.Except(componentSet._restrictionValues).Count() == 0, "Combined set allows values not allowed by component set");
|
||||
}
|
||||
else if (combinedSet._behavior == KeyRestrictionBehavior.PreventUsage) {
|
||||
// Component==Allow, Combined==PreventUsage
|
||||
// Preventions override allows, so there is nothing to check here
|
||||
}
|
||||
else {
|
||||
Debug.Assert(false, string.Format("Unknown behavior for combined set: {0}", combinedSet._behavior));
|
||||
}
|
||||
}
|
||||
else if (componentSet._behavior == KeyRestrictionBehavior.PreventUsage) {
|
||||
if (combinedSet._behavior == KeyRestrictionBehavior.AllowOnly) {
|
||||
// Component==PreventUsage, Combined==Allow
|
||||
// There shouldn't be any of the values from the Component Set in the Combined Set
|
||||
// Intersect(Component, Combined) == null
|
||||
Debug.Assert(combinedSet._restrictionValues.Intersect(componentSet._restrictionValues).Count() == 0, "Combined values allows values prevented by component set");
|
||||
}
|
||||
else if (combinedSet._behavior == KeyRestrictionBehavior.PreventUsage) {
|
||||
// Component==PreventUsage, Combined==PreventUsage
|
||||
// All values in the Component Set should also be in the Combined Set
|
||||
// Component - Combined == null
|
||||
Debug.Assert(componentSet._restrictionValues.Except(combinedSet._restrictionValues).Count() == 0, "Combined values does not prevent all of the values prevented by the component set");
|
||||
}
|
||||
else {
|
||||
Debug.Assert(false, string.Format("Unknown behavior for combined set: {0}", combinedSet._behavior));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Debug.Assert(false, string.Format("Unknown behavior for component set: {0}", componentSet._behavior));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsRestrictedKeyword(string key) {
|
||||
// restricted if not found
|
||||
return ((null == _restrictionValues) || (0 > Array.BinarySearch(_restrictionValues, key, StringComparer.Ordinal)));
|
||||
}
|
||||
|
||||
internal bool IsSupersetOf(DBConnectionString entry) {
|
||||
Debug.Assert(!_hasPassword || ContainsKey(KEY.Password) || ContainsKey(KEY.Pwd), "OnDeserialized password mismatch this");
|
||||
Debug.Assert(!entry._hasPassword || entry.ContainsKey(KEY.Password) || entry.ContainsKey(KEY.Pwd), "OnDeserialized password mismatch entry");
|
||||
|
||||
switch(_behavior) {
|
||||
case KeyRestrictionBehavior.AllowOnly:
|
||||
// every key must either be in the resticted connection string or in the allowed keywords
|
||||
// keychain may contain duplicates, but it is better than GetEnumerator on _parsetable.Keys
|
||||
for(NameValuePair current = entry.KeyChain; null != current; current = current.Next) {
|
||||
if (!ContainsKey(current.Name) && IsRestrictedKeyword(current.Name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KeyRestrictionBehavior.PreventUsage:
|
||||
// every key can not be in the restricted keywords (even if in the restricted connection string)
|
||||
if (null != _restrictionValues) {
|
||||
foreach(string restriction in _restrictionValues) {
|
||||
if (entry.ContainsKey(restriction)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "invalid KeyRestrictionBehavior");
|
||||
throw ADP.InvalidKeyRestrictionBehavior(_behavior);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static private string[] NewRestrictionAllowOnly(string[] allowonly, string[] preventusage) {
|
||||
List<string> newlist = null;
|
||||
for (int i = 0; i < allowonly.Length; ++i) {
|
||||
if (0 > Array.BinarySearch(preventusage, allowonly[i], StringComparer.Ordinal)) {
|
||||
if (null == newlist) {
|
||||
newlist = new List<string>();
|
||||
}
|
||||
newlist.Add(allowonly[i]);
|
||||
}
|
||||
}
|
||||
string[] restrictionValues = null;
|
||||
if (null != newlist) {
|
||||
restrictionValues = newlist.ToArray();
|
||||
}
|
||||
Verify(restrictionValues);
|
||||
return restrictionValues;
|
||||
}
|
||||
|
||||
static private string[] NewRestrictionIntersect(string[] a, string[] b) {
|
||||
List<string> newlist = null;
|
||||
for (int i = 0; i < a.Length; ++i) {
|
||||
if (0 <= Array.BinarySearch(b, a[i], StringComparer.Ordinal)) {
|
||||
if (null == newlist) {
|
||||
newlist = new List<string>();
|
||||
}
|
||||
newlist.Add(a[i]);
|
||||
}
|
||||
}
|
||||
string[] restrictionValues = null;
|
||||
if (newlist != null) {
|
||||
restrictionValues = newlist.ToArray();
|
||||
}
|
||||
Verify(restrictionValues);
|
||||
return restrictionValues;
|
||||
}
|
||||
|
||||
static private string[] NoDuplicateUnion(string[] a, string[] b) {
|
||||
#if DEBUG
|
||||
Debug.Assert(null != a && 0 < a.Length, "empty a");
|
||||
Debug.Assert(null != b && 0 < b.Length, "empty b");
|
||||
Verify(a);
|
||||
Verify(b);
|
||||
#endif
|
||||
List<string> newlist = new List<string>(a.Length + b.Length);
|
||||
for(int i = 0; i < a.Length; ++i) {
|
||||
newlist.Add(a[i]);
|
||||
}
|
||||
for(int i = 0; i < b.Length; ++i) { // find duplicates
|
||||
if (0 > Array.BinarySearch(a, b[i], StringComparer.Ordinal)) {
|
||||
newlist.Add(b[i]);
|
||||
}
|
||||
}
|
||||
string[] restrictionValues = newlist.ToArray();
|
||||
Array.Sort(restrictionValues, StringComparer.Ordinal);
|
||||
Verify(restrictionValues);
|
||||
return restrictionValues;
|
||||
}
|
||||
|
||||
private static string[] ParseRestrictions(string restrictions, Hashtable synonyms) {
|
||||
#if DEBUG
|
||||
if (Bid.AdvancedOn) {
|
||||
Bid.Trace("<comm.DBConnectionString|INFO|ADV> Restrictions='%ls'\n", restrictions);
|
||||
}
|
||||
#endif
|
||||
List<string> restrictionValues = new List<string>();
|
||||
StringBuilder buffer = new StringBuilder(restrictions.Length);
|
||||
|
||||
int nextStartPosition = 0;
|
||||
int endPosition = restrictions.Length;
|
||||
while (nextStartPosition < endPosition) {
|
||||
int startPosition = nextStartPosition;
|
||||
|
||||
string keyname, keyvalue; // since parsing restrictions ignores values, it doesn't matter if we use ODBC rules or OLEDB rules
|
||||
nextStartPosition = DbConnectionOptions.GetKeyValuePair(restrictions, startPosition, buffer, false, out keyname, out keyvalue);
|
||||
if (!ADP.IsEmpty(keyname)) {
|
||||
#if DEBUG
|
||||
if (Bid.AdvancedOn) {
|
||||
Bid.Trace("<comm.DBConnectionString|INFO|ADV> KeyName='%ls'\n", keyname);
|
||||
}
|
||||
#endif
|
||||
string realkeyname = ((null != synonyms) ? (string)synonyms[keyname] : keyname); // MDAC 85144
|
||||
if (ADP.IsEmpty(realkeyname)) {
|
||||
throw ADP.KeywordNotSupported(keyname);
|
||||
}
|
||||
restrictionValues.Add(realkeyname);
|
||||
}
|
||||
}
|
||||
return RemoveDuplicates(restrictionValues.ToArray());
|
||||
|
||||
}
|
||||
|
||||
static internal string[] RemoveDuplicates(string[] restrictions) {
|
||||
int count = restrictions.Length;
|
||||
if (0 < count) {
|
||||
Array.Sort(restrictions, StringComparer.Ordinal);
|
||||
|
||||
for (int i = 1; i < restrictions.Length; ++i) {
|
||||
string prev = restrictions[i-1];
|
||||
if ((0 == prev.Length) || (prev == restrictions[i])) {
|
||||
restrictions[i-1] = null;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
if (0 == restrictions[restrictions.Length-1].Length) {
|
||||
restrictions[restrictions.Length-1] = null;
|
||||
count--;
|
||||
}
|
||||
if (count != restrictions.Length) {
|
||||
string[] tmp = new String[count];
|
||||
count = 0;
|
||||
for (int i = 0; i < restrictions.Length; ++i) {
|
||||
if (null != restrictions[i]) {
|
||||
tmp[count++] = restrictions[i];
|
||||
}
|
||||
}
|
||||
restrictions = tmp;
|
||||
}
|
||||
}
|
||||
Verify(restrictions);
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
[ConditionalAttribute("DEBUG")]
|
||||
private static void Verify(string[] restrictionValues) {
|
||||
if (null != restrictionValues) {
|
||||
for (int i = 1; i < restrictionValues.Length; ++i) {
|
||||
Debug.Assert(!ADP.IsEmpty(restrictionValues[i-1]), "empty restriction");
|
||||
Debug.Assert(!ADP.IsEmpty(restrictionValues[i]), "empty restriction");
|
||||
Debug.Assert(0 >= StringComparer.Ordinal.Compare(restrictionValues[i-1], restrictionValues[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,376 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DBDataPermission.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System.Collections;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
|
||||
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, ControlEvidence=true, ControlPolicy=true)]
|
||||
[Serializable]
|
||||
public abstract class DBDataPermission : CodeAccessPermission, IUnrestrictedPermission {
|
||||
|
||||
private bool _isUnrestricted;// = false;
|
||||
private bool _allowBlankPassword;// = false;
|
||||
private NameValuePermission _keyvaluetree = NameValuePermission.Default;
|
||||
private /*DBConnectionString[]*/ArrayList _keyvalues; // = null;
|
||||
|
||||
[ Obsolete("DBDataPermission() has been deprecated. Use the DBDataPermission(PermissionState.None) constructor. http://go.microsoft.com/fwlink/?linkid=14202", true) ] // V1.2.3300, MDAC 86034
|
||||
protected DBDataPermission() : this(PermissionState.None) { // V1.0.3300
|
||||
}
|
||||
|
||||
protected DBDataPermission(PermissionState state) { // V1.0.3300
|
||||
if (state == PermissionState.Unrestricted) {
|
||||
_isUnrestricted = true;
|
||||
}
|
||||
else if (state == PermissionState.None) {
|
||||
_isUnrestricted = false;
|
||||
}
|
||||
else {
|
||||
throw ADP.InvalidPermissionState(state);
|
||||
}
|
||||
}
|
||||
|
||||
[ Obsolete("DBDataPermission(PermissionState state,Boolean allowBlankPassword) has been deprecated. Use the DBDataPermission(PermissionState.None) constructor. http://go.microsoft.com/fwlink/?linkid=14202", true) ] // V1.2.3300, MDAC 86034
|
||||
protected DBDataPermission(PermissionState state, bool allowBlankPassword) : this(state) { // V1.0.3300, MDAC 84281
|
||||
AllowBlankPassword = allowBlankPassword;
|
||||
}
|
||||
|
||||
protected DBDataPermission(DBDataPermission permission) { // V1.0.5000, for Copy
|
||||
if (null == permission) {
|
||||
throw ADP.ArgumentNull("permissionAttribute");
|
||||
}
|
||||
CopyFrom(permission);
|
||||
}
|
||||
|
||||
protected DBDataPermission(DBDataPermissionAttribute permissionAttribute) { // V1.0.5000, for CreatePermission
|
||||
if (null == permissionAttribute) {
|
||||
throw ADP.ArgumentNull("permissionAttribute");
|
||||
}
|
||||
_isUnrestricted = permissionAttribute.Unrestricted;
|
||||
if (!_isUnrestricted) {
|
||||
_allowBlankPassword = permissionAttribute.AllowBlankPassword;
|
||||
if (permissionAttribute.ShouldSerializeConnectionString() || permissionAttribute.ShouldSerializeKeyRestrictions()) { // MDAC 86773
|
||||
Add(permissionAttribute.ConnectionString, permissionAttribute.KeyRestrictions, permissionAttribute.KeyRestrictionBehavior);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// how connectionString security is used
|
||||
// parsetable (all string) is shared with connection
|
||||
internal DBDataPermission(DbConnectionOptions connectionOptions) { // v2.0
|
||||
if (null != connectionOptions) {
|
||||
_allowBlankPassword = connectionOptions.HasBlankPassword; // MDAC 84563
|
||||
AddPermissionEntry(new DBConnectionString(connectionOptions));
|
||||
}
|
||||
}
|
||||
|
||||
public bool AllowBlankPassword { // V1.0.3300
|
||||
get {
|
||||
return _allowBlankPassword;
|
||||
}
|
||||
set { // MDAC 61263
|
||||
// for behavioral backward compatability with V1.1
|
||||
// set_AllowBlankPassword does not _isUnrestricted=false
|
||||
_allowBlankPassword = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Add(string connectionString, string restrictions, KeyRestrictionBehavior behavior) { // V1.0.5000
|
||||
DBConnectionString constr = new DBConnectionString(connectionString, restrictions, behavior, null, false);
|
||||
AddPermissionEntry(constr);
|
||||
}
|
||||
|
||||
internal void AddPermissionEntry(DBConnectionString entry) {
|
||||
if (null == _keyvaluetree) {
|
||||
_keyvaluetree = new NameValuePermission();
|
||||
}
|
||||
if (null == _keyvalues) {
|
||||
_keyvalues = new ArrayList();
|
||||
}
|
||||
NameValuePermission.AddEntry(_keyvaluetree, _keyvalues, entry);
|
||||
_isUnrestricted = false; // MDAC 84639
|
||||
}
|
||||
|
||||
protected void Clear() { // V1.2.3300, MDAC 83105
|
||||
_keyvaluetree = null;
|
||||
_keyvalues = null;
|
||||
}
|
||||
|
||||
// IPermission interface methods
|
||||
// [ObsoleteAttribute("override Copy instead of using default implementation")] // not inherited
|
||||
override public IPermission Copy() {
|
||||
DBDataPermission copy = CreateInstance();
|
||||
copy.CopyFrom(this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
private void CopyFrom(DBDataPermission permission) {
|
||||
_isUnrestricted = permission.IsUnrestricted();
|
||||
if (!_isUnrestricted) {
|
||||
_allowBlankPassword = permission.AllowBlankPassword;
|
||||
|
||||
if (null != permission._keyvalues) {
|
||||
_keyvalues = (ArrayList) permission._keyvalues.Clone();
|
||||
|
||||
if (null != permission._keyvaluetree) {
|
||||
_keyvaluetree = permission._keyvaluetree.CopyNameValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [ Obsolete("use DBDataPermission(DBDataPermission) ctor") ]
|
||||
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] // V1.0.5000, MDAC 82936
|
||||
virtual protected DBDataPermission CreateInstance() {
|
||||
// derived class should override with a different implementation avoiding reflection to allow semi-trusted scenarios
|
||||
return (Activator.CreateInstance(GetType(), System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null) as DBDataPermission);
|
||||
}
|
||||
|
||||
override public IPermission Intersect(IPermission target) { // used during Deny actions
|
||||
if (null == target) {
|
||||
return null;
|
||||
}
|
||||
if (target.GetType() != this.GetType()) {
|
||||
throw ADP.PermissionTypeMismatch();
|
||||
}
|
||||
if (this.IsUnrestricted()) { // MDAC 84803, NDPWhidbey 29121
|
||||
return target.Copy();
|
||||
}
|
||||
|
||||
DBDataPermission operand = (DBDataPermission) target;
|
||||
if (operand.IsUnrestricted()) { // NDPWhidbey 29121
|
||||
return this.Copy();
|
||||
}
|
||||
|
||||
DBDataPermission newPermission = (DBDataPermission) operand.Copy();
|
||||
newPermission._allowBlankPassword &= AllowBlankPassword;
|
||||
|
||||
if ((null != _keyvalues) && (null != newPermission._keyvalues)) {
|
||||
newPermission._keyvalues.Clear();
|
||||
|
||||
newPermission._keyvaluetree.Intersect(newPermission._keyvalues, _keyvaluetree);
|
||||
}
|
||||
else {
|
||||
// either target.Add or this.Add have not been called
|
||||
// return a non-null object so IsSubset calls will fail
|
||||
newPermission._keyvalues = null;
|
||||
newPermission._keyvaluetree = null;
|
||||
}
|
||||
|
||||
if (newPermission.IsEmpty()) { // no intersection, MDAC 86773
|
||||
newPermission = null;
|
||||
}
|
||||
return newPermission;
|
||||
}
|
||||
|
||||
private bool IsEmpty() { // MDAC 84804
|
||||
ArrayList keyvalues = _keyvalues;
|
||||
bool flag = (!IsUnrestricted() && !AllowBlankPassword && ((null == keyvalues) || (0 == keyvalues.Count)));
|
||||
return flag;
|
||||
}
|
||||
|
||||
override public bool IsSubsetOf(IPermission target) {
|
||||
if (null == target) {
|
||||
return IsEmpty();
|
||||
}
|
||||
if (target.GetType() != this.GetType()) {
|
||||
throw ADP.PermissionTypeMismatch();
|
||||
}
|
||||
|
||||
DBDataPermission superset = (target as DBDataPermission);
|
||||
|
||||
bool subset = superset.IsUnrestricted();
|
||||
if (!subset) {
|
||||
if (!IsUnrestricted() &&
|
||||
(!AllowBlankPassword || superset.AllowBlankPassword) &&
|
||||
((null == _keyvalues) || (null != superset._keyvaluetree))) {
|
||||
|
||||
subset = true;
|
||||
if (null != _keyvalues) {
|
||||
foreach(DBConnectionString kventry in _keyvalues) {
|
||||
if(!superset._keyvaluetree.CheckValueForKeyPermit(kventry)) {
|
||||
subset = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return subset;
|
||||
}
|
||||
|
||||
// IUnrestrictedPermission interface methods
|
||||
public bool IsUnrestricted() {
|
||||
return _isUnrestricted;
|
||||
}
|
||||
|
||||
override public IPermission Union(IPermission target) {
|
||||
if (null == target) {
|
||||
return this.Copy();
|
||||
}
|
||||
if (target.GetType() != this.GetType()) {
|
||||
throw ADP.PermissionTypeMismatch();
|
||||
}
|
||||
if (IsUnrestricted()) { // MDAC 84803
|
||||
return this.Copy();
|
||||
}
|
||||
|
||||
DBDataPermission newPermission = (DBDataPermission) target.Copy();
|
||||
if (!newPermission.IsUnrestricted()) {
|
||||
newPermission._allowBlankPassword |= AllowBlankPassword;
|
||||
|
||||
if (null != _keyvalues) {
|
||||
foreach(DBConnectionString entry in _keyvalues) {
|
||||
newPermission.AddPermissionEntry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (newPermission.IsEmpty() ? null : newPermission);
|
||||
}
|
||||
|
||||
private string DecodeXmlValue(string value) {
|
||||
if ((null != value) && (0 < value.Length)) {
|
||||
value = value.Replace(""", "\"");
|
||||
value = value.Replace("'", "\'");
|
||||
value = value.Replace("<", "<");
|
||||
value = value.Replace(">", ">");
|
||||
value = value.Replace("&", "&");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private string EncodeXmlValue(string value) {
|
||||
if ((null != value) && (0 < value.Length)) {
|
||||
value = value.Replace('\0', ' '); // assumption that '\0' will only be at end of string
|
||||
value = value.Trim();
|
||||
value = value.Replace("&", "&");
|
||||
value = value.Replace(">", ">");
|
||||
value = value.Replace("<", "<");
|
||||
value = value.Replace("\'", "'");
|
||||
value = value.Replace("\"", """);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// <IPermission class="...Permission" version="1" AllowBlankPassword=false>
|
||||
// <add ConnectionString="provider=x;data source=y;" KeyRestrictions="address=;server=" KeyRestrictionBehavior=PreventUsage/>
|
||||
// </IPermission>
|
||||
override public void FromXml(SecurityElement securityElement) {
|
||||
// code derived from CodeAccessPermission.ValidateElement
|
||||
if (null == securityElement) {
|
||||
throw ADP.ArgumentNull("securityElement");
|
||||
}
|
||||
string tag = securityElement.Tag;
|
||||
if (!tag.Equals(XmlStr._Permission) && !tag.Equals(XmlStr._IPermission)) {
|
||||
throw ADP.NotAPermissionElement();
|
||||
}
|
||||
String version = securityElement.Attribute(XmlStr._Version);
|
||||
if ((null != version) && !version.Equals(XmlStr._VersionNumber)) {
|
||||
throw ADP.InvalidXMLBadVersion();
|
||||
}
|
||||
|
||||
string unrestrictedValue = securityElement.Attribute(XmlStr._Unrestricted);
|
||||
_isUnrestricted = (null != unrestrictedValue) && Boolean.Parse(unrestrictedValue);
|
||||
|
||||
Clear(); // MDAC 83105
|
||||
if (!_isUnrestricted) {
|
||||
string allowNull = securityElement.Attribute(XmlStr._AllowBlankPassword);
|
||||
_allowBlankPassword = (null != allowNull) && Boolean.Parse(allowNull);
|
||||
|
||||
ArrayList children = securityElement.Children;
|
||||
if (null != children) {
|
||||
foreach(SecurityElement keyElement in children) {
|
||||
tag = keyElement.Tag;
|
||||
if ((XmlStr._add == tag) || ((null != tag) && (XmlStr._add == tag.ToLower(CultureInfo.InvariantCulture)))) {
|
||||
string constr = keyElement.Attribute(XmlStr._ConnectionString);
|
||||
string restrt = keyElement.Attribute(XmlStr._KeyRestrictions);
|
||||
string behavr = keyElement.Attribute(XmlStr._KeyRestrictionBehavior);
|
||||
|
||||
KeyRestrictionBehavior behavior = KeyRestrictionBehavior.AllowOnly;
|
||||
if (null != behavr) {
|
||||
behavior = (KeyRestrictionBehavior) Enum.Parse(typeof(KeyRestrictionBehavior), behavr, true);
|
||||
}
|
||||
constr = DecodeXmlValue(constr);
|
||||
restrt = DecodeXmlValue(restrt);
|
||||
Add(constr, restrt, behavior);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
_allowBlankPassword = false;
|
||||
}
|
||||
}
|
||||
|
||||
// <IPermission class="...Permission" version="1" AllowBlankPassword=false>
|
||||
// <add ConnectionString="provider=x;data source=y;"/>
|
||||
// <add ConnectionString="provider=x;data source=y;" KeyRestrictions="user id=;password=;" KeyRestrictionBehavior=AllowOnly/>
|
||||
// <add ConnectionString="provider=x;data source=y;" KeyRestrictions="address=;server=" KeyRestrictionBehavior=PreventUsage/>
|
||||
// </IPermission>
|
||||
override public SecurityElement ToXml() {
|
||||
Type type = this.GetType();
|
||||
SecurityElement root = new SecurityElement(XmlStr._IPermission);
|
||||
root.AddAttribute(XmlStr._class, type.AssemblyQualifiedName.Replace('\"', '\''));
|
||||
root.AddAttribute(XmlStr._Version, XmlStr._VersionNumber);
|
||||
|
||||
if (IsUnrestricted()) {
|
||||
root.AddAttribute(XmlStr._Unrestricted, XmlStr._true);
|
||||
}
|
||||
else {
|
||||
root.AddAttribute(XmlStr._AllowBlankPassword, _allowBlankPassword.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
if (null != _keyvalues) {
|
||||
foreach(DBConnectionString value in _keyvalues) {
|
||||
SecurityElement valueElement = new SecurityElement(XmlStr._add);
|
||||
string tmp;
|
||||
|
||||
tmp = value.ConnectionString; // WebData 97375
|
||||
tmp = EncodeXmlValue(tmp);
|
||||
if (!ADP.IsEmpty(tmp)) {
|
||||
valueElement.AddAttribute(XmlStr._ConnectionString, tmp);
|
||||
}
|
||||
tmp = value.Restrictions;
|
||||
tmp = EncodeXmlValue(tmp);
|
||||
if (null == tmp) { tmp = ADP.StrEmpty; }
|
||||
valueElement.AddAttribute(XmlStr._KeyRestrictions, tmp);
|
||||
|
||||
tmp = value.Behavior.ToString();
|
||||
valueElement.AddAttribute(XmlStr._KeyRestrictionBehavior, tmp);
|
||||
|
||||
root.AddChild(valueElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
private static class XmlStr {
|
||||
internal const string _class = "class";
|
||||
internal const string _IPermission = "IPermission";
|
||||
internal const string _Permission = "Permission";
|
||||
internal const string _Unrestricted = "Unrestricted";
|
||||
internal const string _AllowBlankPassword = "AllowBlankPassword";
|
||||
internal const string _true = "true";
|
||||
internal const string _Version = "version";
|
||||
internal const string _VersionNumber = "1";
|
||||
|
||||
internal const string _add = "add";
|
||||
|
||||
internal const string _ConnectionString = "ConnectionString";
|
||||
internal const string _KeyRestrictions = "KeyRestrictions";
|
||||
internal const string _KeyRestrictionBehavior = "KeyRestrictionBehavior";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DBDataPermissionAttribute.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
|
||||
/* derived class pattern
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
|
||||
[Serializable] sealed public class XPermissionAttribute : DBDataPermissionAttribute {
|
||||
public XPermissionAttribute(SecurityAction action) : base(action) {
|
||||
}
|
||||
override public IPermission CreatePermission() {
|
||||
return new XPermission(this);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
[Serializable(), AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
|
||||
public abstract class DBDataPermissionAttribute : CodeAccessSecurityAttribute { // V1.0.3300
|
||||
private bool _allowBlankPassword;// = false;
|
||||
private string _connectionString;// = ADP.StrEmpty;
|
||||
private string _restrictions;// = ADP.StrEmpty;
|
||||
private KeyRestrictionBehavior _behavior;// = KeyRestrictionBehavior.AllowOnly;
|
||||
|
||||
protected DBDataPermissionAttribute(SecurityAction action) : base(action) {
|
||||
}
|
||||
|
||||
public bool AllowBlankPassword { // V1.0.3300
|
||||
get {
|
||||
return _allowBlankPassword;
|
||||
}
|
||||
set {
|
||||
_allowBlankPassword = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string ConnectionString { // V1.0.5000
|
||||
get {
|
||||
string value = _connectionString;
|
||||
return ((null != value) ? value : String.Empty);
|
||||
}
|
||||
set {
|
||||
_connectionString = value;
|
||||
}
|
||||
}
|
||||
|
||||
public KeyRestrictionBehavior KeyRestrictionBehavior { // V1.0.5000, default AllowOnly
|
||||
get {
|
||||
return _behavior;
|
||||
}
|
||||
set {
|
||||
switch(value) {
|
||||
case KeyRestrictionBehavior.PreventUsage:
|
||||
case KeyRestrictionBehavior.AllowOnly:
|
||||
_behavior = value;
|
||||
break;
|
||||
default:
|
||||
throw ADP.InvalidKeyRestrictionBehavior(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyRestrictions { // V1.0.5000
|
||||
get {
|
||||
string value = _restrictions;
|
||||
return (null != value) ? value : ADP.StrEmpty;
|
||||
}
|
||||
set {
|
||||
_restrictions = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ EditorBrowsableAttribute(EditorBrowsableState.Never) ]
|
||||
public bool ShouldSerializeConnectionString() { // V1.2.3300
|
||||
return (null != _connectionString);
|
||||
}
|
||||
|
||||
[ EditorBrowsableAttribute(EditorBrowsableState.Never) ]
|
||||
public bool ShouldSerializeKeyRestrictions() { // V1.2.3300
|
||||
return (null != _restrictions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace System.Data { // MDAC 83087
|
||||
|
||||
[Serializable]
|
||||
|
||||
public enum KeyRestrictionBehavior { // V1.0.5000
|
||||
AllowOnly = 0,
|
||||
PreventUsage = 1,
|
||||
}
|
||||
}
|
@@ -0,0 +1,155 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DbParameter.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
|
||||
public abstract class DbParameter : MarshalByRefObject, IDbDataParameter { // V1.2.3300
|
||||
|
||||
protected DbParameter() : base() {
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
RefreshProperties(RefreshProperties.All),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbParameter_DbType),
|
||||
]
|
||||
abstract public DbType DbType {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
EditorBrowsableAttribute(EditorBrowsableState.Advanced)
|
||||
]
|
||||
public abstract void ResetDbType();
|
||||
|
||||
[
|
||||
DefaultValue(ParameterDirection.Input),
|
||||
RefreshProperties(RefreshProperties.All),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbParameter_Direction),
|
||||
]
|
||||
abstract public ParameterDirection Direction {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignOnly(true),
|
||||
EditorBrowsableAttribute(EditorBrowsableState.Never)
|
||||
]
|
||||
abstract public Boolean IsNullable {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(""),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbParameter_ParameterName),
|
||||
]
|
||||
abstract public String ParameterName {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
byte IDbDataParameter.Precision { // SqlProjectTracking 17233
|
||||
get {
|
||||
return 0;
|
||||
}
|
||||
set {
|
||||
}
|
||||
}
|
||||
|
||||
byte IDbDataParameter.Scale { // SqlProjectTracking 17233
|
||||
get {
|
||||
return 0;
|
||||
}
|
||||
set {
|
||||
}
|
||||
}
|
||||
|
||||
virtual public byte Precision {
|
||||
get {
|
||||
return ((IDbDataParameter)this).Precision;
|
||||
}
|
||||
set {
|
||||
((IDbDataParameter)this).Precision = value;
|
||||
}
|
||||
}
|
||||
|
||||
virtual public byte Scale {
|
||||
get {
|
||||
return ((IDbDataParameter)this).Scale;
|
||||
}
|
||||
set {
|
||||
((IDbDataParameter)this).Scale = value;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbParameter_Size),
|
||||
]
|
||||
abstract public int Size {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(""),
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbParameter_SourceColumn),
|
||||
]
|
||||
abstract public String SourceColumn {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(false),
|
||||
EditorBrowsableAttribute(EditorBrowsableState.Advanced),
|
||||
RefreshProperties(RefreshProperties.All),
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbParameter_SourceColumnNullMapping),
|
||||
]
|
||||
abstract public bool SourceColumnNullMapping {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(DataRowVersion.Current),
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbParameter_SourceVersion),
|
||||
]
|
||||
virtual public DataRowVersion SourceVersion {
|
||||
get { return DataRowVersion.Default; }
|
||||
set { }
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(null),
|
||||
RefreshProperties(RefreshProperties.All),
|
||||
ResCategoryAttribute(Res.DataCategory_Data),
|
||||
ResDescriptionAttribute(Res.DbParameter_Value),
|
||||
]
|
||||
abstract public object Value {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,395 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DBSchemaRow.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
sealed internal class DbSchemaRow {
|
||||
internal const string SchemaMappingUnsortedIndex = "SchemaMapping Unsorted Index";
|
||||
DbSchemaTable schemaTable;
|
||||
DataRow dataRow;
|
||||
|
||||
static internal DbSchemaRow[] GetSortedSchemaRows(DataTable dataTable, bool returnProviderSpecificTypes) { // MDAC 60609
|
||||
DataColumn sortindex= dataTable.Columns[SchemaMappingUnsortedIndex];
|
||||
if (null == sortindex) { // WebData 100390
|
||||
sortindex = new DataColumn(SchemaMappingUnsortedIndex, typeof(Int32)); // MDAC 67050
|
||||
dataTable.Columns.Add(sortindex);
|
||||
}
|
||||
int count = dataTable.Rows.Count;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
dataTable.Rows[i][sortindex] = i;
|
||||
};
|
||||
DbSchemaTable schemaTable = new DbSchemaTable(dataTable, returnProviderSpecificTypes);
|
||||
|
||||
const DataViewRowState rowStates = DataViewRowState.Unchanged | DataViewRowState.Added | DataViewRowState.ModifiedCurrent;
|
||||
DataRow[] dataRows = dataTable.Select(null, "ColumnOrdinal ASC", rowStates);
|
||||
Debug.Assert(null != dataRows, "GetSchemaRows: unexpected null dataRows");
|
||||
|
||||
DbSchemaRow[] schemaRows = new DbSchemaRow[dataRows.Length];
|
||||
|
||||
for (int i = 0; i < dataRows.Length; ++i) {
|
||||
schemaRows[i] = new DbSchemaRow(schemaTable, dataRows[i]);
|
||||
}
|
||||
return schemaRows;
|
||||
}
|
||||
|
||||
internal DbSchemaRow(DbSchemaTable schemaTable, DataRow dataRow) {
|
||||
this.schemaTable = schemaTable;
|
||||
this.dataRow = dataRow;
|
||||
}
|
||||
|
||||
internal DataRow DataRow {
|
||||
get {
|
||||
return dataRow;
|
||||
}
|
||||
}
|
||||
|
||||
internal string ColumnName {
|
||||
get {
|
||||
Debug.Assert(null != schemaTable.ColumnName, "no column ColumnName");
|
||||
object value = dataRow[schemaTable.ColumnName, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.ColumnName, "missing column ColumnName");
|
||||
dataRow[schemaTable.ColumnName] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
//internal Int32 Ordinal {
|
||||
/*get {
|
||||
Debug.Assert(null != schemaTable.Ordinal, "no column Ordinal");
|
||||
return Convert.ToInt32(dataRow[schemaTable.Ordinal, DataRowVersion.Default], CultureInfo.InvariantCulture);
|
||||
}*/
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.Ordinal, "missing column Ordinal");
|
||||
dataRow[schemaTable.Ordinal] = value;
|
||||
}*/
|
||||
|
||||
//}
|
||||
|
||||
internal Int32 Size {
|
||||
get {
|
||||
Debug.Assert(null != schemaTable.Size, "no column Size");
|
||||
object value = dataRow[schemaTable.Size, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToInt32(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.Size, "missing column Size");
|
||||
dataRow[schemaTable.Size] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal string BaseColumnName {
|
||||
get {
|
||||
if (null != schemaTable.BaseColumnName) {
|
||||
object value = dataRow[schemaTable.BaseColumnName, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.BaseColumnName, "missing column BaseColumnName");
|
||||
dataRow[schemaTable.BaseColumnName] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal string BaseServerName {
|
||||
get {
|
||||
if (null != schemaTable.BaseServerName) {
|
||||
object value = dataRow[schemaTable.BaseServerName, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.BaseServerName, "missing column BaseServerName");
|
||||
dataRow[schemaTable.BaseServerName] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
internal string BaseCatalogName {
|
||||
get {
|
||||
if (null != schemaTable.BaseCatalogName) {
|
||||
object value = dataRow[schemaTable.BaseCatalogName, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.BaseCatalogName, "missing column BaseCatalogName");
|
||||
dataRow[schemaTable.BaseCatalogName] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal string BaseSchemaName {
|
||||
get {
|
||||
if (null != schemaTable.BaseSchemaName) {
|
||||
object value = dataRow[schemaTable.BaseSchemaName, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.BaseSchemaName, "missing column BaseSchemaName");
|
||||
dataRow[schemaTable.BaseSchemaName] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal string BaseTableName {
|
||||
get {
|
||||
if (null != schemaTable.BaseTableName) {
|
||||
object value = dataRow[schemaTable.BaseTableName, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.BaseTableName, "missing column BaseTableName");
|
||||
dataRow[schemaTable.BaseTableName] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal bool IsAutoIncrement {
|
||||
get {
|
||||
if (null != schemaTable.IsAutoIncrement) {
|
||||
object value = dataRow[schemaTable.IsAutoIncrement, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsAutoIncrement, "missing column IsAutoIncrement");
|
||||
dataRow[schemaTable.IsAutoIncrement] = (bool)value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal bool IsUnique {
|
||||
get {
|
||||
if (null != schemaTable.IsUnique) {
|
||||
object value = dataRow[schemaTable.IsUnique, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsUnique, "missing column IsUnique");
|
||||
dataRow[schemaTable.IsUnique] = (bool)value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal bool IsRowVersion {
|
||||
get {
|
||||
if (null != schemaTable.IsRowVersion) {
|
||||
object value = dataRow[schemaTable.IsRowVersion, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsRowVersion, "missing column IsRowVersion");
|
||||
dataRow[schemaTable.IsRowVersion] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal bool IsKey {
|
||||
get {
|
||||
if (null != schemaTable.IsKey) {
|
||||
object value = dataRow[schemaTable.IsKey, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsKey, "missing column IsKey");
|
||||
dataRow[schemaTable.IsKey] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
// consider: just do comparison directly -> (object)(baseColumnName) == (object)(columnName)
|
||||
//internal bool IsAliased {
|
||||
/*get {
|
||||
if (null != schemaTable.IsAliased) { // MDAC 62336
|
||||
object value = dataRow[schemaTable.IsAliased, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}*/
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsAliased, "missing column IsAliased");
|
||||
dataRow[schemaTable.IsAliased] = value;
|
||||
}*/
|
||||
//}
|
||||
|
||||
internal bool IsExpression {
|
||||
get {
|
||||
if (null != schemaTable.IsExpression) { // MDAC 62336
|
||||
object value = dataRow[schemaTable.IsExpression, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsExpression, "missing column IsExpression");
|
||||
dataRow[schemaTable.IsExpression] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
//internal bool IsIdentity {
|
||||
/*get {
|
||||
if (null != schemaTable.IsIdentity) { // MDAC 62336
|
||||
object value = dataRow[schemaTable.IsIdentity, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}*/
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsIdentity, "missing column IsIdentity");
|
||||
dataRow[schemaTable.IsIdentity] = value;
|
||||
}*/
|
||||
//}
|
||||
|
||||
internal bool IsHidden {
|
||||
get {
|
||||
if (null != schemaTable.IsHidden) { // MDAC 62336
|
||||
object value = dataRow[schemaTable.IsHidden, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsHidden, "missing column IsHidden");
|
||||
dataRow[schemaTable.IsHidden] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal bool IsLong {
|
||||
get {
|
||||
if (null != schemaTable.IsLong) { // MDAC 62336
|
||||
object value = dataRow[schemaTable.IsLong, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsLong, "missing column IsHidden");
|
||||
dataRow[schemaTable.IsLong] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal bool IsReadOnly {
|
||||
get {
|
||||
if (null != schemaTable.IsReadOnly) { // MDAC 62336
|
||||
object value = dataRow[schemaTable.IsReadOnly, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.IsReadOnly, "missing column IsReadOnly");
|
||||
dataRow[schemaTable.IsReadOnly] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal System.Type DataType {
|
||||
get {
|
||||
if (null != schemaTable.DataType) {
|
||||
object value = dataRow[schemaTable.DataType, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return(System.Type) value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.DataType, "missing column DataType");
|
||||
dataRow[schemaTable.DataType] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
internal bool AllowDBNull {
|
||||
get {
|
||||
if (null != schemaTable.AllowDBNull) {
|
||||
object value = dataRow[schemaTable.AllowDBNull, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*set {
|
||||
Debug.Assert(null != schemaTable.AllowDBNull, "missing column MaybeNull");
|
||||
dataRow[schemaTable.AllowDBNull] = value;
|
||||
}*/
|
||||
}
|
||||
|
||||
/*internal Int32 ProviderType {
|
||||
get {
|
||||
if (null != schemaTable.ProviderType) {
|
||||
object value = dataRow[schemaTable.ProviderType, DataRowVersion.Default];
|
||||
if (!Convert.IsDBNull(value)) {
|
||||
return Convert.ToInt32(value);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
set {
|
||||
Debug.Assert(null != schemaTable.ProviderType, "missing column ProviderType");
|
||||
dataRow[schemaTable.ProviderType] = value;
|
||||
}
|
||||
}*/
|
||||
|
||||
internal Int32 UnsortedIndex {
|
||||
get {
|
||||
return (Int32) dataRow[schemaTable.UnsortedIndex, DataRowVersion.Default];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,125 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DBSchemaTable.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.ProviderBase;
|
||||
using System.Diagnostics;
|
||||
|
||||
sealed internal class DbSchemaTable {
|
||||
|
||||
private enum ColumnEnum {
|
||||
ColumnName,
|
||||
ColumnOrdinal,
|
||||
ColumnSize,
|
||||
BaseServerName,
|
||||
BaseCatalogName,
|
||||
BaseColumnName,
|
||||
BaseSchemaName,
|
||||
BaseTableName,
|
||||
IsAutoIncrement,
|
||||
IsUnique,
|
||||
IsKey,
|
||||
IsRowVersion,
|
||||
DataType,
|
||||
ProviderSpecificDataType,
|
||||
AllowDBNull,
|
||||
ProviderType,
|
||||
IsExpression,
|
||||
IsHidden,
|
||||
IsLong,
|
||||
IsReadOnly,
|
||||
SchemaMappingUnsortedIndex,
|
||||
}
|
||||
|
||||
static readonly private string[] DBCOLUMN_NAME = new string[] {
|
||||
SchemaTableColumn.ColumnName,
|
||||
SchemaTableColumn.ColumnOrdinal,
|
||||
SchemaTableColumn.ColumnSize,
|
||||
SchemaTableOptionalColumn.BaseServerName,
|
||||
SchemaTableOptionalColumn.BaseCatalogName,
|
||||
SchemaTableColumn.BaseColumnName,
|
||||
SchemaTableColumn.BaseSchemaName,
|
||||
SchemaTableColumn.BaseTableName,
|
||||
SchemaTableOptionalColumn.IsAutoIncrement,
|
||||
SchemaTableColumn.IsUnique,
|
||||
SchemaTableColumn.IsKey,
|
||||
SchemaTableOptionalColumn.IsRowVersion,
|
||||
SchemaTableColumn.DataType,
|
||||
SchemaTableOptionalColumn.ProviderSpecificDataType,
|
||||
SchemaTableColumn.AllowDBNull,
|
||||
SchemaTableColumn.ProviderType,
|
||||
SchemaTableColumn.IsExpression,
|
||||
SchemaTableOptionalColumn.IsHidden,
|
||||
SchemaTableColumn.IsLong,
|
||||
SchemaTableOptionalColumn.IsReadOnly,
|
||||
DbSchemaRow.SchemaMappingUnsortedIndex,
|
||||
};
|
||||
|
||||
internal DataTable dataTable;
|
||||
private DataColumnCollection columns;
|
||||
private DataColumn[] columnCache = new DataColumn[DBCOLUMN_NAME.Length];
|
||||
private bool _returnProviderSpecificTypes;
|
||||
|
||||
internal DbSchemaTable(DataTable dataTable, bool returnProviderSpecificTypes) {
|
||||
this.dataTable = dataTable;
|
||||
this.columns = dataTable.Columns;
|
||||
_returnProviderSpecificTypes = returnProviderSpecificTypes;
|
||||
}
|
||||
|
||||
internal DataColumn ColumnName { get { return CachedDataColumn(ColumnEnum.ColumnName);}}
|
||||
internal DataColumn Size { get { return CachedDataColumn(ColumnEnum.ColumnSize);}}
|
||||
internal DataColumn BaseServerName { get { return CachedDataColumn(ColumnEnum.BaseServerName);}}
|
||||
internal DataColumn BaseColumnName { get { return CachedDataColumn(ColumnEnum.BaseColumnName);}}
|
||||
internal DataColumn BaseTableName { get { return CachedDataColumn(ColumnEnum.BaseTableName);}}
|
||||
internal DataColumn BaseCatalogName { get { return CachedDataColumn(ColumnEnum.BaseCatalogName);}}
|
||||
internal DataColumn BaseSchemaName { get { return CachedDataColumn(ColumnEnum.BaseSchemaName);}}
|
||||
internal DataColumn IsAutoIncrement { get { return CachedDataColumn(ColumnEnum.IsAutoIncrement);}}
|
||||
internal DataColumn IsUnique { get { return CachedDataColumn(ColumnEnum.IsUnique);}}
|
||||
internal DataColumn IsKey { get { return CachedDataColumn(ColumnEnum.IsKey);}}
|
||||
internal DataColumn IsRowVersion { get { return CachedDataColumn(ColumnEnum.IsRowVersion);}}
|
||||
|
||||
internal DataColumn AllowDBNull { get { return CachedDataColumn(ColumnEnum.AllowDBNull);}}
|
||||
internal DataColumn IsExpression { get { return CachedDataColumn(ColumnEnum.IsExpression);}}
|
||||
internal DataColumn IsHidden { get { return CachedDataColumn(ColumnEnum.IsHidden);}}
|
||||
internal DataColumn IsLong { get { return CachedDataColumn(ColumnEnum.IsLong);}}
|
||||
internal DataColumn IsReadOnly { get { return CachedDataColumn(ColumnEnum.IsReadOnly);}}
|
||||
|
||||
internal DataColumn UnsortedIndex { get { return CachedDataColumn(ColumnEnum.SchemaMappingUnsortedIndex);}}
|
||||
|
||||
internal DataColumn DataType {
|
||||
get {
|
||||
if (_returnProviderSpecificTypes) {
|
||||
return CachedDataColumn(ColumnEnum.ProviderSpecificDataType, ColumnEnum.DataType);
|
||||
}
|
||||
return CachedDataColumn(ColumnEnum.DataType);
|
||||
}
|
||||
}
|
||||
|
||||
private DataColumn CachedDataColumn(ColumnEnum column) {
|
||||
return CachedDataColumn(column, column);
|
||||
}
|
||||
|
||||
private DataColumn CachedDataColumn(ColumnEnum column, ColumnEnum column2) {
|
||||
DataColumn dataColumn = columnCache[(int) column];
|
||||
if (null == dataColumn) {
|
||||
int index = columns.IndexOf(DBCOLUMN_NAME[(int) column]);
|
||||
if ((-1 == index) && (column != column2)) {
|
||||
index = columns.IndexOf(DBCOLUMN_NAME[(int) column2]);
|
||||
}
|
||||
if (-1 != index) {
|
||||
dataColumn = columns[index];
|
||||
columnCache[(int) column] = dataColumn;
|
||||
}
|
||||
}
|
||||
return dataColumn;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,207 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DataColumnMapping.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design.Serialization;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
[
|
||||
System.ComponentModel.TypeConverterAttribute(typeof(System.Data.Common.DataColumnMapping.DataColumnMappingConverter))
|
||||
]
|
||||
public sealed class DataColumnMapping : MarshalByRefObject, IColumnMapping, ICloneable {
|
||||
private DataColumnMappingCollection parent;
|
||||
private string _dataSetColumnName;
|
||||
private string _sourceColumnName;
|
||||
|
||||
public DataColumnMapping() {
|
||||
}
|
||||
|
||||
public DataColumnMapping(string sourceColumn, string dataSetColumn) {
|
||||
SourceColumn = sourceColumn;
|
||||
DataSetColumn = dataSetColumn;
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(""),
|
||||
ResCategoryAttribute(Res.DataCategory_Mapping),
|
||||
ResDescriptionAttribute(Res.DataColumnMapping_DataSetColumn),
|
||||
]
|
||||
public string DataSetColumn {
|
||||
get {
|
||||
string dataSetColumnName = _dataSetColumnName;
|
||||
return ((null != dataSetColumnName) ? dataSetColumnName : ADP.StrEmpty);
|
||||
}
|
||||
set {
|
||||
_dataSetColumnName = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal DataColumnMappingCollection Parent {
|
||||
get {
|
||||
return parent;
|
||||
}
|
||||
set {
|
||||
parent = value;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(""),
|
||||
ResCategoryAttribute(Res.DataCategory_Mapping),
|
||||
ResDescriptionAttribute(Res.DataColumnMapping_SourceColumn),
|
||||
]
|
||||
public string SourceColumn {
|
||||
get {
|
||||
string sourceColumnName = _sourceColumnName;
|
||||
return ((null != sourceColumnName) ? sourceColumnName : ADP.StrEmpty);
|
||||
}
|
||||
set {
|
||||
if ((null != Parent) && (0 != ADP.SrcCompare(_sourceColumnName, value))) {
|
||||
Parent.ValidateSourceColumn(-1, value);
|
||||
}
|
||||
_sourceColumnName = value;
|
||||
}
|
||||
}
|
||||
|
||||
object ICloneable.Clone() {
|
||||
DataColumnMapping clone = new DataColumnMapping(); // MDAC 81448
|
||||
clone._sourceColumnName = _sourceColumnName;
|
||||
clone._dataSetColumnName = _dataSetColumnName;
|
||||
return clone;
|
||||
}
|
||||
|
||||
[ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508
|
||||
public DataColumn GetDataColumnBySchemaAction(DataTable dataTable, Type dataType, MissingSchemaAction schemaAction) {
|
||||
return GetDataColumnBySchemaAction(SourceColumn, DataSetColumn, dataTable, dataType, schemaAction);
|
||||
}
|
||||
|
||||
[ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508
|
||||
static public DataColumn GetDataColumnBySchemaAction(string sourceColumn, string dataSetColumn, DataTable dataTable, Type dataType, MissingSchemaAction schemaAction) {
|
||||
if (null == dataTable) {
|
||||
throw ADP.ArgumentNull("dataTable");
|
||||
}
|
||||
if (ADP.IsEmpty(dataSetColumn)) {
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceWarning) {
|
||||
Debug.WriteLine("explicit filtering of SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
DataColumnCollection columns = dataTable.Columns;
|
||||
Debug.Assert(null != columns, "GetDataColumnBySchemaAction: unexpected null DataColumnCollection");
|
||||
|
||||
int index = columns.IndexOf(dataSetColumn);
|
||||
if ((0 <= index) && (index < columns.Count)) {
|
||||
DataColumn dataColumn = columns[index];
|
||||
Debug.Assert(null != dataColumn, "GetDataColumnBySchemaAction: unexpected null dataColumn");
|
||||
|
||||
if (!ADP.IsEmpty(dataColumn.Expression)) {
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceError) {
|
||||
Debug.WriteLine("schema mismatch on DataColumn \"" + dataSetColumn + "\" which is a computed column");
|
||||
}
|
||||
#endif
|
||||
throw ADP.ColumnSchemaExpression(sourceColumn, dataSetColumn);
|
||||
}
|
||||
if ((null == dataType) || (dataType.IsArray == dataColumn.DataType.IsArray)) {
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceInfo) {
|
||||
Debug.WriteLine("schema match on DataColumn \"" + dataSetColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
return dataColumn;
|
||||
}
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceWarning) {
|
||||
Debug.WriteLine("schema mismatch on DataColumn \"" + dataSetColumn + "\" " + dataType.Name + " != " + dataColumn.DataType.Name);
|
||||
}
|
||||
#endif
|
||||
throw ADP.ColumnSchemaMismatch(sourceColumn, dataType, dataColumn);
|
||||
}
|
||||
|
||||
return CreateDataColumnBySchemaAction(sourceColumn, dataSetColumn, dataTable, dataType, schemaAction);
|
||||
}
|
||||
|
||||
static internal DataColumn CreateDataColumnBySchemaAction(string sourceColumn, string dataSetColumn, DataTable dataTable, Type dataType, MissingSchemaAction schemaAction) {
|
||||
Debug.Assert(dataTable != null, "Should not call with a null DataTable");
|
||||
if (ADP.IsEmpty(dataSetColumn)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (schemaAction) {
|
||||
case MissingSchemaAction.Add:
|
||||
case MissingSchemaAction.AddWithKey:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceInfo) {
|
||||
Debug.WriteLine("schema add of DataColumn \"" + dataSetColumn + "\" <" + Convert.ToString(dataType, CultureInfo.InvariantCulture) +">");
|
||||
}
|
||||
#endif
|
||||
return new DataColumn(dataSetColumn, dataType);
|
||||
|
||||
case MissingSchemaAction.Ignore:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceWarning) {
|
||||
Debug.WriteLine("schema filter of DataColumn \"" + dataSetColumn + "\" <" + Convert.ToString(dataType, CultureInfo.InvariantCulture) +">");
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
|
||||
case MissingSchemaAction.Error:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceError) {
|
||||
Debug.WriteLine("schema error on DataColumn \"" + dataSetColumn + "\" <" + Convert.ToString(dataType, CultureInfo.InvariantCulture) +">");
|
||||
}
|
||||
#endif
|
||||
throw ADP.ColumnSchemaMissing(dataSetColumn, dataTable.TableName, sourceColumn);
|
||||
}
|
||||
throw ADP.InvalidMissingSchemaAction(schemaAction);
|
||||
}
|
||||
|
||||
public override String ToString() {
|
||||
return SourceColumn;
|
||||
}
|
||||
|
||||
sealed internal class DataColumnMappingConverter : System.ComponentModel.ExpandableObjectConverter {
|
||||
|
||||
// converter classes should have public ctor
|
||||
public DataColumnMappingConverter() {
|
||||
}
|
||||
|
||||
override public bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
|
||||
if (typeof(InstanceDescriptor) == destinationType) {
|
||||
return true;
|
||||
}
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
|
||||
override public object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
|
||||
if (null == destinationType) {
|
||||
throw ADP.ArgumentNull("destinationType");
|
||||
}
|
||||
|
||||
if ((typeof(InstanceDescriptor) == destinationType) && (value is DataColumnMapping)) {
|
||||
DataColumnMapping mapping = (DataColumnMapping)value;
|
||||
|
||||
object[] values = new object[] { mapping.SourceColumn, mapping.DataSetColumn };
|
||||
Type[] types = new Type[] { typeof(string), typeof(string) };
|
||||
|
||||
ConstructorInfo ctor = typeof(DataColumnMapping).GetConstructor(types);
|
||||
return new InstanceDescriptor(ctor, values);
|
||||
}
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,456 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DataColumnMappingCollection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
|
||||
public sealed class DataColumnMappingCollection : MarshalByRefObject, IColumnMappingCollection {
|
||||
private List<DataColumnMapping> items; // delay creation until AddWithoutEvents, Insert, CopyTo, GetEnumerator
|
||||
|
||||
public DataColumnMappingCollection() {
|
||||
}
|
||||
|
||||
// explicit ICollection implementation
|
||||
bool System.Collections.ICollection.IsSynchronized {
|
||||
get { return false;}
|
||||
}
|
||||
object System.Collections.ICollection.SyncRoot {
|
||||
get { return this;}
|
||||
}
|
||||
|
||||
// explicit IList implementation
|
||||
bool System.Collections.IList.IsReadOnly {
|
||||
get { return false;}
|
||||
}
|
||||
bool System.Collections.IList.IsFixedSize {
|
||||
get { return false;}
|
||||
}
|
||||
object System.Collections.IList.this[int index] {
|
||||
get {
|
||||
return this[index];
|
||||
}
|
||||
set {
|
||||
ValidateType(value);
|
||||
this[index] = (DataColumnMapping) value;
|
||||
}
|
||||
}
|
||||
|
||||
// explicit IColumnMappingCollection implementation
|
||||
object IColumnMappingCollection.this[string index] {
|
||||
get {
|
||||
return this[index];
|
||||
}
|
||||
set {
|
||||
ValidateType(value);
|
||||
this[index] = (DataColumnMapping) value;
|
||||
}
|
||||
}
|
||||
IColumnMapping IColumnMappingCollection.Add(string sourceColumnName, string dataSetColumnName) {
|
||||
return Add(sourceColumnName, dataSetColumnName);
|
||||
}
|
||||
IColumnMapping IColumnMappingCollection.GetByDataSetColumn(string dataSetColumnName) {
|
||||
return GetByDataSetColumn(dataSetColumnName);
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
ResDescriptionAttribute(Res.DataColumnMappings_Count),
|
||||
]
|
||||
public int Count {
|
||||
get {
|
||||
return ((null != items) ? items.Count : 0);
|
||||
}
|
||||
}
|
||||
|
||||
private Type ItemType {
|
||||
get { return typeof(DataColumnMapping); }
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
ResDescriptionAttribute(Res.DataColumnMappings_Item),
|
||||
]
|
||||
public DataColumnMapping this[int index] {
|
||||
get {
|
||||
RangeCheck(index);
|
||||
return items[index];
|
||||
}
|
||||
set {
|
||||
RangeCheck(index);
|
||||
Replace(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
ResDescriptionAttribute(Res.DataColumnMappings_Item),
|
||||
]
|
||||
public DataColumnMapping this[string sourceColumn] {
|
||||
get {
|
||||
int index = RangeCheck(sourceColumn);
|
||||
return items[index];
|
||||
}
|
||||
set {
|
||||
int index = RangeCheck(sourceColumn);
|
||||
Replace(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
public int Add(object value) {
|
||||
ValidateType(value);
|
||||
Add((DataColumnMapping) value);
|
||||
return Count-1;
|
||||
}
|
||||
|
||||
private DataColumnMapping Add(DataColumnMapping value) {
|
||||
AddWithoutEvents(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public DataColumnMapping Add(string sourceColumn, string dataSetColumn) {
|
||||
return Add(new DataColumnMapping(sourceColumn, dataSetColumn));
|
||||
}
|
||||
|
||||
public void AddRange(DataColumnMapping[] values) { // V1.0.3300
|
||||
AddEnumerableRange(values, false);
|
||||
}
|
||||
|
||||
public void AddRange(System.Array values) { // V1.2.3300
|
||||
AddEnumerableRange(values, false);
|
||||
}
|
||||
|
||||
/*/// <include file='doc\DataColumnMappingCollection.uex' path='docs/doc[@for="DataColumnMappingCollection.AddCloneOfRange"]/*' />
|
||||
public void AddCloneOfRange(IEnumerable values) {
|
||||
AddEnumerableRange(values, true);
|
||||
}*/
|
||||
|
||||
private void AddEnumerableRange(IEnumerable values, bool doClone) {
|
||||
if (null == values) {
|
||||
throw ADP.ArgumentNull("values");
|
||||
}
|
||||
foreach(object value in values) {
|
||||
ValidateType(value);
|
||||
}
|
||||
if (doClone) {
|
||||
foreach(ICloneable value in values) {
|
||||
AddWithoutEvents(value.Clone() as DataColumnMapping);
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach(DataColumnMapping value in values) {
|
||||
AddWithoutEvents(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddWithoutEvents(DataColumnMapping value) {
|
||||
Validate(-1, value);
|
||||
value.Parent = this;
|
||||
ArrayList().Add(value);
|
||||
}
|
||||
|
||||
// implemented as a method, not as a property because the VS7 debugger
|
||||
// object browser calls properties to display their value, and we want this delayed
|
||||
private List<DataColumnMapping> ArrayList() {
|
||||
if (null == this.items) {
|
||||
this.items = new List<DataColumnMapping>();
|
||||
}
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
if (0 < Count) {
|
||||
ClearWithoutEvents();
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearWithoutEvents() {
|
||||
if (null != items) {
|
||||
foreach(DataColumnMapping item in items) {
|
||||
item.Parent = null;
|
||||
}
|
||||
items.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(string value) {
|
||||
return(-1 != IndexOf(value));
|
||||
}
|
||||
|
||||
public bool Contains(object value) {
|
||||
return(-1 != IndexOf(value));
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index) {
|
||||
((ICollection)ArrayList()).CopyTo(array, index);
|
||||
}
|
||||
|
||||
public void CopyTo(DataColumnMapping[] array, int index) {
|
||||
ArrayList().CopyTo(array, index);
|
||||
}
|
||||
|
||||
public DataColumnMapping GetByDataSetColumn(string value) {
|
||||
int index = IndexOfDataSetColumn(value);
|
||||
if (0 > index) {
|
||||
throw ADP.ColumnsDataSetColumn(value);
|
||||
}
|
||||
return items[index];
|
||||
}
|
||||
|
||||
public IEnumerator GetEnumerator() {
|
||||
return ArrayList().GetEnumerator();
|
||||
}
|
||||
|
||||
public int IndexOf (object value) {
|
||||
if (null != value) {
|
||||
ValidateType(value);
|
||||
for (int i = 0; i < Count; ++i) {
|
||||
if (items[i] == value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int IndexOf(string sourceColumn) {
|
||||
if (!ADP.IsEmpty(sourceColumn)) {
|
||||
int count = Count;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (0 == ADP.SrcCompare(sourceColumn, items[i].SourceColumn)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int IndexOfDataSetColumn(string dataSetColumn) {
|
||||
if (!ADP.IsEmpty(dataSetColumn)) {
|
||||
int count = Count;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if ( 0 == ADP.DstCompare(dataSetColumn, items[i].DataSetColumn)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Insert(int index, Object value) {
|
||||
ValidateType(value);
|
||||
Insert(index, (DataColumnMapping) value);
|
||||
}
|
||||
|
||||
public void Insert(int index, DataColumnMapping value) {
|
||||
if (null == value) {
|
||||
throw ADP.ColumnsAddNullAttempt("value");
|
||||
}
|
||||
Validate(-1, value);
|
||||
value.Parent = this;
|
||||
ArrayList().Insert(index, value);
|
||||
}
|
||||
|
||||
private void RangeCheck(int index) {
|
||||
if ((index < 0) || (Count <= index)) {
|
||||
throw ADP.ColumnsIndexInt32(index, this);
|
||||
}
|
||||
}
|
||||
|
||||
private int RangeCheck(string sourceColumn) {
|
||||
int index = IndexOf(sourceColumn);
|
||||
if (index < 0) {
|
||||
throw ADP.ColumnsIndexSource(sourceColumn);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public void RemoveAt(int index) {
|
||||
RangeCheck(index);
|
||||
RemoveIndex(index);
|
||||
}
|
||||
|
||||
public void RemoveAt(string sourceColumn) {
|
||||
int index = RangeCheck(sourceColumn);
|
||||
RemoveIndex(index);
|
||||
}
|
||||
|
||||
private void RemoveIndex(int index) {
|
||||
Debug.Assert((null != items) && (0 <= index) && (index < Count), "RemoveIndex, invalid");
|
||||
items[index].Parent = null;
|
||||
items.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void Remove(object value) {
|
||||
ValidateType(value);
|
||||
Remove((DataColumnMapping) value);
|
||||
}
|
||||
|
||||
public void Remove (DataColumnMapping value) {
|
||||
if (null == value) {
|
||||
throw ADP.ColumnsAddNullAttempt ("value");
|
||||
}
|
||||
int index = IndexOf (value);
|
||||
|
||||
if (-1 != index) {
|
||||
RemoveIndex (index);
|
||||
}
|
||||
else {
|
||||
throw ADP.CollectionRemoveInvalidObject(ItemType, this);
|
||||
}
|
||||
}
|
||||
|
||||
private void Replace(int index, DataColumnMapping newValue) {
|
||||
Debug.Assert((null != items) && (0 <= index) && (index < Count), "RemoveIndex, invalid");
|
||||
Validate(index, newValue);
|
||||
items[index].Parent = null;
|
||||
newValue.Parent = this;
|
||||
items[index] = newValue;
|
||||
}
|
||||
|
||||
private void ValidateType(object value) {
|
||||
if (null == value) {
|
||||
throw ADP.ColumnsAddNullAttempt("value");
|
||||
}
|
||||
else if (!ItemType.IsInstanceOfType(value)) {
|
||||
throw ADP.NotADataColumnMapping(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void Validate(int index, DataColumnMapping value) {
|
||||
if (null == value) {
|
||||
throw ADP.ColumnsAddNullAttempt("value");
|
||||
}
|
||||
if (null != value.Parent) {
|
||||
if (this != value.Parent) {
|
||||
throw ADP.ColumnsIsNotParent(this);
|
||||
}
|
||||
else if (index != IndexOf(value)) {
|
||||
throw ADP.ColumnsIsParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
String name = value.SourceColumn;
|
||||
if (ADP.IsEmpty(name)) {
|
||||
index = 1;
|
||||
do {
|
||||
name = ADP.SourceColumn + index.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
index++;
|
||||
} while (-1 != IndexOf(name));
|
||||
value.SourceColumn = name;
|
||||
}
|
||||
else {
|
||||
ValidateSourceColumn(index, name);
|
||||
}
|
||||
}
|
||||
|
||||
internal void ValidateSourceColumn(int index, string value) {
|
||||
int pindex = IndexOf(value);
|
||||
if ((-1 != pindex) && (index != pindex)) { // must be non-null and unique
|
||||
throw ADP.ColumnsUniqueSourceColumn(value);
|
||||
}
|
||||
}
|
||||
|
||||
[ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508
|
||||
static public DataColumn GetDataColumn(DataColumnMappingCollection columnMappings, string sourceColumn, Type dataType, DataTable dataTable, MissingMappingAction mappingAction, MissingSchemaAction schemaAction) {
|
||||
if (null != columnMappings) {
|
||||
int index = columnMappings.IndexOf(sourceColumn);
|
||||
if (-1 != index) {
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceInfo) {
|
||||
Debug.WriteLine("mapping match on SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
return columnMappings.items[index].GetDataColumnBySchemaAction(dataTable, dataType, schemaAction);
|
||||
}
|
||||
}
|
||||
if (ADP.IsEmpty(sourceColumn)) {
|
||||
throw ADP.InvalidSourceColumn("sourceColumn");
|
||||
}
|
||||
switch (mappingAction) {
|
||||
case MissingMappingAction.Passthrough:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceInfo) {
|
||||
Debug.WriteLine("mapping passthrough of SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
return DataColumnMapping.GetDataColumnBySchemaAction(sourceColumn, sourceColumn, dataTable, dataType, schemaAction);
|
||||
|
||||
case MissingMappingAction.Ignore:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceWarning) {
|
||||
Debug.WriteLine("mapping filter of SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
|
||||
case MissingMappingAction.Error:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceError) {
|
||||
Debug.WriteLine("mapping error on SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
throw ADP.MissingColumnMapping(sourceColumn);
|
||||
}
|
||||
throw ADP.InvalidMissingMappingAction(mappingAction);
|
||||
}
|
||||
|
||||
[ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508
|
||||
static public DataColumnMapping GetColumnMappingBySchemaAction(DataColumnMappingCollection columnMappings, string sourceColumn, MissingMappingAction mappingAction) {
|
||||
if (null != columnMappings) {
|
||||
int index = columnMappings.IndexOf(sourceColumn);
|
||||
if (-1 != index) {
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceInfo) {
|
||||
Debug.WriteLine("mapping match on SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
return columnMappings.items[index];
|
||||
}
|
||||
}
|
||||
if (ADP.IsEmpty(sourceColumn)) {
|
||||
throw ADP.InvalidSourceColumn("sourceColumn");
|
||||
}
|
||||
switch (mappingAction) {
|
||||
case MissingMappingAction.Passthrough:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceInfo) {
|
||||
Debug.WriteLine("mapping passthrough of SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
return new DataColumnMapping(sourceColumn, sourceColumn);
|
||||
|
||||
case MissingMappingAction.Ignore:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceWarning) {
|
||||
Debug.WriteLine("mapping filter of SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
|
||||
case MissingMappingAction.Error:
|
||||
#if DEBUG
|
||||
if (AdapterSwitches.DataSchema.TraceError) {
|
||||
Debug.WriteLine("mapping error on SourceColumn \"" + sourceColumn + "\"");
|
||||
}
|
||||
#endif
|
||||
throw ADP.MissingColumnMapping(sourceColumn);
|
||||
}
|
||||
throw ADP.InvalidMissingMappingAction(mappingAction);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,346 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DataRecordInternal.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.ProviderBase;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
internal sealed class DataRecordInternal : DbDataRecord, ICustomTypeDescriptor {
|
||||
private SchemaInfo[] _schemaInfo;
|
||||
private object[] _values;
|
||||
private PropertyDescriptorCollection _propertyDescriptors;
|
||||
private FieldNameLookup _fieldNameLookup; // MDAC 69015
|
||||
|
||||
// copy all runtime data information
|
||||
internal DataRecordInternal(SchemaInfo[] schemaInfo, object[] values, PropertyDescriptorCollection descriptors, FieldNameLookup fieldNameLookup) {
|
||||
Debug.Assert(null != schemaInfo, "invalid attempt to instantiate DataRecordInternal with null schema information");
|
||||
Debug.Assert(null != values, "invalid attempt to instantiate DataRecordInternal with null value[]");
|
||||
_schemaInfo = schemaInfo;
|
||||
_values = values;
|
||||
_propertyDescriptors = descriptors;
|
||||
_fieldNameLookup = fieldNameLookup;
|
||||
}
|
||||
|
||||
// copy all runtime data information
|
||||
internal DataRecordInternal(object[] values, PropertyDescriptorCollection descriptors, FieldNameLookup fieldNameLookup) {
|
||||
Debug.Assert(null != values, "invalid attempt to instantiate DataRecordInternal with null value[]");
|
||||
_values = values;
|
||||
_propertyDescriptors = descriptors;
|
||||
_fieldNameLookup = fieldNameLookup;
|
||||
}
|
||||
|
||||
internal void SetSchemaInfo(SchemaInfo[] schemaInfo) {
|
||||
Debug.Assert(null == _schemaInfo, "invalid attempt to override DataRecordInternal schema information");
|
||||
_schemaInfo = schemaInfo;
|
||||
}
|
||||
|
||||
public override int FieldCount {
|
||||
get {
|
||||
return _schemaInfo.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetValues(object[] values) {
|
||||
if (null == values) {
|
||||
throw ADP.ArgumentNull("values");
|
||||
}
|
||||
|
||||
int copyLen = (values.Length < _schemaInfo.Length) ? values.Length : _schemaInfo.Length;
|
||||
for (int i = 0; i < copyLen; i++) {
|
||||
values[i] = _values[i];
|
||||
}
|
||||
return copyLen;
|
||||
}
|
||||
|
||||
public override string GetName(int i) {
|
||||
return _schemaInfo[i].name;
|
||||
}
|
||||
|
||||
|
||||
public override object GetValue(int i) {
|
||||
return _values[i];
|
||||
}
|
||||
|
||||
public override string GetDataTypeName(int i) {
|
||||
return _schemaInfo[i].typeName;
|
||||
}
|
||||
|
||||
public override Type GetFieldType(int i) {
|
||||
return _schemaInfo[i].type;
|
||||
}
|
||||
|
||||
public override int GetOrdinal(string name) { // MDAC 69015
|
||||
return _fieldNameLookup.GetOrdinal(name); // MDAC 71470
|
||||
}
|
||||
|
||||
public override object this[int i] {
|
||||
get {
|
||||
return GetValue(i);
|
||||
}
|
||||
}
|
||||
|
||||
public override object this[string name] {
|
||||
get {
|
||||
return GetValue(GetOrdinal(name));
|
||||
}
|
||||
}
|
||||
|
||||
public override bool GetBoolean(int i) {
|
||||
return((bool) _values[i]);
|
||||
}
|
||||
|
||||
public override byte GetByte(int i) {
|
||||
return((byte) _values[i]);
|
||||
}
|
||||
|
||||
public override long GetBytes(int i, long dataIndex, byte[] buffer, int bufferIndex, int length) {
|
||||
int cbytes = 0;
|
||||
int ndataIndex;
|
||||
|
||||
byte[] data = (byte[])_values[i];
|
||||
|
||||
cbytes = data.Length;
|
||||
|
||||
// since arrays can't handle 64 bit values and this interface doesn't
|
||||
// allow chunked access to data, a dataIndex outside the rang of Int32
|
||||
// is invalid
|
||||
if (dataIndex > Int32.MaxValue) {
|
||||
throw ADP.InvalidSourceBufferIndex(cbytes, dataIndex, "dataIndex");
|
||||
}
|
||||
|
||||
ndataIndex = (int)dataIndex;
|
||||
|
||||
// if no buffer is passed in, return the number of characters we have
|
||||
if (null == buffer)
|
||||
return cbytes;
|
||||
|
||||
try {
|
||||
if (ndataIndex < cbytes) {
|
||||
// help the user out in the case where there's less data than requested
|
||||
if ((ndataIndex + length) > cbytes)
|
||||
cbytes = cbytes - ndataIndex;
|
||||
else
|
||||
cbytes = length;
|
||||
}
|
||||
|
||||
// until arrays are 64 bit, we have to do these casts
|
||||
Array.Copy(data, ndataIndex, buffer, bufferIndex, (int)cbytes);
|
||||
}
|
||||
catch (Exception e) {
|
||||
//
|
||||
if (ADP.IsCatchableExceptionType(e)) {
|
||||
cbytes = data.Length;
|
||||
|
||||
if (length < 0)
|
||||
throw ADP.InvalidDataLength(length);
|
||||
|
||||
// if bad buffer index, throw
|
||||
if (bufferIndex < 0 || bufferIndex >= buffer.Length)
|
||||
throw ADP.InvalidDestinationBufferIndex(length, bufferIndex, "bufferIndex");
|
||||
|
||||
// if bad data index, throw
|
||||
if (dataIndex < 0 || dataIndex >= cbytes)
|
||||
throw ADP.InvalidSourceBufferIndex(length, dataIndex, "dataIndex");
|
||||
|
||||
// if there is not enough room in the buffer for data
|
||||
if (cbytes + bufferIndex > buffer.Length)
|
||||
throw ADP.InvalidBufferSizeOrIndex(cbytes, bufferIndex);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return cbytes;
|
||||
}
|
||||
|
||||
public override char GetChar(int i) {
|
||||
string s;
|
||||
|
||||
s = (string)_values[i];
|
||||
char[] c = s.ToCharArray();
|
||||
return c[0];
|
||||
}
|
||||
|
||||
public override long GetChars(int i, long dataIndex, char[] buffer, int bufferIndex, int length) {
|
||||
int cchars = 0;
|
||||
string s;
|
||||
int ndataIndex;
|
||||
|
||||
// if the object doesn't contain a char[] then the user will get an exception
|
||||
s = (string)_values[i];
|
||||
|
||||
char[] data = s.ToCharArray();
|
||||
|
||||
cchars = data.Length;
|
||||
|
||||
// since arrays can't handle 64 bit values and this interface doesn't
|
||||
// allow chunked access to data, a dataIndex outside the rang of Int32
|
||||
// is invalid
|
||||
if (dataIndex > Int32.MaxValue) {
|
||||
throw ADP.InvalidSourceBufferIndex(cchars, dataIndex, "dataIndex");
|
||||
}
|
||||
|
||||
ndataIndex = (int)dataIndex;
|
||||
|
||||
|
||||
// if no buffer is passed in, return the number of characters we have
|
||||
if (null == buffer)
|
||||
return cchars;
|
||||
|
||||
try {
|
||||
if (ndataIndex < cchars) {
|
||||
// help the user out in the case where there's less data than requested
|
||||
if ((ndataIndex + length) > cchars)
|
||||
cchars = cchars - ndataIndex;
|
||||
else
|
||||
cchars = length;
|
||||
}
|
||||
|
||||
Array.Copy(data, ndataIndex, buffer, bufferIndex, cchars);
|
||||
}
|
||||
catch (Exception e) {
|
||||
//
|
||||
if (ADP.IsCatchableExceptionType(e)) {
|
||||
cchars = data.Length;
|
||||
|
||||
if (length < 0)
|
||||
throw ADP.InvalidDataLength(length);
|
||||
|
||||
// if bad buffer index, throw
|
||||
if (bufferIndex < 0 || bufferIndex >= buffer.Length)
|
||||
throw ADP.InvalidDestinationBufferIndex(buffer.Length, bufferIndex, "bufferIndex");
|
||||
|
||||
// if bad data index, throw
|
||||
if (ndataIndex < 0 || ndataIndex >= cchars)
|
||||
throw ADP.InvalidSourceBufferIndex(cchars, dataIndex, "dataIndex");
|
||||
|
||||
// if there is not enough room in the buffer for data
|
||||
if (cchars + bufferIndex > buffer.Length)
|
||||
throw ADP.InvalidBufferSizeOrIndex(cchars, bufferIndex);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return cchars;
|
||||
}
|
||||
|
||||
public override Guid GetGuid(int i) {
|
||||
return ((Guid)_values[i]);
|
||||
}
|
||||
|
||||
|
||||
public override Int16 GetInt16(int i) {
|
||||
return((Int16) _values[i]);
|
||||
}
|
||||
|
||||
public override Int32 GetInt32(int i) {
|
||||
return((Int32) _values[i]);
|
||||
}
|
||||
|
||||
public override Int64 GetInt64(int i) {
|
||||
return((Int64) _values[i]);
|
||||
}
|
||||
|
||||
public override float GetFloat(int i) {
|
||||
return((float) _values[i]);
|
||||
}
|
||||
|
||||
public override double GetDouble(int i) {
|
||||
return((double) _values[i]);
|
||||
}
|
||||
|
||||
public override string GetString(int i) {
|
||||
return((string) _values[i]);
|
||||
}
|
||||
|
||||
public override Decimal GetDecimal(int i) {
|
||||
return((Decimal) _values[i]);
|
||||
}
|
||||
|
||||
public override DateTime GetDateTime(int i) {
|
||||
return((DateTime) _values[i]);
|
||||
}
|
||||
|
||||
public override bool IsDBNull(int i) {
|
||||
object o = _values[i];
|
||||
return (null == o || Convert.IsDBNull(o));
|
||||
}
|
||||
|
||||
//
|
||||
// ICustomTypeDescriptor
|
||||
//
|
||||
|
||||
AttributeCollection ICustomTypeDescriptor.GetAttributes() {
|
||||
return new AttributeCollection((Attribute[])null);
|
||||
|
||||
}
|
||||
|
||||
string ICustomTypeDescriptor.GetClassName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
string ICustomTypeDescriptor.GetComponentName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeConverter ICustomTypeDescriptor.GetConverter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
object ICustomTypeDescriptor.GetEditor(Type editorBaseType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EventDescriptorCollection ICustomTypeDescriptor.GetEvents() {
|
||||
return new EventDescriptorCollection(null);
|
||||
}
|
||||
|
||||
EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) {
|
||||
return new EventDescriptorCollection(null);
|
||||
}
|
||||
|
||||
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() {
|
||||
return((ICustomTypeDescriptor)this).GetProperties(null);
|
||||
}
|
||||
|
||||
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) {
|
||||
if(_propertyDescriptors == null) {
|
||||
_propertyDescriptors = new PropertyDescriptorCollection(null);
|
||||
}
|
||||
return _propertyDescriptors;
|
||||
}
|
||||
|
||||
object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// this doesn't change per record, only alloc once
|
||||
internal struct SchemaInfo {
|
||||
public string name;
|
||||
public string typeName;
|
||||
public Type type;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user