Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <copyright file="AcceptRejectRule.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 {
public enum AcceptRejectRule {
/// <devdoc>
/// <para>
/// No action occurs.
/// </para>
/// </devdoc>
None = 0,
/// <devdoc>
/// <para>
/// Changes are cascaded across the relationship.
/// </para>
/// </devdoc>
Cascade = 1
}
}

View File

@@ -0,0 +1,53 @@
//------------------------------------------------------------------------------
// <copyright file="AggregateType.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 {
/// <devdoc>
/// <para>Specifies the aggregate function type.</para>
/// </devdoc>
internal enum AggregateType {
/// <devdoc>
/// <para>None.</para>
/// </devdoc>
None = 0,
/// <devdoc>
/// <para>Sum.</para>
/// </devdoc>
Sum = 4,
/// <devdoc>
/// <para>Average value of the aggregate set.</para>
/// </devdoc>
Mean = 5,
/// <devdoc>
/// <para>The minimum value of the set.</para>
/// </devdoc>
Min = 6,
/// <devdoc>
/// <para>The maximum value of the set.</para>
/// </devdoc>
Max = 7,
/// <devdoc>
/// <para>First element of the set.</para>
/// </devdoc>
First = 8,
/// <devdoc>
/// <para>The count of the set.</para>
/// </devdoc>
Count = 9,
/// <devdoc>
/// <para>Variance.</para>
/// </devdoc>
Var = 10,
/// <devdoc>
/// <para>Standard deviation.</para>
/// </devdoc>
StDev = 11
}
}

View File

@@ -0,0 +1,99 @@
//------------------------------------------------------------------------------
// <copyright file="BaseCollection.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 {
using System;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
/// <devdoc>
/// <para>Provides the base functionality for creating collections.</para>
/// </devdoc>
public class InternalDataCollectionBase : ICollection {
internal static CollectionChangeEventArgs RefreshEventArgs = new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null);
//==================================================
// the ICollection methods
//==================================================
/// <devdoc>
/// <para>Gets the total number of elements in a collection.</para>
/// </devdoc>
[
Browsable(false)
]
public virtual int Count {
get {
return List.Count;
}
}
public virtual void CopyTo(Array ar, int index) {
List.CopyTo(ar, index);
}
public virtual IEnumerator GetEnumerator() {
return List.GetEnumerator();
}
[
Browsable(false)
]
public bool IsReadOnly {
get {
return false;
}
}
[Browsable(false)]
public bool IsSynchronized {
get {
// so the user will know that it has to lock this object
return false;
}
}
// Return value:
// > 0 (1) : CaseSensitve equal
// < 0 (-1) : Case-Insensitive Equal
// = 0 : Not Equal
internal int NamesEqual(string s1, string s2, bool fCaseSensitive, CultureInfo locale) {
if (fCaseSensitive) {
if (String.Compare(s1, s2, false, locale) == 0)
return 1;
else
return 0;
}
// Case, kana and width -Insensitive compare
if (locale.CompareInfo.Compare(s1, s2,
CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth) == 0) {
if (String.Compare(s1, s2, false, locale) == 0)
return 1;
else
return -1;
}
return 0;
}
[Browsable(false)]
public object SyncRoot {
get {
return this;
}
}
protected virtual ArrayList List {
get {
return null;
}
}
}
}

View File

@@ -0,0 +1,17 @@
//------------------------------------------------------------------------------
// <copyright file="CatalogLocation.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;
public enum CatalogLocation { // V1.2.3300, MDAC 79449
Start = 1,
End = 2,
}
}

View File

@@ -0,0 +1,115 @@
//------------------------------------------------------------------------------
// <copyright file="StrongTypingException.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 {
using System;
using System.Collections;
using System.Data;
using System.Runtime.Serialization;
/// <devdoc>
/// <para>DEV: The exception that is throwing from strong typed DataSet when user access to DBNull value.</para>
/// </devdoc>
[Serializable]
public class StrongTypingException : DataException {
protected StrongTypingException(SerializationInfo info, StreamingContext context)
: base(info, context) {
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public StrongTypingException() : base() {
HResult = HResults.StrongTyping;
}
public StrongTypingException(string message) : base(message) {
HResult = HResults.StrongTyping;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public StrongTypingException(string s, Exception innerException) : base(s, innerException) {
HResult = HResults.StrongTyping;
}
}
/// <devdoc>
/// <para>DEV: The exception that is throwing in generating strong typed DataSet when name conflict happens.</para>
/// </devdoc>
[Serializable]
public class TypedDataSetGeneratorException : DataException {
private ArrayList errorList;
private string KEY_ARRAYCOUNT = "KEY_ARRAYCOUNT";
private string KEY_ARRAYVALUES = "KEY_ARRAYVALUES";
protected TypedDataSetGeneratorException(SerializationInfo info, StreamingContext context)
: base(info, context) {
int count = (int) info.GetValue(KEY_ARRAYCOUNT, typeof(System.Int32));
if (count > 0) {
errorList = new ArrayList();
for (int i = 0; i < count; i++) {
errorList.Add(info.GetValue(KEY_ARRAYVALUES + i, typeof(System.String)));
}
}
else
errorList = null;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public TypedDataSetGeneratorException() : base() {
errorList = null;
HResult = HResults.StrongTyping;
}
public TypedDataSetGeneratorException(string message) : base(message) {
HResult = HResults.StrongTyping;
}
public TypedDataSetGeneratorException(string message, Exception innerException) : base(message, innerException) {
HResult = HResults.StrongTyping;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public TypedDataSetGeneratorException(ArrayList list) : this() {
errorList = list;
HResult = HResults.StrongTyping;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public ArrayList ErrorList {
get {
return errorList;
}
}
[System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags=System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
if (errorList != null) {
info.AddValue(KEY_ARRAYCOUNT, errorList.Count);
for (int i = 0; i < errorList.Count; i++) {
info.AddValue(KEY_ARRAYVALUES + i, errorList[i].ToString());
}
}
else {
info.AddValue(KEY_ARRAYCOUNT, 0);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,173 @@
//------------------------------------------------------------------------------
// <copyright file="ColumnTypeConverter.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 {
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Globalization;
using System.Data.SqlTypes;
/// <devdoc>
/// <para>Provides a type
/// converter that can be used to populate a list box with available types.</para>
/// </devdoc>
internal sealed class ColumnTypeConverter : TypeConverter {
private static Type[] types = new Type[] {
typeof(Boolean),
typeof(Byte),
typeof(Byte[]),
typeof(Char),
typeof(DateTime),
typeof(Decimal),
typeof(Double),
typeof(Guid),
typeof(Int16),
typeof(Int32),
typeof(Int64),
typeof(object),
typeof(SByte),
typeof(Single),
typeof(string),
typeof(TimeSpan),
typeof(UInt16),
typeof(UInt32),
typeof(UInt64),
typeof(SqlInt16),
typeof(SqlInt32),
typeof(SqlInt64),
typeof(SqlDecimal),
typeof(SqlSingle),
typeof(SqlDouble),
typeof(SqlString),
typeof(SqlBoolean),
typeof(SqlBinary),
typeof(SqlByte),
typeof(SqlDateTime),
typeof(SqlGuid),
typeof(SqlMoney),
typeof(SqlBytes),
typeof(SqlChars),
typeof(SqlXml)
};
private StandardValuesCollection values;
// converter classes should have public ctor
public ColumnTypeConverter() {
}
/// <devdoc>
/// <para>Gets a value indicating whether this converter can
/// convert an object to the given destination type using the context.</para>
/// </devdoc>
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
if (destinationType == typeof(InstanceDescriptor)) {
return true;
}
return base.CanConvertTo(context, destinationType);
}
/// <devdoc>
/// <para>Converts the given value object to the specified destination type.</para>
/// </devdoc>
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
if (destinationType == null) {
throw new ArgumentNullException("destinationType");
}
if (destinationType == typeof(string)) {
if (value == null) {
return String.Empty;
}
else {
value.ToString();
}
}
if (value != null && destinationType == typeof(InstanceDescriptor)) {
Object newValue = value;
if (value is string) {
for (int i = 0; i < types.Length; i++) {
if (types[i].ToString().Equals(value))
newValue = types[i];
}
}
if (value is Type || value is string) {
System.Reflection.MethodInfo method = typeof(Type).GetMethod("GetType", new Type[] {typeof(string)}); // change done for security review
if (method != null) {
return new InstanceDescriptor(method, new object[] {((Type)newValue).AssemblyQualifiedName});
}
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
if (sourceType == typeof(string)) {
return true;
}
return base.CanConvertTo(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
if (value != null && value.GetType() == typeof(string)) {
for (int i = 0; i < types.Length; i++) {
if (types[i].ToString().Equals(value))
return types[i];
}
return typeof(string);
}
return base.ConvertFrom(context, culture, value);
}
/// <devdoc>
/// <para>Gets a collection of standard values for the data type this validator is
/// designed for.</para>
/// </devdoc>
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {
if (values == null) {
object[] objTypes;
if (types != null) {
objTypes = new object[types.Length];
Array.Copy(types, objTypes, types.Length);
}
else {
objTypes = null;
}
values = new StandardValuesCollection(objTypes);
}
return values;
}
/// <devdoc>
/// <para>Gets a value indicating whether the list of standard values returned from
/// <see cref='System.ComponentModel.TypeListConverter.GetStandardValues'/> is an exclusive list. </para>
/// </devdoc>
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {
return true;
}
/// <devdoc>
/// <para>Gets a value indicating whether this object supports a
/// standard set of values that can be picked from a list using the specified
/// context.</para>
/// </devdoc>
public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
return true;
}
}
}

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <copyright file="CommandBehavior.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 {
[Flags()]
public enum CommandBehavior {
Default = 0, // with data, multiple results, may affect database, MDAC 68240
SingleResult = 1, // with data, force single result, may affect database
SchemaOnly = 2, // column info, no data, no effect on database
KeyInfo = 4, // column info + primary key information (if available)
//
SingleRow = 8, // data, hint single row and single result, may affect database - doesn't apply to child(chapter) results
SequentialAccess = 0x10,
CloseConnection = 0x20,
}
}

View File

@@ -0,0 +1,18 @@
//------------------------------------------------------------------------------
// <copyright file="CommandType.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 {
public enum CommandType {
Text = 0x1,
//Table = 0x2,
StoredProcedure = 0x4,
//File = 0x100,
TableDirect = 0x200,
}
}

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <copyright file="AdapterSwitches.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
// <owner current="true" primary="false">[....]</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

View File

@@ -0,0 +1 @@
71092075d227694f12a3b1b21c6ca70412849015

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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]));
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More