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,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="AcceptRejectRule.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">amirhmy</owner>
|
||||
// <owner current="true" primary="false">markash</owner>
|
||||
// <owner current="false" primary="false">jasonzhu</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
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="AggregateType.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">amirhmy</owner>
|
||||
// <owner current="true" primary="false">markash</owner>
|
||||
// <owner current="false" primary="false">jasonzhu</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
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CatalogLocation.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>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data.Common {
|
||||
|
||||
using System;
|
||||
|
||||
public enum CatalogLocation { // V1.2.3300, MDAC 79449
|
||||
Start = 1,
|
||||
End = 2,
|
||||
}
|
||||
}
|
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CommandBehavior.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>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
// UNDONE: SingleRow = 8 | SingleResult,
|
||||
SingleRow = 8, // data, hint single row and single result, may affect database - doesn't apply to child(chapter) results
|
||||
SequentialAccess = 0x10,
|
||||
CloseConnection = 0x20,
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CommandType.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>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Data {
|
||||
|
||||
public enum CommandType {
|
||||
Text = 0x1,
|
||||
//Table = 0x2,
|
||||
StoredProcedure = 0x4,
|
||||
//File = 0x100,
|
||||
TableDirect = 0x200,
|
||||
}
|
||||
}
|
@@ -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]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user