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,62 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ExtendedClrTypeCode.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">alazela</owner>
|
||||
// <owner current="true" primary="false">stevesta</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
internal enum ExtendedClrTypeCode {
|
||||
Invalid = -1,
|
||||
Boolean, // System.Boolean
|
||||
Byte, // System.Byte
|
||||
Char, // System.Char
|
||||
DateTime, // System.DateTime
|
||||
DBNull, // System.DBNull
|
||||
Decimal, // System.Decimal
|
||||
Double, // System.Double
|
||||
Empty, // null reference
|
||||
Int16, // System.Int16
|
||||
Int32, // System.Int32
|
||||
Int64, // System.Int64
|
||||
SByte, // System.SByte
|
||||
Single, // System.Single
|
||||
String, // System.String
|
||||
UInt16, // System.UInt16
|
||||
UInt32, // System.UInt32
|
||||
UInt64, // System.UInt64
|
||||
Object, // System.Object
|
||||
ByteArray, // System.ByteArray
|
||||
CharArray, // System.CharArray
|
||||
Guid, // System.Guid
|
||||
SqlBinary, // System.Data.SqlTypes.SqlBinary
|
||||
SqlBoolean, // System.Data.SqlTypes.SqlBoolean
|
||||
SqlByte, // System.Data.SqlTypes.SqlByte
|
||||
SqlDateTime, // System.Data.SqlTypes.SqlDateTime
|
||||
SqlDouble, // System.Data.SqlTypes.SqlDouble
|
||||
SqlGuid, // System.Data.SqlTypes.SqlGuid
|
||||
SqlInt16, // System.Data.SqlTypes.SqlInt16
|
||||
SqlInt32, // System.Data.SqlTypes.SqlInt32
|
||||
SqlInt64, // System.Data.SqlTypes.SqlInt64
|
||||
SqlMoney, // System.Data.SqlTypes.SqlMoney
|
||||
SqlDecimal, // System.Data.SqlTypes.SqlDecimal
|
||||
SqlSingle, // System.Data.SqlTypes.SqlSingle
|
||||
SqlString, // System.Data.SqlTypes.SqlString
|
||||
SqlChars, // System.Data.SqlTypes.SqlChars
|
||||
SqlBytes, // System.Data.SqlTypes.SqlBytes
|
||||
SqlXml, // System.Data.SqlTypes.SqlXml
|
||||
DataTable, // System.Data.DataTable
|
||||
DbDataReader, // System.Data.DbDataReader (SqlDataReader falls under this category)
|
||||
IEnumerableOfSqlDataRecord, // System.Collections.Generic.IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord>
|
||||
TimeSpan, // System.TimeSpan
|
||||
DateTimeOffset, // System.DateTimeOffset
|
||||
Stream, // System.IO.Stream
|
||||
TextReader, // System.IO.TextReader
|
||||
XmlReader, // System.Xml.XmlReader
|
||||
Last = XmlReader, // end-of-enum marker
|
||||
First = Boolean, // beginning-of-enum marker
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ITypedGetters.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">alazela</owner>
|
||||
// <owner current="true" primary="false">stevesta</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SqlTypes;
|
||||
|
||||
// Interface for strongly-typed value getters
|
||||
internal interface ITypedGetters {
|
||||
|
||||
// Null test
|
||||
bool IsDBNull( int ordinal );
|
||||
|
||||
// Check what type current sql_variant value is
|
||||
SqlDbType GetVariantType( int ordinal );
|
||||
|
||||
// By value accessors (data copy across the interface boundary implied)
|
||||
Boolean GetBoolean( int ordinal );
|
||||
|
||||
Byte GetByte( int ordinal );
|
||||
|
||||
Int64 GetBytes( int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length );
|
||||
|
||||
Char GetChar( int ordinal );
|
||||
|
||||
Int64 GetChars( int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length );
|
||||
|
||||
Int16 GetInt16( int ordinal );
|
||||
|
||||
Int32 GetInt32( int ordinal );
|
||||
|
||||
Int64 GetInt64( int ordinal );
|
||||
|
||||
Single GetFloat( int ordinal );
|
||||
|
||||
Double GetDouble( int ordinal );
|
||||
|
||||
String GetString( int ordinal );
|
||||
|
||||
Decimal GetDecimal( int ordinal );
|
||||
|
||||
DateTime GetDateTime( int ordinal );
|
||||
|
||||
Guid GetGuid( int ordinal );
|
||||
|
||||
SqlBoolean GetSqlBoolean( int ordinal );
|
||||
|
||||
SqlByte GetSqlByte( int ordinal );
|
||||
|
||||
SqlInt16 GetSqlInt16( int ordinal );
|
||||
|
||||
SqlInt32 GetSqlInt32( int ordinal );
|
||||
|
||||
SqlInt64 GetSqlInt64( int ordinal );
|
||||
|
||||
SqlSingle GetSqlSingle( int ordinal );
|
||||
|
||||
SqlDouble GetSqlDouble( int ordinal );
|
||||
|
||||
SqlMoney GetSqlMoney( int ordinal );
|
||||
|
||||
SqlDateTime GetSqlDateTime( int ordinal );
|
||||
|
||||
SqlDecimal GetSqlDecimal( int ordinal );
|
||||
|
||||
SqlString GetSqlString( int ordinal );
|
||||
|
||||
SqlBinary GetSqlBinary( int ordinal );
|
||||
|
||||
SqlGuid GetSqlGuid( int ordinal );
|
||||
|
||||
SqlChars GetSqlChars( int ordinal );
|
||||
|
||||
SqlBytes GetSqlBytes( int ordinal );
|
||||
|
||||
SqlXml GetSqlXml( int ordinal );
|
||||
|
||||
|
||||
// "By reference" accessors
|
||||
// May hook to buffer.
|
||||
// Semantics guarantee is that as long as the object exposing the accessor is not logically
|
||||
// moved to a new set of values and the overall state (open/closed) isn't changed, it will not
|
||||
// change the underlying value returned and continue to allow access to it.
|
||||
//
|
||||
// Example: GetSqlCharsRef called on an event stream value. The back-end optimizes by re-using
|
||||
// the buffer wrapped by the returned SqlChars on the next row event, but guarantees that it
|
||||
// won't change the value until the next event is consumed.
|
||||
//
|
||||
// Simplest way to guarantee this behavior is to simply call the corresponding by-value accessor.
|
||||
SqlBytes GetSqlBytesRef( int ordinal );
|
||||
|
||||
SqlChars GetSqlCharsRef( int ordinal );
|
||||
|
||||
SqlXml GetSqlXmlRef( int ordinal );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ITypedGettersV3.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">alazela</owner>
|
||||
// <owner current="true" primary="false">stevesta</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SqlTypes;
|
||||
|
||||
// Interface for strongly-typed value getters
|
||||
internal interface ITypedGettersV3 {
|
||||
|
||||
// Null test
|
||||
// valid for all types
|
||||
bool IsDBNull( SmiEventSink sink, int ordinal );
|
||||
|
||||
// Check what type current sql_variant value is
|
||||
// valid for SqlDbType.Variant
|
||||
SmiMetaData GetVariantType( SmiEventSink sink, int ordinal );
|
||||
|
||||
//
|
||||
// Actual value accessors
|
||||
// valid type indicates column must be of the type or column must be variant
|
||||
// and GetVariantType returned the type
|
||||
//
|
||||
|
||||
// valid for SqlDbType.Bit
|
||||
Boolean GetBoolean( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbType.TinyInt
|
||||
Byte GetByte( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbTypes: Binary, VarBinary, Image, Udt, Xml, Char, VarChar, Text, NChar, NVarChar, NText
|
||||
// (Character type support needed for ExecuteXmlReader handling)
|
||||
Int64 GetBytesLength( SmiEventSink sink, int ordinal );
|
||||
int GetBytes( SmiEventSink sink, int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length );
|
||||
|
||||
// valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
|
||||
Int64 GetCharsLength( SmiEventSink sink, int ordinal );
|
||||
int GetChars( SmiEventSink sink, int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length );
|
||||
String GetString( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbType.SmallInt
|
||||
Int16 GetInt16( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbType.Int
|
||||
Int32 GetInt32( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbType.BigInt, SqlDbType.Money, SqlDbType.SmallMoney
|
||||
Int64 GetInt64( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbType.Real
|
||||
Single GetSingle( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbType.Float
|
||||
Double GetDouble( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbType.Numeric (uses SqlDecimal since Decimal cannot hold full range)
|
||||
SqlDecimal GetSqlDecimal( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for DateTime & SmallDateTime
|
||||
DateTime GetDateTime( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for UniqueIdentifier
|
||||
Guid GetGuid( SmiEventSink sink, int ordinal );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ITypedSetters.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">alazela</owner>
|
||||
// <owner current="true" primary="false">stevesta</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
|
||||
// interface for strongly-typed value setters
|
||||
internal interface ITypedSetters {
|
||||
|
||||
// By value setters (data copy across the interface boundary implied)
|
||||
void SetDBNull( int ordinal );
|
||||
|
||||
void SetBoolean( int ordinal, Boolean value );
|
||||
|
||||
void SetByte( int ordinal, Byte value );
|
||||
|
||||
void SetBytes( int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length );
|
||||
|
||||
void SetChar( int ordinal, char value );
|
||||
|
||||
void SetChars( int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length );
|
||||
|
||||
void SetInt16( int ordinal, Int16 value );
|
||||
|
||||
void SetInt32( int ordinal, Int32 value );
|
||||
|
||||
void SetInt64( int ordinal, Int64 value );
|
||||
|
||||
void SetFloat( int ordinal, Single value );
|
||||
|
||||
void SetDouble( int ordinal, Double value );
|
||||
|
||||
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use setter with offset." )]
|
||||
void SetString( int ordinal, string value );
|
||||
|
||||
// Method introduced as of SMI V2
|
||||
void SetString( int ordinal, string value, int offset );
|
||||
|
||||
void SetDecimal( int ordinal, Decimal value );
|
||||
|
||||
void SetDateTime( int ordinal, DateTime value );
|
||||
|
||||
void SetGuid( int ordinal, Guid value );
|
||||
|
||||
void SetSqlBoolean( int ordinal, SqlBoolean value );
|
||||
|
||||
void SetSqlByte( int ordinal, SqlByte value );
|
||||
|
||||
void SetSqlInt16( int ordinal, SqlInt16 value );
|
||||
|
||||
void SetSqlInt32( int ordinal, SqlInt32 value );
|
||||
|
||||
void SetSqlInt64( int ordinal, SqlInt64 value );
|
||||
|
||||
void SetSqlSingle( int ordinal, SqlSingle value );
|
||||
|
||||
void SetSqlDouble( int ordinal, SqlDouble value );
|
||||
|
||||
void SetSqlMoney( int ordinal, SqlMoney value );
|
||||
|
||||
void SetSqlDateTime( int ordinal, SqlDateTime value );
|
||||
|
||||
void SetSqlDecimal( int ordinal, SqlDecimal value );
|
||||
|
||||
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use setter with offset." )]
|
||||
void SetSqlString( int ordinal, SqlString value );
|
||||
|
||||
// Method introduced as of SMI V2
|
||||
void SetSqlString( int ordinal, SqlString value, int offset );
|
||||
|
||||
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use setter with offset." )]
|
||||
void SetSqlBinary( int ordinal, SqlBinary value );
|
||||
|
||||
// Method introduced as of SMI V2
|
||||
void SetSqlBinary( int ordinal, SqlBinary value, int offset );
|
||||
|
||||
void SetSqlGuid( int ordinal, SqlGuid value );
|
||||
|
||||
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use setter with offset." )]
|
||||
void SetSqlChars( int ordinal, SqlChars value );
|
||||
|
||||
// Method introduced as of SMI V2
|
||||
void SetSqlChars( int ordinal, SqlChars value, int offset );
|
||||
|
||||
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use setter with offset." )]
|
||||
void SetSqlBytes( int ordinal, SqlBytes value );
|
||||
|
||||
// Method introduced as of SMI V2
|
||||
void SetSqlBytes( int ordinal, SqlBytes value, int offset );
|
||||
|
||||
void SetSqlXml( int ordinal, SqlXml value );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ITypedSettersV3.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">alazela</owner>
|
||||
// <owner current="true" primary="false">stevesta</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
|
||||
// interface for strongly-typed value setters
|
||||
internal interface ITypedSettersV3 {
|
||||
|
||||
// By value setters (data copy across the interface boundary implied)
|
||||
// All setters are valid for SqlDbType.Variant
|
||||
|
||||
// SetVariantMetaData is used to set the precise type of data just before pushing
|
||||
// data into a variant type via one one of the other setters. It
|
||||
// is only valid to set metadata with a SqlDbType that associated with with the
|
||||
// data setter that will be called.
|
||||
// Since LOBs, Udt's and fixed-length types are not currently stored in a variant,
|
||||
// the following pairs are the only setters/sqldbtypes that need this call:
|
||||
// NVarChar/VarChar + SetString (needed only for non-global collation, i.e. SqlString)
|
||||
// Money/SmallMoney + SetInt64
|
||||
void SetVariantMetaData( SmiEventSink sink, int ordinal, SmiMetaData metaData );
|
||||
|
||||
// Set value to null
|
||||
// valid for all types
|
||||
void SetDBNull( SmiEventSink sink, int ordinal );
|
||||
|
||||
// valid for SqlDbType.Bit
|
||||
void SetBoolean( SmiEventSink sink, int ordinal, Boolean value );
|
||||
|
||||
// valid for SqlDbType.TinyInt
|
||||
void SetByte( SmiEventSink sink, int ordinal, Byte value );
|
||||
|
||||
// Semantics for SetBytes are to modify existing value, not overwrite
|
||||
// Use in combination with SetLength to ensure overwriting when necessary
|
||||
// valid for SqlDbTypes: Binary, VarBinary, Image, Udt, Xml
|
||||
// (VarBinary assumed for variants)
|
||||
int SetBytes( SmiEventSink sink, int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length );
|
||||
void SetBytesLength( SmiEventSink sink, int ordinal, long length );
|
||||
|
||||
// Semantics for SetChars are to modify existing value, not overwrite
|
||||
// Use in combination with SetLength to ensure overwriting when necessary
|
||||
// valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
|
||||
// (NVarChar and global clr collation assumed for variants)
|
||||
int SetChars( SmiEventSink sink, int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length );
|
||||
void SetCharsLength( SmiEventSink sink, int ordinal, long length );
|
||||
|
||||
// valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
|
||||
void SetString( SmiEventSink sink, int ordinal, string value, int offset, int length );
|
||||
|
||||
// valid for SqlDbType.SmallInt
|
||||
void SetInt16( SmiEventSink sink, int ordinal, Int16 value );
|
||||
|
||||
// valid for SqlDbType.Int
|
||||
void SetInt32( SmiEventSink sink, int ordinal, Int32 value );
|
||||
|
||||
// valid for SqlDbType.BigInt, SqlDbType.Money, SqlDbType.SmallMoney
|
||||
void SetInt64( SmiEventSink sink, int ordinal, Int64 value );
|
||||
|
||||
// valid for SqlDbType.Real
|
||||
void SetSingle( SmiEventSink sink, int ordinal, Single value );
|
||||
|
||||
// valid for SqlDbType.Float
|
||||
void SetDouble( SmiEventSink sink, int ordinal, Double value );
|
||||
|
||||
// valid for SqlDbType.Numeric (uses SqlDecimal since Decimal cannot hold full range)
|
||||
void SetSqlDecimal( SmiEventSink sink, int ordinal, SqlDecimal value );
|
||||
|
||||
// valid for DateTime & SmallDateTime
|
||||
void SetDateTime( SmiEventSink sink, int ordinal, DateTime value );
|
||||
|
||||
// valid for UniqueIdentifier
|
||||
void SetGuid( SmiEventSink sink, int ordinal, Guid value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="MemoryRecordBuffer.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 Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Diagnostics;
|
||||
|
||||
// Class for implementing a record object used in out-of-proc scenarios.
|
||||
internal sealed class MemoryRecordBuffer : SmiRecordBuffer {
|
||||
|
||||
private SqlRecordBuffer[] _buffer;
|
||||
|
||||
internal MemoryRecordBuffer(SmiMetaData[] metaData) {
|
||||
Debug.Assert(null != metaData, "invalid attempt to instantiate MemoryRecordBuffer with null SmiMetaData[]");
|
||||
|
||||
_buffer = new SqlRecordBuffer[metaData.Length];
|
||||
|
||||
for (int i = 0; i < _buffer.Length; ++i) {
|
||||
_buffer[i] = new SqlRecordBuffer(metaData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#region Getters
|
||||
// Null test
|
||||
// valid for all types
|
||||
public override bool IsDBNull(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].IsNull;
|
||||
}
|
||||
|
||||
// Check what type current sql_variant value is
|
||||
// valid for SqlDbType.Variant
|
||||
public override SmiMetaData GetVariantType(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].VariantType;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Bit
|
||||
public override Boolean GetBoolean(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].Boolean;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.TinyInt
|
||||
public override Byte GetByte(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].Byte;
|
||||
}
|
||||
|
||||
// valid for SqlDbTypes: Binary, VarBinary, Image, Udt, Xml, Char, VarChar, Text, NChar, NVarChar, NText
|
||||
// (Character type support needed for ExecuteXmlReader handling)
|
||||
public override Int64 GetBytesLength(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].BytesLength;
|
||||
}
|
||||
public override int GetBytes(SmiEventSink sink, int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length) {
|
||||
return _buffer[ordinal].GetBytes(fieldOffset, buffer, bufferOffset, length);
|
||||
}
|
||||
|
||||
// valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
|
||||
public override Int64 GetCharsLength(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].CharsLength;
|
||||
}
|
||||
public override int GetChars(SmiEventSink sink, int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length) {
|
||||
return _buffer[ordinal].GetChars(fieldOffset, buffer, bufferOffset, length);
|
||||
}
|
||||
public override String GetString(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].String;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.SmallInt
|
||||
public override Int16 GetInt16(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].Int16;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Int
|
||||
public override Int32 GetInt32(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].Int32;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.BigInt, SqlDbType.Money, SqlDbType.SmallMoney
|
||||
public override Int64 GetInt64(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].Int64;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Real
|
||||
public override Single GetSingle(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].Single;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Float
|
||||
public override Double GetDouble(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].Double;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Numeric (uses SqlDecimal since Decimal cannot hold full range)
|
||||
public override SqlDecimal GetSqlDecimal(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].SqlDecimal;
|
||||
}
|
||||
|
||||
// valid for DateTime, SmallDateTime, Date, and DateTime2
|
||||
public override DateTime GetDateTime(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].DateTime;
|
||||
}
|
||||
|
||||
// valid for UniqueIdentifier
|
||||
public override Guid GetGuid(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].Guid;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Time
|
||||
public override TimeSpan GetTimeSpan(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].TimeSpan;
|
||||
}
|
||||
|
||||
// valid for DateTimeOffset
|
||||
public override DateTimeOffset GetDateTimeOffset(SmiEventSink sink, int ordinal) {
|
||||
return _buffer[ordinal].DateTimeOffset;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Setters
|
||||
// Set value to null
|
||||
// valid for all types
|
||||
public override void SetDBNull(SmiEventSink sink, int ordinal) {
|
||||
_buffer[ordinal].SetNull();
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Bit
|
||||
public override void SetBoolean(SmiEventSink sink, int ordinal, Boolean value) {
|
||||
_buffer[ordinal].Boolean = value;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.TinyInt
|
||||
public override void SetByte(SmiEventSink sink, int ordinal, Byte value) {
|
||||
_buffer[ordinal].Byte = value;
|
||||
}
|
||||
|
||||
// Semantics for SetBytes are to modify existing value, not overwrite
|
||||
// Use in combination with SetLength to ensure overwriting when necessary
|
||||
// valid for SqlDbTypes: Binary, VarBinary, Image, Udt, Xml
|
||||
// (VarBinary assumed for variants)
|
||||
public override int SetBytes(SmiEventSink sink, int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length) {
|
||||
return _buffer[ordinal].SetBytes(fieldOffset, buffer, bufferOffset, length);
|
||||
}
|
||||
public override void SetBytesLength(SmiEventSink sink, int ordinal, long length) {
|
||||
_buffer[ordinal].BytesLength = length;
|
||||
}
|
||||
|
||||
// Semantics for SetChars are to modify existing value, not overwrite
|
||||
// Use in combination with SetLength to ensure overwriting when necessary
|
||||
// valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
|
||||
// (NVarChar and global clr collation assumed for variants)
|
||||
public override int SetChars(SmiEventSink sink, int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length) {
|
||||
return _buffer[ordinal].SetChars(fieldOffset, buffer, bufferOffset, length);
|
||||
}
|
||||
public override void SetCharsLength(SmiEventSink sink, int ordinal, long length) {
|
||||
_buffer[ordinal].CharsLength = length;
|
||||
}
|
||||
|
||||
// valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
|
||||
public override void SetString(SmiEventSink sink, int ordinal, string value, int offset, int length) {
|
||||
Debug.Assert(offset == 0 && length <= value.Length, "Invalid string length or offset"); // for sqlvariant, length could be less than value.Length
|
||||
|
||||
_buffer[ordinal].String = value.Substring(offset, length); // Perf test shows that Substring method has already optimized the case where length = value.Length
|
||||
}
|
||||
|
||||
// valid for SqlDbType.SmallInt
|
||||
public override void SetInt16(SmiEventSink sink, int ordinal, Int16 value) {
|
||||
_buffer[ordinal].Int16 = value;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Int
|
||||
public override void SetInt32(SmiEventSink sink, int ordinal, Int32 value) {
|
||||
_buffer[ordinal].Int32 = value;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.BigInt, SqlDbType.Money, SqlDbType.SmallMoney
|
||||
public override void SetInt64(SmiEventSink sink, int ordinal, Int64 value) {
|
||||
_buffer[ordinal].Int64 = value;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Real
|
||||
public override void SetSingle(SmiEventSink sink, int ordinal, Single value) {
|
||||
_buffer[ordinal].Single = value;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Float
|
||||
public override void SetDouble(SmiEventSink sink, int ordinal, Double value) {
|
||||
_buffer[ordinal].Double = value;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Numeric (uses SqlDecimal since Decimal cannot hold full range)
|
||||
public override void SetSqlDecimal(SmiEventSink sink, int ordinal, SqlDecimal value) {
|
||||
_buffer[ordinal].SqlDecimal = value;
|
||||
}
|
||||
|
||||
// valid for DateTime, SmallDateTime, Date, and DateTime2
|
||||
public override void SetDateTime(SmiEventSink sink, int ordinal, DateTime value) {
|
||||
_buffer[ordinal].DateTime = value;
|
||||
}
|
||||
|
||||
// valid for UniqueIdentifier
|
||||
public override void SetGuid(SmiEventSink sink, int ordinal, Guid value) {
|
||||
_buffer[ordinal].Guid = value;
|
||||
}
|
||||
|
||||
// SqlDbType.Time
|
||||
public override void SetTimeSpan(SmiEventSink sink, int ordinal, TimeSpan value) {
|
||||
_buffer[ordinal].TimeSpan = value;
|
||||
}
|
||||
|
||||
// DateTimeOffset
|
||||
public override void SetDateTimeOffset(SmiEventSink sink, int ordinal, DateTimeOffset value) {
|
||||
_buffer[ordinal].DateTimeOffset = value;
|
||||
}
|
||||
|
||||
// valid for SqlDbType.Variant
|
||||
public override void SetVariantMetaData(SmiEventSink sink, int ordinal, SmiMetaData metaData) {
|
||||
_buffer[ordinal].VariantType = metaData;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,99 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiConnection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
|
||||
internal abstract class SmiConnection : IDisposable {
|
||||
|
||||
//
|
||||
// Miscellaneous directives / accessors
|
||||
//
|
||||
|
||||
internal abstract string GetCurrentDatabase(
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
internal abstract void SetCurrentDatabase (
|
||||
string databaseName,
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
//
|
||||
// IDisposable
|
||||
//
|
||||
public virtual void Dispose( ) {
|
||||
// Obsoleting from SMI -- use Close( SmiEventSink ) instead.
|
||||
// Intended to be removed (along with inheriting IDisposable) prior to RTM.
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V3+ and dropped support for V2-.
|
||||
// 2) Server didn't implement V2- on some interface and negotiated V2-.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
}
|
||||
|
||||
public virtual void Close(
|
||||
SmiEventSink eventSink
|
||||
) {
|
||||
// Adding as of V3
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V2- and hasn't implemented V3 yet.
|
||||
// 2) Server didn't implement V3 on some interface, but negotiated V3+.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Transaction API (should we encapsulate in it's own class or interface?)
|
||||
//
|
||||
internal abstract void BeginTransaction (
|
||||
string name,
|
||||
IsolationLevel level,
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
internal abstract void CommitTransaction (
|
||||
long transactionId,
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
internal abstract void CreateTransactionSavePoint (
|
||||
long transactionId,
|
||||
string name,
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
internal abstract byte[] GetDTCAddress( // better buffer management needed? I.e. non-allocating call needed/possible?
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
internal abstract void EnlistTransaction (
|
||||
byte[] token, // better buffer management needed? I.e. non-allocating call needed/possible?
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
internal abstract byte[] PromoteTransaction ( // better buffer management needed? I.e. non-allocating call needed/possible?
|
||||
long transactionId,
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
internal abstract void RollbackTransaction (
|
||||
long transactionId,
|
||||
string savePointName, // only roll back to save point if name non-null
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiContext.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Sql;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Security.Principal;
|
||||
|
||||
// NOTE: connection, transaction and context pipe operations could be
|
||||
// encapsulated in their own classes, and should if they get complex
|
||||
// (transaction is borderline at this point).
|
||||
internal abstract class SmiContext {
|
||||
|
||||
internal abstract event EventHandler OutOfScope;
|
||||
|
||||
internal abstract SmiConnection ContextConnection { get; }
|
||||
|
||||
internal abstract long ContextTransactionId { get; }
|
||||
|
||||
internal abstract System.Transactions.Transaction ContextTransaction { get; }
|
||||
|
||||
internal abstract bool HasContextPipe { get; }
|
||||
|
||||
internal abstract WindowsIdentity WindowsIdentity { get; }
|
||||
|
||||
internal abstract SmiRecordBuffer CreateRecordBuffer (
|
||||
SmiExtendedMetaData[] columnMetaData, // Extended metadata because it requires names, udttypename and xmlschemaname ignored
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
internal abstract SmiRequestExecutor CreateRequestExecutor (
|
||||
string commandText,
|
||||
CommandType commandType,
|
||||
SmiParameterMetaData[] parameterMetaData,
|
||||
SmiEventSink eventSink
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
internal abstract object GetContextValue ( int key );
|
||||
|
||||
internal abstract void GetTriggerInfo (
|
||||
SmiEventSink eventSink,
|
||||
out bool[] columnsUpdated,
|
||||
out TriggerAction action,
|
||||
out SqlXml eventInstanceData
|
||||
);
|
||||
|
||||
internal abstract void SendMessageToPipe( string message, SmiEventSink eventSink );
|
||||
|
||||
internal abstract void SendResultsStartToPipe( SmiRecordBuffer recordBuffer, SmiEventSink eventSink );
|
||||
|
||||
internal abstract void SendResultsRowToPipe( SmiRecordBuffer recordBuffer, SmiEventSink eventSink );
|
||||
|
||||
internal abstract void SendResultsEndToPipe( SmiRecordBuffer recordBuffer, SmiEventSink eventSink );
|
||||
|
||||
internal abstract void SetContextValue ( int key, object value );
|
||||
|
||||
// Scratch LOB storage region
|
||||
internal virtual SmiStream GetScratchStream( SmiEventSink sink ) {
|
||||
// Adding as of V3
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V2- and hasn't implemented V3 yet.
|
||||
// 2) Server didn't implement V3, but negotiated V3+.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiContextFactory.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
|
||||
sealed internal class SmiContextFactory {
|
||||
public static readonly SmiContextFactory Instance = new SmiContextFactory();
|
||||
|
||||
private readonly SmiLink _smiLink;
|
||||
private readonly ulong _negotiatedSmiVersion;
|
||||
private readonly byte _majorVersion;
|
||||
private readonly byte _minorVersion;
|
||||
private readonly short _buildNum;
|
||||
private readonly string _serverVersion;
|
||||
private readonly SmiEventSink_Default _eventSinkForGetCurrentContext;
|
||||
|
||||
internal const ulong YukonVersion = 100;
|
||||
internal const ulong KatmaiVersion = 210;
|
||||
internal const ulong LatestVersion = KatmaiVersion;
|
||||
|
||||
private readonly ulong[] __supportedSmiVersions = new ulong[] {YukonVersion, KatmaiVersion};
|
||||
|
||||
// Used as the key for SmiContext.GetContextValue()
|
||||
internal enum ContextKey {
|
||||
Connection = 0,
|
||||
SqlContext = 1
|
||||
}
|
||||
|
||||
|
||||
private SmiContextFactory() {
|
||||
if (InOutOfProcHelper.InProc) {
|
||||
Type smiLinkType = Type.GetType("Microsoft.SqlServer.Server.InProcLink, SqlAccess, PublicKeyToken=89845dcd8080cc91");
|
||||
|
||||
if (null == smiLinkType) {
|
||||
Debug.Assert(false, "could not get InProcLink type");
|
||||
throw SQL.ContextUnavailableOutOfProc(); // Must not be a valid version of Sql Server.
|
||||
}
|
||||
|
||||
System.Reflection.FieldInfo instanceField = GetStaticField(smiLinkType, "Instance");
|
||||
if (instanceField != null) {
|
||||
_smiLink = (SmiLink)GetValue(instanceField);
|
||||
}
|
||||
else {
|
||||
Debug.Assert(false, "could not get InProcLink.Instance");
|
||||
throw SQL.ContextUnavailableOutOfProc(); // Must not be a valid version of Sql Server.
|
||||
}
|
||||
|
||||
System.Reflection.FieldInfo buildVersionField = GetStaticField(smiLinkType, "BuildVersion");
|
||||
if (buildVersionField != null) {
|
||||
UInt32 buildVersion = (UInt32)GetValue(buildVersionField);
|
||||
|
||||
_majorVersion = (byte)(buildVersion >> 24);
|
||||
_minorVersion = (byte)((buildVersion >> 16) & 0xff);
|
||||
_buildNum = (short)(buildVersion & 0xffff);
|
||||
_serverVersion = (String.Format((IFormatProvider)null, "{0:00}.{1:00}.{2:0000}", _majorVersion, (short) _minorVersion, _buildNum));
|
||||
}
|
||||
else {
|
||||
_serverVersion = String.Empty; // default value if nothing exists.
|
||||
}
|
||||
_negotiatedSmiVersion = _smiLink.NegotiateVersion(SmiLink.InterfaceVersion);
|
||||
bool isSupportedVersion = false;
|
||||
for(int i=0; !isSupportedVersion && i<__supportedSmiVersions.Length; i++) {
|
||||
if (__supportedSmiVersions[i] == _negotiatedSmiVersion) {
|
||||
isSupportedVersion = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnect if we didn't get a supported version!!
|
||||
if (!isSupportedVersion) {
|
||||
_smiLink = null;
|
||||
}
|
||||
|
||||
_eventSinkForGetCurrentContext = new SmiEventSink_Default();
|
||||
}
|
||||
}
|
||||
|
||||
internal ulong NegotiatedSmiVersion {
|
||||
get {
|
||||
if (null == _smiLink) {
|
||||
throw SQL.ContextUnavailableOutOfProc(); // Must not be a valid version of Sql Server, or not be SqlCLR
|
||||
}
|
||||
|
||||
return _negotiatedSmiVersion;
|
||||
}
|
||||
}
|
||||
|
||||
internal string ServerVersion {
|
||||
get {
|
||||
if (null == _smiLink) {
|
||||
throw SQL.ContextUnavailableOutOfProc(); // Must not be a valid version of Sql Server, or not be SqlCLR
|
||||
}
|
||||
|
||||
return _serverVersion;
|
||||
}
|
||||
}
|
||||
|
||||
internal SmiContext GetCurrentContext() {
|
||||
if (null == _smiLink) {
|
||||
throw SQL.ContextUnavailableOutOfProc(); // Must not be a valid version of Sql Server, or not be SqlCLR
|
||||
}
|
||||
|
||||
object result = _smiLink.GetCurrentContext(_eventSinkForGetCurrentContext);
|
||||
_eventSinkForGetCurrentContext.ProcessMessagesAndThrow();
|
||||
|
||||
if (null == result) {
|
||||
throw SQL.ContextUnavailableWhileInProc();
|
||||
}
|
||||
|
||||
Debug.Assert(typeof(SmiContext).IsInstanceOfType(result), "didn't get SmiContext from GetCurrentContext?");
|
||||
return (SmiContext)result;
|
||||
}
|
||||
|
||||
[System.Security.Permissions.ReflectionPermission(System.Security.Permissions.SecurityAction.Assert, MemberAccess=true)]
|
||||
private object GetValue(System.Reflection.FieldInfo fieldInfo) {
|
||||
object result = fieldInfo.GetValue(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
[System.Security.Permissions.ReflectionPermission(System.Security.Permissions.SecurityAction.Assert, MemberAccess=true)]
|
||||
private System.Reflection.FieldInfo GetStaticField(Type aType, string fieldName) {
|
||||
System.Reflection.FieldInfo result = aType.GetField(fieldName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.GetField);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiEventSink.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Sql;
|
||||
|
||||
// SqlEventSink is implemented by calling code. In all methods that accept
|
||||
// a SqlEventSink directly the sink must be able to handle multiple callbacks
|
||||
// without control returning from the original call.
|
||||
|
||||
// Methods that do not accept SmiEventSync are (generally) ProcessEvent on
|
||||
// the SmiEventStream methods returning a SmiEventStream and methods that
|
||||
// are certain to never call to the server (most will, for in-proc back end).
|
||||
|
||||
// Methods are commented with their corresponding TDS token
|
||||
|
||||
// NOTE: Throwing from these methods will not usually produce the desired
|
||||
// effect -- the managed to native boundary will eat any exceptions,
|
||||
// and will cause a simple "Something bad happened" exception to be
|
||||
// thrown in the native to managed boundary...
|
||||
internal abstract class SmiEventSink {
|
||||
|
||||
#region Active methods
|
||||
|
||||
// Called at end of stream whether errors or no
|
||||
internal abstract void BatchCompleted( );
|
||||
|
||||
// Called zero or one time when output parameters are available (errors could prevent event from occuring)
|
||||
internal virtual void ParameterAvailable(SmiParameterMetaData metaData, SmiTypedGetterSetter paramValue, int ordinal) {
|
||||
// Adding as of V200
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V3- and hasn't implemented V200 yet.
|
||||
// 2) Server didn't implement V200 on some interface, but negotiated V200+.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
}
|
||||
|
||||
// Called when the server database context changes (ENVCHANGE token)
|
||||
internal abstract void DefaultDatabaseChanged( string databaseName );
|
||||
|
||||
// Called for messages and errors (ERROR and INFO tokens)
|
||||
internal abstract void MessagePosted ( int number, byte state, byte errorClass, string server, string message, string procedure, int lineNumber );
|
||||
|
||||
// Called for new resultset starting (COLMETADATA token)
|
||||
internal abstract void MetaDataAvailable( SmiQueryMetaData[] metaData, bool nextEventIsRow );
|
||||
|
||||
|
||||
internal virtual void RowAvailable(SmiTypedGetterSetter rowData) {
|
||||
// Adding as of V200
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V3- and hasn't implemented V200 yet.
|
||||
// 2) Server didn't implement V200 on some interface, but negotiated V200+.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
}
|
||||
|
||||
// Called when any statement completes on server (DONE token)
|
||||
internal abstract void StatementCompleted( int rowsAffected );
|
||||
|
||||
// Called when a transaction is commited (ENVCHANGE token)
|
||||
internal abstract void TransactionCommitted( long transactionId );
|
||||
|
||||
// Called when a transaction is commited (ENVCHANGE token)
|
||||
internal abstract void TransactionDefected( long transactionId );
|
||||
|
||||
// Called when a transaction is commited (ENVCHANGE token)
|
||||
internal abstract void TransactionEnlisted( long transactionId );
|
||||
|
||||
// Called when a transaction is forcibly ended in the server, not requested
|
||||
// by the provider's batch (ENVCHANGE token)
|
||||
internal abstract void TransactionEnded( long transactionId );
|
||||
|
||||
// Called when a transaction is rolled back (ENVCHANGE token)
|
||||
internal abstract void TransactionRolledBack( long transactionId );
|
||||
|
||||
// Called when a transaction is started (ENVCHANGE token)
|
||||
internal abstract void TransactionStarted( long transactionId );
|
||||
|
||||
#endregion
|
||||
|
||||
#region OBSOLETE METHODS
|
||||
#region OBSOLETED as of V200 but active in previous version
|
||||
// Called zero or one time when output parameters are available (errors could prevent event from occuring)
|
||||
internal virtual void ParametersAvailable( SmiParameterMetaData[] metaData, ITypedGettersV3 paramValues ) {
|
||||
// Adding as of V3
|
||||
// Obsoleting as of V200
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V200+ and dropped support for V200-.
|
||||
// 2) Server didn't implement V3- on some interface and negotiated V3-.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
}
|
||||
|
||||
// Called when a new row arrives (ROW token)
|
||||
internal virtual void RowAvailable( ITypedGettersV3 rowData ) {
|
||||
// Adding as of V3
|
||||
// Obsoleting as of V200
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V200+ and dropped support for V200-.
|
||||
// 2) Server didn't implement V3- on some interface and negotiated V3-.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OBSOLETED and never shipped (without ObsoleteAttribute)
|
||||
// Called when a new row arrives (ROW token)
|
||||
internal virtual void RowAvailable( ITypedGetters rowData ) {
|
||||
// Obsoleting from SMI -- use end of dispose that takes an event sink instead.
|
||||
// Intended to be removed (along with inheriting IDisposable) prior to RTM.
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V3+ and dropped support for V2-.
|
||||
// 2) Server didn't implement V2- on some interface and negotiated V2-.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiEventSink_Default.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System.Data.Sql;
|
||||
using System.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
|
||||
internal class SmiEventSink_Default : SmiEventSink {
|
||||
|
||||
private SmiEventSink _parent; // next level up, which we'll defer to if we don't need to handle the event.
|
||||
|
||||
private SqlErrorCollection _errors;
|
||||
private SqlErrorCollection _warnings;
|
||||
|
||||
private SqlErrorCollection Errors {
|
||||
get {
|
||||
if ( null == _errors ) {
|
||||
_errors = new SqlErrorCollection( );
|
||||
}
|
||||
|
||||
return _errors;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasMessages {
|
||||
get {
|
||||
SmiEventSink_Default parent = (SmiEventSink_Default)_parent;
|
||||
if (null != parent) {
|
||||
return parent.HasMessages;
|
||||
}
|
||||
else {
|
||||
bool result = (null != _errors || null != _warnings);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual internal string ServerVersion {
|
||||
get {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal SmiEventSink Parent {
|
||||
get {
|
||||
return _parent;
|
||||
}
|
||||
set {
|
||||
_parent = value;
|
||||
}
|
||||
}
|
||||
|
||||
private SqlErrorCollection Warnings {
|
||||
get {
|
||||
if ( null == _warnings ) {
|
||||
_warnings = new SqlErrorCollection( );
|
||||
}
|
||||
|
||||
return _warnings;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void DispatchMessages(bool ignoreNonFatalMessages) {
|
||||
// virtual because we want a default implementation in the cases
|
||||
// where we don't have a connection to process stuff, but we want to
|
||||
// provide the connection the ability to fire info messages when it
|
||||
// hooks up.
|
||||
SmiEventSink_Default parent = (SmiEventSink_Default)_parent;
|
||||
if (null != parent) {
|
||||
parent.DispatchMessages(ignoreNonFatalMessages);
|
||||
}
|
||||
else {
|
||||
SqlException errors = ProcessMessages(true, ignoreNonFatalMessages); // ignore warnings, because there's no place to send them...
|
||||
if (null != errors) {
|
||||
throw errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected SqlException ProcessMessages(bool ignoreWarnings, bool ignoreNonFatalMessages) {
|
||||
SqlException result = null;
|
||||
SqlErrorCollection temp = null; // temp variable to store that which is being thrown - so that local copies can be deleted
|
||||
|
||||
if ( null != _errors ) {
|
||||
Debug.Assert( 0 != _errors.Count, "empty error collection?" ); // must be something in the collection
|
||||
|
||||
if (ignoreNonFatalMessages) {
|
||||
temp = new SqlErrorCollection();
|
||||
foreach(SqlError error in _errors) {
|
||||
if (error.Class >= TdsEnums.FATAL_ERROR_CLASS){
|
||||
temp.Add(error);
|
||||
}
|
||||
}
|
||||
if (temp.Count <= 0) {
|
||||
temp = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (null != _warnings ) {
|
||||
// When we throw an exception we place all the warnings that
|
||||
// occurred at the end of the collection - after all the errors.
|
||||
// That way the user can see all the errors AND warnings that
|
||||
// occurred for the exception.
|
||||
foreach ( SqlError warning in _warnings ) {
|
||||
_errors.Add( warning );
|
||||
}
|
||||
}
|
||||
temp = _errors;
|
||||
}
|
||||
|
||||
_errors = null;
|
||||
_warnings = null;
|
||||
}
|
||||
else {
|
||||
Debug.Assert( null == _warnings || 0 != _warnings.Count, "empty warning collection?" );// must be something in the collection
|
||||
|
||||
if (!ignoreWarnings) {
|
||||
temp = _warnings;
|
||||
}
|
||||
_warnings = null;
|
||||
}
|
||||
|
||||
if ( null != temp ) {
|
||||
result = SqlException.CreateException( temp, ServerVersion );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void CleanMessages() {
|
||||
SmiEventSink_Default parent = (SmiEventSink_Default)_parent;
|
||||
if (null != parent) {
|
||||
parent.CleanMessages();
|
||||
}
|
||||
else {
|
||||
_errors = null;
|
||||
_warnings = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal void ProcessMessagesAndThrow() {
|
||||
ProcessMessagesAndThrow(false);
|
||||
}
|
||||
|
||||
internal void ProcessMessagesAndThrow(bool ignoreNonFatalMessages) {
|
||||
if (HasMessages) {
|
||||
DispatchMessages(ignoreNonFatalMessages);
|
||||
}
|
||||
}
|
||||
|
||||
internal enum UnexpectedEventType {
|
||||
BatchCompleted,
|
||||
ColumnInfoAvailable,
|
||||
DefaultDatabaseChanged,
|
||||
MessagePosted,
|
||||
MetaDataAvailable,
|
||||
ParameterAvailable,
|
||||
ParametersAvailable,
|
||||
RowAvailable,
|
||||
StatementCompleted,
|
||||
TableNameAvailable,
|
||||
TransactionCommitted,
|
||||
TransactionDefected,
|
||||
TransactionEnlisted,
|
||||
TransactionEnded,
|
||||
TransactionRolledBack,
|
||||
TransactionStarted,
|
||||
}
|
||||
|
||||
|
||||
internal SmiEventSink_Default () {
|
||||
}
|
||||
|
||||
internal SmiEventSink_Default ( SmiEventSink parent ) {
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
|
||||
// NOTE: See the note in SmiEventSink about throwing from these methods;
|
||||
// We're throwing here because we don't want to miss something, but
|
||||
// you'll need to turn on Bid tracing to figure out what it is that
|
||||
// was thrown, because they will be eaten by the server and replaced
|
||||
// with a different exception.
|
||||
|
||||
|
||||
// Called at end of stream
|
||||
internal override void BatchCompleted( ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.BatchCompleted);
|
||||
}
|
||||
_parent.BatchCompleted();
|
||||
}
|
||||
|
||||
internal override void ParametersAvailable(SmiParameterMetaData[] metaData, ITypedGettersV3 paramValues) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.ParametersAvailable);
|
||||
}
|
||||
_parent.ParametersAvailable(metaData, paramValues);
|
||||
}
|
||||
|
||||
internal override void ParameterAvailable(SmiParameterMetaData metaData, SmiTypedGetterSetter paramValue, int ordinal) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.ParameterAvailable);
|
||||
}
|
||||
_parent.ParameterAvailable(metaData, paramValue, ordinal);
|
||||
}
|
||||
|
||||
// Called when the server database context changes (ENVCHANGE token)
|
||||
internal override void DefaultDatabaseChanged( string databaseName ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.DefaultDatabaseChanged);
|
||||
}
|
||||
_parent.DefaultDatabaseChanged( databaseName );
|
||||
}
|
||||
|
||||
// Called for messages and errors (ERROR and INFO tokens)
|
||||
internal override void MessagePosted ( int number, byte state, byte errorClass, string server, string message, string procedure, int lineNumber ) {
|
||||
if (null == _parent) {
|
||||
if (Bid.AdvancedOn) {
|
||||
Bid.Trace("<sc.SmiEventSink_Default.MessagePosted|ADV> %d#, number=%d state=%d errorClass=%d server='%ls' message='%ls' procedure='%ls' linenumber=%d.\n",
|
||||
0,
|
||||
number,
|
||||
state,
|
||||
errorClass,
|
||||
(null != server) ? server : "<null>",
|
||||
(null != message) ? message : "<null>",
|
||||
(null != procedure) ? procedure : "<null>",
|
||||
lineNumber
|
||||
);
|
||||
}
|
||||
SqlError error = new SqlError ( number, state, errorClass, server, message, procedure, lineNumber );
|
||||
|
||||
if ( error.Class < TdsEnums.MIN_ERROR_CLASS ) {
|
||||
Warnings.Add( error );
|
||||
}
|
||||
else {
|
||||
Errors.Add( error );
|
||||
}
|
||||
}
|
||||
else {
|
||||
_parent.MessagePosted( number, state, errorClass, server, message, procedure, lineNumber );
|
||||
}
|
||||
}
|
||||
|
||||
// Called for new resultset starting (COLMETADATA token)
|
||||
internal override void MetaDataAvailable( SmiQueryMetaData[] metaData, bool nextEventIsRow ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.MetaDataAvailable);
|
||||
}
|
||||
_parent.MetaDataAvailable( metaData, nextEventIsRow );
|
||||
}
|
||||
|
||||
// Called when a new row arrives (ROW token)
|
||||
internal override void RowAvailable( ITypedGetters rowData ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.RowAvailable);
|
||||
}
|
||||
_parent.RowAvailable( rowData );
|
||||
}
|
||||
|
||||
// Called when a new row arrives (ROW token)
|
||||
internal override void RowAvailable( ITypedGettersV3 rowData ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.RowAvailable);
|
||||
}
|
||||
_parent.RowAvailable( rowData );
|
||||
}
|
||||
|
||||
// Called when any statement completes on server (DONE token)
|
||||
internal override void StatementCompleted( int rowsAffected ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.StatementCompleted);
|
||||
}
|
||||
_parent.StatementCompleted( rowsAffected );
|
||||
}
|
||||
|
||||
// Called when a transaction is commited (ENVCHANGE token)
|
||||
internal override void TransactionCommitted( long transactionId ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.TransactionCommitted);
|
||||
}
|
||||
_parent.TransactionCommitted( transactionId );
|
||||
}
|
||||
|
||||
// Called when a transaction is commited (ENVCHANGE token)
|
||||
internal override void TransactionDefected( long transactionId ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.TransactionDefected);
|
||||
}
|
||||
_parent.TransactionDefected( transactionId );
|
||||
}
|
||||
|
||||
// Called when a transaction is commited (ENVCHANGE token)
|
||||
internal override void TransactionEnlisted( long transactionId ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.TransactionEnlisted);
|
||||
}
|
||||
_parent.TransactionEnlisted( transactionId );
|
||||
}
|
||||
|
||||
// Called when a transaction is forcibly ended in the server, not requested
|
||||
// by the provider's batch (ENVCHANGE token)
|
||||
internal override void TransactionEnded( long transactionId ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.TransactionEnded);
|
||||
}
|
||||
_parent.TransactionEnded( transactionId );
|
||||
}
|
||||
|
||||
// Called when a transaction is rolled back (ENVCHANGE token)
|
||||
internal override void TransactionRolledBack( long transactionId ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.TransactionRolledBack);
|
||||
}
|
||||
_parent.TransactionRolledBack( transactionId );
|
||||
}
|
||||
|
||||
// Called when a transaction is started (ENVCHANGE token)
|
||||
internal override void TransactionStarted( long transactionId ) {
|
||||
if (null == _parent) {
|
||||
throw SQL.UnexpectedSmiEvent(UnexpectedEventType.TransactionStarted);
|
||||
}
|
||||
_parent.TransactionStarted( transactionId );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiEventSink_DeferedProcessing.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System.Data.Sql;
|
||||
using System.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
|
||||
// This class exists purely to defer processing of messages until a later time.
|
||||
// It is designed to allow calling common code that interacts with the SMI layers
|
||||
// without throwing or otherwise processing messages in the sink until later on.
|
||||
//
|
||||
// Main example:
|
||||
// SqlCommand.ExecuteNonQuerySmi calls EventStream.ProcessEvent with it's command event sink (CES)
|
||||
// ProcessEvent calls OnParametersAvailable on the CES
|
||||
// OnParametersAvailable sets up a deferedprocessing event sink (DPES) with the CES as its parent
|
||||
// OnParametersAvailable calls ValueUtils to extract param values passing the DPES
|
||||
// ValueUtils calls Smi passing DPES
|
||||
// Smi may call MessagePosted, which will send a message up the sink parent chain and save it.
|
||||
// ValueUtils calls ProcessMessagesAndThrow on DPES, which skips handling
|
||||
// ... return up the stack ...
|
||||
// SqlCommand.ExecuteNonQuerySmi calls CES.ProcessMessagesAndThrow, which handles the messages
|
||||
// sent from the Smi value extraction code.
|
||||
//
|
||||
// IMPORTANT: Code that uses the DeferedProccess event sink is responsible for ensuring that
|
||||
// these messages ARE processed at some point.
|
||||
internal class SmiEventSink_DeferedProcessing : SmiEventSink_Default {
|
||||
internal SmiEventSink_DeferedProcessing ( SmiEventSink parent ) : base(parent) {
|
||||
}
|
||||
|
||||
protected override void DispatchMessages(bool ignoreNonFatalMessages) {
|
||||
// Skip processing messages. Since messages are sent to parent and calling code will call
|
||||
// ProcessMessages against parent, messages ARE NOT LOST!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiEventStream.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
|
||||
internal abstract class SmiEventStream : IDisposable {
|
||||
|
||||
internal abstract bool HasEvents { get; }
|
||||
|
||||
internal abstract void Close( SmiEventSink sink );
|
||||
|
||||
public virtual void Dispose( ) {
|
||||
// Obsoleting from SMI -- use Close instead.
|
||||
// Intended to be removed (along with inheriting IDisposable) prior to RTM.
|
||||
|
||||
// Implement body with throw because there are only a couple of ways to get to this code:
|
||||
// 1) Client is calling this method even though the server negotiated for V3+ and dropped support for V2-.
|
||||
// 2) Server didn't implement V2- on some interface and negotiated V2-.
|
||||
System.Data.Common.ADP.InternalError( System.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod );
|
||||
}
|
||||
|
||||
internal abstract void ProcessEvent( SmiEventSink sink );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiExecuteType.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">alazela</owner>
|
||||
// <owner current="true" primary="false">stevesta</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Sql;
|
||||
|
||||
// enum representing the type of execution requested
|
||||
internal enum SmiExecuteType {
|
||||
NonQuery = 0,
|
||||
Reader = 1,
|
||||
ToPipe = 2,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiGettersStream.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
internal class SmiGettersStream : Stream {
|
||||
|
||||
private SmiEventSink_Default _sink;
|
||||
private ITypedGettersV3 _getters;
|
||||
private int _ordinal;
|
||||
private long _readPosition;
|
||||
private SmiMetaData _metaData;
|
||||
|
||||
internal SmiGettersStream( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
|
||||
Debug.Assert( null != sink );
|
||||
Debug.Assert( null != getters );
|
||||
Debug.Assert( 0 <= ordinal );
|
||||
Debug.Assert( null != metaData );
|
||||
|
||||
_sink = sink;
|
||||
_getters = getters;
|
||||
_ordinal = ordinal;
|
||||
_readPosition = 0;
|
||||
_metaData = metaData;
|
||||
}
|
||||
|
||||
public override bool CanRead {
|
||||
get {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If CanSeek is false, Position, Seek, Length, and SetLength should throw.
|
||||
public override bool CanSeek {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanWrite {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override long Length {
|
||||
get {
|
||||
return ValueUtilsSmi.GetBytesInternal( _sink, _getters, _ordinal, _metaData, 0, null, 0, 0, false );
|
||||
}
|
||||
}
|
||||
|
||||
public override long Position {
|
||||
get {
|
||||
return _readPosition;
|
||||
}
|
||||
set {
|
||||
throw SQL.StreamSeekNotSupported();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Flush() {
|
||||
throw SQL.StreamWriteNotSupported();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin) {
|
||||
throw SQL.StreamSeekNotSupported();
|
||||
}
|
||||
|
||||
public override void SetLength(long value) {
|
||||
throw SQL.StreamWriteNotSupported();
|
||||
}
|
||||
|
||||
public override int Read( byte[] buffer, int offset, int count ) {
|
||||
long bytesRead = ValueUtilsSmi.GetBytesInternal( _sink, _getters, _ordinal, _metaData, _readPosition, buffer, offset, count, false );
|
||||
_readPosition += bytesRead;
|
||||
|
||||
return checked( (int) bytesRead );
|
||||
}
|
||||
|
||||
public override void Write( byte[] buffer, int offset, int count ) {
|
||||
throw SQL.StreamWriteNotSupported();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiLink.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">alazela</owner>
|
||||
// <owner current="true" primary="false">billin</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("SqlAccess, PublicKey=0024000004800000940000000602000000240000525341310004000001000100272736ad6e5f9586bac2d531eabc3acc666c2f8ec879fa94f8f7b0327d2ff2ed523448f83c3d5c5dd2dfc7bc99c5286b2c125117bf5cbe242b9d41750732b2bdffe649c6efb8e5526d526fdd130095ecdb7bf210809c6cdad8824faa9ac0310ac3cba2aa0523567b2dfa7fe250b30facbd62d4ec99b94ac47c7d3b28f1f6e4c8")] // SQLBU 437687
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
|
||||
internal abstract class SmiLink {
|
||||
|
||||
// NOTE: Except for changing the constant value below, adding new members
|
||||
// to this class may create versioning issues. We would prefer not
|
||||
// to add additional items to this if possible.
|
||||
|
||||
internal const ulong InterfaceVersion = 210;
|
||||
|
||||
// Version negotiation (appdomain-wide negotiation)
|
||||
// This needs to be the first method called when negotiating with a
|
||||
// driver back end. Once called, the rest of the back end interface
|
||||
// needs to conform to the returned version number's interface.
|
||||
internal abstract ulong NegotiateVersion( ulong requestedVersion );
|
||||
|
||||
// Get utility class valid in current thread execution environment
|
||||
// This returns an object, to allow us to version the context without
|
||||
// having to version this class. (eg. SmiContext1 vs SmiContext2)
|
||||
internal abstract object GetCurrentContext( SmiEventSink eventSink );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,261 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SmiMetaData.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.SqlServer.Server {
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
// SmiMetaDataProperty defines an extended, optional property to be used on the SmiMetaData class
|
||||
// This approach to adding properties is added combat the growing number of sparsely-used properties
|
||||
// that are specially handled on the base classes
|
||||
|
||||
internal enum SmiPropertySelector {
|
||||
DefaultFields = 0x0,
|
||||
SortOrder = 0x1,
|
||||
UniqueKey = 0x2,
|
||||
}
|
||||
|
||||
// Simple collection for properties. Could extend to IDictionary support if needed in future.
|
||||
internal class SmiMetaDataPropertyCollection {
|
||||
private const int SelectorCount = 3; // number of elements in SmiPropertySelector
|
||||
|
||||
private SmiMetaDataProperty[] _properties;
|
||||
private bool _isReadOnly;
|
||||
|
||||
internal static readonly SmiMetaDataPropertyCollection EmptyInstance;
|
||||
|
||||
// Singleton empty instances to ensure each property is always non-null
|
||||
private static readonly SmiDefaultFieldsProperty __emptyDefaultFields = new SmiDefaultFieldsProperty(new List<bool>());
|
||||
private static readonly SmiOrderProperty __emptySortOrder = new SmiOrderProperty(new List<SmiOrderProperty.SmiColumnOrder>());
|
||||
private static readonly SmiUniqueKeyProperty __emptyUniqueKey = new SmiUniqueKeyProperty(new List<bool>());
|
||||
|
||||
static SmiMetaDataPropertyCollection() {
|
||||
EmptyInstance = new SmiMetaDataPropertyCollection();
|
||||
EmptyInstance.SetReadOnly();
|
||||
}
|
||||
|
||||
internal SmiMetaDataPropertyCollection() {
|
||||
_properties = new SmiMetaDataProperty[SelectorCount];
|
||||
_isReadOnly = false;
|
||||
_properties[(int)SmiPropertySelector.DefaultFields] = __emptyDefaultFields;
|
||||
_properties[(int)SmiPropertySelector.SortOrder] = __emptySortOrder;
|
||||
_properties[(int)SmiPropertySelector.UniqueKey] = __emptyUniqueKey;
|
||||
}
|
||||
|
||||
internal SmiMetaDataProperty this[SmiPropertySelector key] {
|
||||
get {
|
||||
return _properties[(int)key];
|
||||
}
|
||||
set {
|
||||
if (null == value) {
|
||||
throw ADP.InternalError(ADP.InternalErrorCode.InvalidSmiCall);
|
||||
}
|
||||
EnsureWritable();
|
||||
_properties[(int)key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsReadOnly {
|
||||
get {
|
||||
return _isReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<SmiMetaDataProperty> Values {
|
||||
get {
|
||||
return new List<SmiMetaDataProperty>(_properties);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow switching to read only, but not back.
|
||||
internal void SetReadOnly() {
|
||||
_isReadOnly = true;
|
||||
}
|
||||
|
||||
private void EnsureWritable() {
|
||||
if (IsReadOnly) {
|
||||
throw System.Data.Common.ADP.InternalError(System.Data.Common.ADP.InternalErrorCode.InvalidSmiCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Base class for properties
|
||||
internal abstract class SmiMetaDataProperty {
|
||||
internal abstract string TraceString();
|
||||
}
|
||||
|
||||
// Property defining a list of column ordinals that define a unique key
|
||||
internal class SmiUniqueKeyProperty : SmiMetaDataProperty {
|
||||
private IList<bool> _columns;
|
||||
|
||||
internal SmiUniqueKeyProperty(IList<bool> columnIsKey) {
|
||||
_columns = new List<bool>(columnIsKey).AsReadOnly();
|
||||
}
|
||||
|
||||
// indexed by column ordinal indicating for each column whether it is key or not
|
||||
internal bool this[int ordinal] {
|
||||
get {
|
||||
if (_columns.Count <= ordinal) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return _columns[ordinal];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
internal void CheckCount(int countToMatch) {
|
||||
Debug.Assert(0 == _columns.Count || countToMatch == _columns.Count,
|
||||
"SmiDefaultFieldsProperty.CheckCount: DefaultFieldsProperty size (" + _columns.Count +
|
||||
") not equal to checked size (" + countToMatch + ")" );
|
||||
}
|
||||
|
||||
internal override string TraceString() {
|
||||
string returnValue = "UniqueKey(";
|
||||
bool delimit = false;
|
||||
for (int columnOrd = 0; columnOrd < _columns.Count; columnOrd++) {
|
||||
if (delimit) {
|
||||
returnValue += ",";
|
||||
}
|
||||
else {
|
||||
delimit = true;
|
||||
}
|
||||
if (_columns[columnOrd]) {
|
||||
returnValue += columnOrd.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
returnValue += ")";
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Property defining a sort order for a set of columns (by ordinal and ASC/DESC).
|
||||
internal class SmiOrderProperty : SmiMetaDataProperty {
|
||||
internal struct SmiColumnOrder {
|
||||
internal int SortOrdinal;
|
||||
internal SortOrder Order;
|
||||
|
||||
internal string TraceString() {
|
||||
return String.Format(CultureInfo.InvariantCulture, "{0} {1}", SortOrdinal, Order);
|
||||
}
|
||||
}
|
||||
|
||||
private IList<SmiColumnOrder> _columns;
|
||||
|
||||
internal SmiOrderProperty(IList<SmiColumnOrder> columnOrders) {
|
||||
_columns = new List<SmiColumnOrder>(columnOrders).AsReadOnly();
|
||||
}
|
||||
|
||||
// Readonly list of the columnorder instances making up the sort order
|
||||
// order in list indicates precedence
|
||||
internal SmiColumnOrder this[int ordinal] {
|
||||
get {
|
||||
if (_columns.Count <= ordinal) {
|
||||
SmiColumnOrder order = new SmiColumnOrder();
|
||||
order.Order = SortOrder.Unspecified;
|
||||
order.SortOrdinal = -1;
|
||||
return order;
|
||||
}
|
||||
else {
|
||||
return _columns[ordinal];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
internal void CheckCount(int countToMatch) {
|
||||
Debug.Assert(0 == _columns.Count || countToMatch == _columns.Count,
|
||||
"SmiDefaultFieldsProperty.CheckCount: DefaultFieldsProperty size (" + _columns.Count +
|
||||
") not equal to checked size (" + countToMatch + ")" );
|
||||
}
|
||||
|
||||
internal override string TraceString() {
|
||||
string returnValue = "SortOrder(";
|
||||
bool delimit = false;
|
||||
foreach(SmiColumnOrder columnOrd in _columns) {
|
||||
if (delimit) {
|
||||
returnValue += ",";
|
||||
}
|
||||
else {
|
||||
delimit = true;
|
||||
}
|
||||
|
||||
if (System.Data.SqlClient.SortOrder.Unspecified != columnOrd.Order) {
|
||||
returnValue += columnOrd.TraceString();
|
||||
}
|
||||
}
|
||||
returnValue += ")";
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
// property defining inheritance relationship(s)
|
||||
internal class SmiDefaultFieldsProperty : SmiMetaDataProperty {
|
||||
#region private fields
|
||||
|
||||
private IList<bool> _defaults;
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal interface
|
||||
|
||||
internal SmiDefaultFieldsProperty(IList<bool> defaultFields) {
|
||||
_defaults = new List<bool>(defaultFields).AsReadOnly();
|
||||
}
|
||||
|
||||
internal bool this[int ordinal] {
|
||||
get {
|
||||
if (_defaults.Count <= ordinal) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return _defaults[ordinal];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
internal void CheckCount(int countToMatch) {
|
||||
Debug.Assert(0 == _defaults.Count || countToMatch == _defaults.Count,
|
||||
"SmiDefaultFieldsProperty.CheckCount: DefaultFieldsProperty size (" + _defaults.Count +
|
||||
") not equal to checked size (" + countToMatch + ")" );
|
||||
}
|
||||
|
||||
internal override string TraceString() {
|
||||
string returnValue = "DefaultFields(";
|
||||
bool delimit = false;
|
||||
for(int columnOrd = 0; columnOrd < _defaults.Count; columnOrd++) {
|
||||
if (delimit) {
|
||||
returnValue += ",";
|
||||
}
|
||||
else {
|
||||
delimit = true;
|
||||
}
|
||||
|
||||
if (_defaults[columnOrd]) {
|
||||
returnValue += columnOrd;
|
||||
}
|
||||
}
|
||||
returnValue += ")";
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user